VBA - Désélectionner une cellule avant de lancer une macro

Bonjour,

Dans le fichier ci-joint, si je choisis par exemple 10 dans la cellule F22 de la feuille ‘’Base’’ puis que je lance la macro placée derrière le bouton en place, un tirage est effectué et je peux constater sur la feuille ‘’Contrôle – Résultats’’ nouvellement affichée que c’est bien un tirage pour 9 et 10 joueurs qui a été effectué.

Si j’inscris maintenant 11 en F22, mais que je ne sors pas de cette cellule avant de lancer à nouveau la macro, ça plante.

Savez-vous comment éviter cela ? Comment forcer la désélection de cette cellule – ou d’une autre – avant le lancement de la macro ?

Cordialement.

23demo-30-07.zip (316.97 Ko)

Hello,

pour moi il n'y a aucun problème tant que la saisie est validée, cad que vous appuyez bien sur la touche entrée en déplacer la sélection.

Un détournement assez cochon envoyer un "entrée" dans la procédure "Private Sub Worksheet_Change"

SenKeys "~"

Mais c'est problématique car on ne sais pas forcément ou se trouve le curseur quand on envoi la touche

Bonjour à tous,

Wow mais pourquoi coder comme ça…

Inscrivez "en dur" dans votre code quelles cellules doivent changer (par exemple "F23") au lieu de Target et vous devriez résoudre certains problèmes. De même dans le SelectionChange, puisque apparemment c'est là que se fait la mise à jour des valeurs des cellules F22 et F23, forcément si vous ne changez pas de cellule elles ne sont pas mises à jour puisque SelectionChange n'est pas lancé.

Vous devriez déplacer la logique de fonctionnement dans des Sub à part, par exemple "MettreAJourClubs" ou "CalculerTirage", et appeler ces macros depuis les évènements de la feuille. Ainsi vous aurez beaucoup plus de contrôle, et surtout vous ne serez plus dépendant de "l'utilisateur a cliqué une autre cellule" ou je ne sais quelle erreur pouvant entrainer une boucle infinie d'appels entre vos évènements.

Selon moi, un bon code de gestion d'évènement c'est cela :

' dans le module de feuille : ON MINIMISE LE CODE
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    ' on verifie la ou les conditions qui assurent que notre plage est celle attendue
    If Target.Intersect("maPlageATraiter") Is Nothing Then Exit Sub
    If Target.Count > 1 Then Exit Sub

    ' on s'assure de ne pas faire de boucle infinie    
    Application.ScreenUpdating = False
    Application.EnableEvents = False

    ' on peut lancer notre macro de calcul/traitement
    FaireQuelqueChose

    Application.EnableEvents = True
End Sub

' dans Module1 par exemple
Public Sub FaireQuelqueChose()
    Dim i As Byte, j As Byte
Retour:
    For i = 4 To 23
        If Range("B" & i) = "" And Range("B" & i + 1) <> "" Then
            Range("B" & i) = Range("B" & i + 1)
            Range("B" & i + 1) = ""
            GoTo Retour
        End If
        If Range("C" & i) = "" And Range("C" & i + 1) <> "" Then
            Range("C" & i) = Range("C" & i + 1)
            Range("C" & i + 1) = ""
            GoTo Retour
        End If
    Next i

    Range("F22") = Application.WorksheetFunction.CountA(Range("B4:B23"))
    Range("F23") = Application.WorksheetFunction.CountA(Range("C4:C23"))
End Sub

Bonjour Yvouille,

Si j’inscris maintenant 11 en F22, mais que je ne sors pas de cette cellule avant de lancer à nouveau la macro, ça plante.

Avec l'appel call prenoms on est sur une autre feuille.
La ligne comme ceci :

If Target.Address = "$F$22" Then Sheets("Base").Activate: Range("F23").Activate

Mais bon comme dit Nain Porte koi, il faut appuyer sur la touche Entree avant.

Sinon je n'ai pas trop compris le pourquoi de la macro call prenom puisque l'on est sur la feuille Base et que si feuille Base la macro n'est pas exécutée.
Un autre chose pourquoi aller sélectionner la dernière cellule de la feuille dans cette ligne

