exécuter automatiquement une macro Excel lors d'un changement de cellule

91

Comment puis-je exécuter automatiquement une macro Excel chaque fois qu'une valeur dans une cellule particulière change?

À l'heure actuelle, mon code de travail est:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub

"H5"est la cellule particulière surveillée et Macroest le nom de la macro.

Y a-t-il un meilleur moyen?

namin
la source
L'UDF RunMacroWhenValueChanges de FormulaDesk répond-il à vos besoins? formuladesk.com
Gareth Hayter

Réponses:

107

Votre code est plutôt bon.

Attention cependant, votre appel à Range("H5")est une commande de raccourci vers Application.Range("H5"), ce qui équivaut à Application.ActiveSheet.Range("H5"). Cela pourrait être bien, si les seuls changements sont des changements d'utilisateur - ce qui est le plus typique - mais il est possible que les valeurs de cellule de la feuille de calcul changent quand ce n'est pas la feuille active via des changements programmatiques, par exemple VBA.

Dans cet esprit, j'utiliserais Target.Worksheet.Range("H5"):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Target.Worksheet.Range("H5")) Is Nothing Then Macro
End Sub

Ou vous pouvez utiliser Me.Range("H5"), si le gestionnaire d'événements se trouve sur la page de codes de la feuille de calcul en question (c'est généralement le cas):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro
End Sub

J'espère que cela t'aides...

Mike Rosenblum
la source
4
et si la cellule H5est modifiée à partir d'une autre feuille, disons que sheet2 la fonction ci-dessus ne fonctionne pas. plz aide dans ce domaine.
dhpratik
2
Pour toute personne venant ici d'une recherche google, assurez-vous de coller ce code dans la feuille dans vba, pas dans un module comme je l'ai fait. regardez stackoverflow.com/questions/15337008/…
hammythepig
Application.ActiveSheet.Range ("H5"). ==> target.parent.range ("H5") est encore plus sûr
Pierre
1
@WillEdiger Chaque fois que vous ne spécifiez pas explicitement une référence de feuille, Excel suppose que ActiveSheetet chaque fois que vous ne spécifiez pas explicitement que vous travaillez avec Excel, Excel suppose Application.
Scott Marcus
1
Notez que, dans un module de code de feuille de calcul (qui est l'endroit où un Worksheet_Changeévénement doit être localisé), un non qualifié Rangene correspond pas par défaut ActiveSheetà la feuille contenant le code, mais à la place. Le code de cette réponse est donc effectivement le même que celui de la question. (Remarque: en 2009, lorsque cette réponse a été écrite, elle avait peut- être été différente, mais je suis presque certain que ce n'était pas le cas.)
YowE3K
7

Gérez l' Worksheet_Changeévénement ou l' Workbook_SheetChangeévénement.

Les gestionnaires d'événements prennent un argument "Target As Range", afin que vous puissiez vérifier si la plage qui change inclut la cellule qui vous intéresse.

Joe
la source
Merci, ça marche. Je vérifie la gamme avec, par exemple, Target.Address = Range("H5").Address. Y a-t-il un moyen plus simple?
namin
Une alternative: Not (Intersect(Target, Range("H5")) Is Nothing) . Est-ce ainsi que vous feriez?
namin
2
Le premier commentaire ( Target.Address = Range("H5").Address) ne fonctionnerait pas si votre cellule ne faisait que partie de la plage modifiée. Le deuxième commentaire souffre encore des problèmes décrits par Mike Rosenblum.
Ant
5

J'ai passé beaucoup de temps à faire des recherches et à apprendre comment tout cela fonctionne, après avoir vraiment gâché les déclencheurs d'événements. Comme il y avait tellement d'informations dispersées, j'ai décidé de partager ce que j'ai trouvé pour fonctionner en un seul endroit, étape par étape comme suit:

1) Ouvrez l'éditeur VBA, sous Projet VBA (YourWorkBookName.xlsm) ouvrez l'objet Microsoft Excel et sélectionnez la feuille à laquelle l'événement de modification se rapportera.

2) La vue de code par défaut est "Général". Dans la liste déroulante en haut au milieu, sélectionnez "Feuille de calcul".

3) Private Sub Worksheet_SelectionChange est déjà là comme il se doit, laissez-le seul. Copiez / collez le code de Mike Rosenblum ci-dessus et modifiez la référence .Range à la cellule pour laquelle vous attendez un changement (B3, dans mon cas). Cependant, ne placez pas encore votre macro (j'ai supprimé le mot "Macro" après "Then"):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
End Sub

ou dans la liste déroulante en haut à gauche, sélectionnez "Modifier" et dans l'espace entre Private Sub et End Sub, collez If Not Intersect(Target, Me.Range("H5")) Is Nothing Then

4) Sur la ligne après "Then", désactivez les événements afin que lorsque vous appelez votre macro, elle ne déclenche pas d'événements et essayez d'exécuter à nouveau ce Worksheet_Change dans un cycle sans fin qui plante Excel et / ou tout gâche:

Application.EnableEvents = False

5) Appelez votre macro

Call YourMacroName

6) Réactivez les événements pour que le prochain changement (et tous les autres événements) se déclenche:

Application.EnableEvents = True

7) Terminez le bloc If et le Sub:

    End If
End Sub

Le code entier:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("B3")) Is Nothing Then
        Application.EnableEvents = False
        Call UpdateAndViewOnly
        Application.EnableEvents = True
    End If
End Sub

Cela nécessite l'activation / désactivation des événements des modules, ce qui crée des problèmes et laisse simplement le changement se déclencher, désactive les événements, exécute votre macro et réactive les événements.

Eric Vaughn-Shobey
la source
3

Je préfère cette façon, pas en utilisant une cellule mais une plage

    Dim cell_to_test As Range, cells_changed As Range

    Set cells_changed = Target(1, 1)
    Set cell_to_test = Range( RANGE_OF_CELLS_TO_DETECT )

    If Not Intersect(cells_changed, cell_to_test) Is Nothing Then 
       Macro
    End If
Javier Torón
la source
C'est la même chose qu'une cellule. Vous pouvez définir une plage comme une cellule, une plage de cellules continues ou même des cellules dispersées (toutes séparées par une virgule).
Shai Alon
0

J'ai une cellule qui est liée à la base de données de stock en ligne et mise à jour fréquemment. Je souhaite déclencher une macro chaque fois que la valeur de la cellule est mise à jour.

Je pense que cela est similaire au changement de valeur de cellule par un programme ou toute mise à jour de données externes, mais les exemples ci-dessus ne fonctionnent pas pour moi. Je pense que le problème est que les événements internes d'Excel ne sont pas déclenchés, mais c'est mon hypothèse.

J'ai fait ce qui suit,

Private Sub Worksheet_Change(ByVal Target As Range) 
  If Not Intersect(Target, Target.Worksheets("Symbols").Range("$C$3")) Is Nothing Then
   'Run Macro
End Sub
Juan Garcia
la source
1
Je ne peux pas faire fonctionner cela pour une raison quelconque. Quand je dis au code de s'exécuter dans VBA, il affiche un menu contextuel et me demande si je veux exécuter la macro au lieu d'exécuter la macro automatiquement?
David Van der Vieren