Application.GoTo Reference:=Worksheets("Base").Range("XFD1048576"), Scroll:=False

Il y a certainement une raison mais je n'ai pas trop analysé..

Cordialement

Bonjour,

Merci à tous pour vos réponses

Il est bien entendu que si la saisie est validée, il n'y a pas de problème. Cependant, plusieurs personnes utiliseront ce fichier et je voudrais éviter cette erreur possible.

@ Dan

Application.GoTo Reference:=Worksheets("Base").Range("XFD1048576"), Scroll:=False

est une proposition avortée de ChatGPT. J’ai simplement oublié d’effacer cette ligne.

Afin que le code de la feuille ’’Base’’ ne crée pas de problème lorsqu’une autre feuille est sélectionnée, j’avais bien eu l’idée de placer l’instruction ci-dessous en début de macro ‘’Worksheet_Change’’, mais ça ne résout pas le problème principal exposé dans mon titre :

If ActiveSheet.Name = Base then

……. ' Mon code

End If

@ Saboh

Je n’ai pas réussi à réaliser ta proposition, comme tu peux le voir dans le fichier ci-joint, ça bloque. Qu’ai-je fait faux ?

7essai-saboh.zip (317.05 Ko)

@ Nain porte koi

Je n’ai pas compris où placer l’instruction SenKeys "~" dans mon code. Plusieurs essais ont échoué.

Amicalement.

re

Afin que le code de la feuille ’’Base’’ ne crée pas de problème lorsqu’une autre feuille est sélectionnée, j’avais bien eu l’idée de placer l’instruction ci-dessous en début de macro ‘’Worksheet_Change’’, mais ça ne résout pas le problème principal exposé dans mon titre :

Heu ... la remarque sur la call prenoms était juste une remarque hors du contexte du souci de la demande. Simplement que je me demandais le pourquoi d'appeler cette macro dans la macro Worksheet_change sachant que ce code réagit sur le changement de la cellule F23 ou F24 dans la feuille Base. Donc on peut supprimer la ligne call prenom.

Par contre la ligne à changer, que j'ai mise après mon commentaire dans mon post précédent, il n'y a pas de plantage

Bonjour,

Ton problème ne vient pas de la désélection de F22 ou non. Ton problème vient du fait que tu tournes en rond en plaçant ton code dans change.

Place un point d'arrêt dans ton change et met ton 10 en F22. En faisant F8 pour faire du pas à pas tu verras déjà que tu relances x fois le même code.

Et en plus comme ton code intervient en supprimant des données de cette feuille bein tu tournes en rond.

Bonjour,

Merci à Alex pour ses dernières propositions.

J’ai construit mon fichier de manière à pouvoir l’utiliser de deux manières différentes : soit en modifiant le nombre de joueurs dans les cellules F22 et F23 de la feuille ‘’Base’’ – ce qui inscrit des noms fictifs dans la plage B4:C23 et me permets d’effectuer des essais - soit en modifiant la liste des noms réels en B4:C23, ce qui modifie le nombre de joueurs en F22 et F23, de manière à préparer le bon tirage.

Tout ceci fonctionne bien, sauf si l’utilisateur saisi une donnée - soit d’un côté, soit de l’autre - et clique sur le bouton en place sans désélectionner la dernière cellule.

J’espérais qu’Excel était capable de remarquer simplement qu’une saisie en cours n’avait pas été confirmée, mais je comprends que ce n’est pas le cas.

Mais comme cette situation est peu probable, je vais abandonner provisoirement le solutionnement de ce problème.

Dan, si je mets en place ta solution, comme dans la Démo_2 jointe, lorsque j’ajoute un joueur en B4:C23 et que je lance la macro sans désélectionner la dernière cellule saisie, ça effectue bien le bon tirage (avec un message d’erreur inapproprié, mais ce n’est pas bien grave). Mais si je change le nombre de joueur dans la cellule F22 sans la désélectionner, que je lance la macro, que la feuille ‘’Base’’ reste visible avec le bon chiffre en F22 et que je sélectionne la feuille ‘’Contrôle – Résultats’’, c’est l’ancien tirage qui est toujours en place.

Encore merci à vous tous et bonnes salutations.

11demo-v2.zip (316.70 Ko)

Bonjour

Dan, si je mets en place ta solution, comme dans la Démo_2 jointe, lorsque j’ajoute un joueur en B4:C23 et que je lance la macro sans désélectionner la dernière cellule saisie, ça effectue bien le bon tirage (avec un message d’erreur inapproprié, mais ce n’est pas bien grave).

C'est un sujet en complément à la première question et je n'ai pas regardé l'impact de la modification dans ces cellule Je n'ai pas ce résultat lorsque je le fais. Le code m'envoie à la dernière cellule dans la feuille
Si je désactive la ligne "application.goto.. dans la sub mise en place, j'ajoute un nom en B14 sans confirmer par la touche Entrée et que je lance le code, j'ai parfois ce message

image

Effectivement je n'avais pas regardé si le tirage était modifié mais cela pourrait se comprendre si on ne valide pas une entrée dans une cellule. Excel conserve l'ancienne donnée.
Peut être essayer en mettant cette instruction au début du code Mise en place --> Application.SendKeys ("{enter}")
Mais bon à voir... à mon avis c'est pas top comme solution.

Crdlt

Salut Dan,

Merci pour cette nouvelle réponse. J’ai alors créé le fichier ci-joint avec cette dernière proposition.

Admettons que j’inscrive 13 en F22 et que je lance la macro : le résultat pour 9 et 13 joueurs s’affiche correctement sur la feuille ‘’Contrôle – Résultats’’.

Ensuite, si j’ajoute un joueur manuellement en B17, que je ne désélectionne pas cette cellule et que je lance la macro, la feuille ‘’Contrôle – Résultats’’ est visible avec le bon nombre de joueurs (14) et le tirage est parfait.

Lorsque je reviens sur la feuille ‘’Base’’, le chiffre en F22 est resté à 13, mais lorsque je sélectionne une autre cellule, ça passe à 14.

Si j’inscris un nouveau joueur en B18, que je ne désélectionne pas cette cellule et que je lance la macro, la toute dernière cellule de la feuille ‘’Base’’ est sélectionnée et il ne se passe rien au niveau de la ‘’Contrôle – Résultats’’ (ça reste à 9 et 14 joueurs).

Tel qu’indiqué plus vite, je vais laisser tomber ce problème provisoirement.

Cordiales salutations.

7demo-v3.zip (316.38 Ko)

Re

Lorsque je reviens sur la feuille ‘’Base’’, le chiffre en F22 est resté à 13, mais lorsque je sélectionne une autre cellule, ça passe à 14.

Effectivement c'est ce que j'ai constaté aussi sans l'avoir mentionné dans mes posts
Par contre si je mets une info en B17 alors qu'il n'y a rien à B14, 15 et 16 (comme c'est le cas dans le fichier), là Excel tourne en boucle et je suis obligé de quitter en dur. Mais c'est peut-être chez moi le souci (j'ai un pC qui râme quelques fois)

Si j’inscris un nouveau joueur en B18, que je ne désélectionne pas cette cellule et que je lance la macro, la toute dernière cellule de la feuille ‘’Base’’ est sélectionnée et il ne se passe rien au niveau de la ‘’Contrôle – Résultats’’ (ça reste à 9 et 14 joueurs).

Faut vérifier si ce n'est pas du coté de l'instruction Application.EnableEvents qui est à False et qui empêche le code d'être exécuté
Il me semble que ce coté là il y a quelques soucis. A voir...

Autre point que je viens de voir,
- j'ajoute un joueur manuellement en B14 et j'appuie sur Entrée puis je lance la macro via le bouton, la feuille en F22 mentionne bien 14
- Si je supprime la valeur en B14, rien ne se passe en F22, il faut que je clique ailleurs dans la feuille pour que le calcul se fasse en F22


Question : est-ce qu'il ne faudrait pas ajouter les instructions Worksheet_function dans le code Worksheet_change en cas d'un changement de valeur dans la plage B2:c23. Donc juste après le Call Controle_Noms_uniques ?
D'ailleurs tant qu'à faire pourquoi ne pas supprimer le code Worksheet_Selection_change et revoir le code Worksheet_change en utilisant des 2 lignes de code plutôt que de faire une boucle for i =4 to 23 -->

Range("B4:B23").SpecialCells(xlCellTypeBlanks).Delete xlShiftUp
Range("C4:C23").SpecialCells(xlCellTypeBlanks).Delete xlShiftUp
Range("B4:C23").Interior.Color = RGB(252, 228, 214)

Autre sujet qui n'a rien avoir mais lorsque j'ouvre le fichier j'ai toujours un chiffre 2 derrière le XLSM... bizarre

image

Crdlt

Bonjour Yvouille,

on crée une nouvelle macro "Yvouille" avec le contenu de la macro "Worksheet_SelectionChange" et on utilise cette macro 2 fois, une fois dans la macro "Worksheet_SelectionChange" et une 2ième fois dans la macro "Worksheet_Change" quand on change quelque chose dans la plage B4:C23

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
     Dim i As Byte, j As Byte

     Application.ScreenUpdating = False
     Application.EnableEvents = False

     If Not Intersect(Target, Range("F22:F23")) Is Nothing Then
          If Target < 8 Then Target = 8
          If Target > 20 Then Target = 20
          Call Prenoms_x
          For i = 10 To 23
               If i - 3 > Range("F22") Then Range("B" & i).ClearContents
               If i - 3 > Range("F23") Then Range("C" & i).ClearContents
          Next i
          If Target.Address = "$F$22" Then Sheets("Base").Activate: Range("F23").Activate
          If Target.Address = "$F$23" Then Sheets("Base").Activate: Range("F24").Activate
          '        If Target.Address = "$F$22" Then Range("F23").Activate ' Sinon ça sélectionne la cellule C23 qui est la dernière effacée ci-dessus
          '        If Target.Address = "$F$23" Then Range("F24").Activate ' Sinon ça sélectionne la cellule C23 qui est la dernière effacée ci-dessus
     End If

     If Not Intersect(Target, Range("B2:C23")) Is Nothing Then
          Call Controle_Noms_uniques
          Yvouille                           'pour mise à jour des 2 compteurs ******************************************
     End If

     Application.EnableEvents = True

End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
     Yvouille                                'pour mise à jour des 2 compteurs ******************************************
End Sub

Private Sub Yvouille()

     Dim i As Byte, j As Byte

     Application.ScreenUpdating = False
     Application.EnableEvents = False

Retour:
     For i = 4 To 23
          If Range("B" & i) = "" And Range("B" & i + 1) <> "" Then
               Range("B" & i) = Range("B" & i + 1)
               Range("B" & i + 1) = ""
               GoTo Retour
          End If
          If Range("C" & i) = "" And Range("C" & i + 1) <> "" Then
               Range("C" & i) = Range("C" & i + 1)
               Range("C" & i + 1) = ""
               GoTo Retour
          End If
     Next i

     Range("F22") = Application.WorksheetFunction.CountA(Range("B4:B23"))
     Range("F23") = Application.WorksheetFunction.CountA(Range("C4:C23"))

     Application.EnableEvents = True

End Sub

Bonjour,

J'ai résolu mon problème de la manière suivante :

'...........
        On Error GoTo Etiquette

        If Target.Address = "$F$22" Then Range("F23").Activate 
        If Target.Address = "$F$23" Then Range("F24").Activate 

Etiquette:
        If Err > 0 Then
            Sheets("Base").Select
            Application.ScreenUpdating = True
            MsgBox "Après avoir inscrit un chiffre dans les cellules F22 ou F23 de la feuille ''Base'', il faut quitter la sélection (cliquer dans une autre cellule)."
            Exit Sub
        End If

        On Error GoTo 0
'...............

Cordialement.

cela est une solution bric à brac.

"On Error ..." est quelque chose qu'on utilise comme dernier recours, si on ne sait pas, avec toutes les possibilités possibles, éviter une erreur, mais ici, je ne vois pas le besoin.

Rechercher des sujets similaires à "vba deselectionner lancer macro"