Petite macro qui me plante Excel sur tous les PC

Re,

Je passerai un fichier sans les infos condifentielles pour pouvoir travailler dessus plus facilement.

bonjour, il faut limiter target au cellules de la plage A15:A25 ! Si on modifie plusieurs cellules en même temps et la première cellule est hors cette plage, il se passe des choses imprévues. Donc il faut créer un boucle avec l'intersect

Private Sub Worksheet_Change(ByVal Target As Range)
     Dim c, cl
     Set c = Intersect(Target, Range("A15:A25")) 'les cellules modifiée de cette plage
     If Not c Is Nothing Then 'il y a des cellules modifiées dans cette plage
          Application.ScreenUpdating = False
          For Each cl In c.Cells 'pour chaque cellule modifiée
               If cl.Offset(, 8).Value = cl.Offset(, 11) Then X = -1 Else X = cl.Offset(, 8).Value ' si I = L then X=-1 ou X=I
               Select Case X 'dépendant de la valeur de X, on change les cellules J-L
                    Case Is > 0: cl.Offset(0, 9).Resize(, 3) = Array(Format(Now, "dd/mm/yy"), Format(Now, "hh:mm;@"), cl.Offset(, 8).Value) 'J=date, K=heure, L=I
                    Case Is = 0: cl.Offset(0, 9).Resize(, 3).Clear 'RAZ J-L
               End Select
          Next
          Application.Goto .Offset(0, 9) 'positionnez dans dernière cellule J modifiée
     End If
End Sub

A nouveau,

Donc il faut créer un boucle avec l'intersect

Pas besoin de boucle

Rappel:

Ce que je souhaitais faire c'était d'introduire la date et heure à laquelle la ligne a été renseignée

Et le Target.count = 1 est suffisant.

amaai, est-ce qu'on essaie à créer quelque chose qui est idiot proof ou pas ?

target.count= 1 est une sorte de politique d'autruche pour camoufler ses défauts.

Bonjour BsAlv,

encore une fois merci pour ton retour.

Il y a un bug avec le dernier code:

image

J'ai testé différente solutions mais je tombe toujours dans l'erreur:

image

Je continue de tester. Et surtout de préparer un fichier que je puisse joindre mais je dois le faire depuis un autre portable. Ce soir j'essaie de joindre le fichier.

Encore merci.

Patrick.

bonjour, j'avais oublié le "cl"

 Application.Goto  cl.Offset(0, 9) 'positionnez dans dernière cellule J modifiée

Bonjour à tous,

Il y a un bug avec le dernier code:

image

Un petit oubli entre Goto et .Offset(0,9) ??

Application.Goto cl.Offset(0, 9)

[EDIT] : Bonjour BsAlv ,

Cordialement,

BsAlv, le fil, bonjour à tous,

Je continue de creuser un peu afin d'obtenir ce que je souhaite obtenir! En tout cas merci pour vos réponses qui m'ont déjà bien aidé.

J'avais développé une macro (qui fonctionne et j'en suis bien content) mais qui entre en "conflit" avec celle que me propose BsAlv (qui fonctionne parfaitement aussi ).

On prend la code de BsAlv:

Private Sub Worksheet_Change(ByVal Target As Range)
     Dim c, cl
     Set c = Intersect(Target, Range("A15:A25")) 'les cellules modifiée de cette plage
     If Not c Is Nothing Then 'il y a des cellules modifiées dans cette plage
          Application.ScreenUpdating = False
          For Each cl In c.Cells 'pour chaque cellule modifiée
               If cl.Offset(, 8).Value = cl.Offset(, 11) Then X = -1 Else X = cl.Offset(, 8).Value ' si I = L then X=-1 ou X=I
               Select Case X 'dépendant de la valeur de X, on change les cellules J-L
                    Case Is > 0: cl.Offset(0, 9).Resize(, 3) = Array(Format(Now, "dd/mm/yy"), Format(Now, "hh:mm;@"), cl.Offset(, 8).Value) 'J=date, K=heure, L=I
                    Case Is = 0: cl.Offset(0, 9).Resize(, 3).Clear 'RAZ J-L
               End Select
          Next
          'Application.Goto cl.Offset(0, 9) 'positionnez dans dernière cellule J modifiée
     End If

End Sub

Petite parenthèse: Je mets le code ci-dessous en ' car il me donne erreur:

'Application.Goto cl.Offset(0, 9) 'positionnez dans dernière cellule J modifiée

Mon code sert lui à éviter qu'il y ait deux fois la même référence et évite ainsi les doublons:

Private Sub Worksheet_Change(ByVal Target As Excel.Range)

'Détecte les doublons sur la colonne I et renvoie un message d'erreur.

Dim Lg%, X%
Lg = Range("i6500").End(xlUp).Row
    If Not Application.Intersect(Target, Range("i8:i" & Lg)) Is Nothing Then
            If Application.CountIf(Range("i:i"), Target) > 1 Then
                    X = Application.Match(Target, Range("i:i"), 0)
                If X = Target.Row Then
                    X = Application.Match(Target, Range(Target.Offset(1, 0), Cells(Lg, 1)), 0) + Target.Row
                End If
                    MsgBox ("Cette référence a déjà été scannée sur la" & Chr(10) & "ligne " & X), vbExclamation, "GESTION DES SCANS: DOUBLON"
                    'Cells(x, 1).Select
                    Target.ClearContents
                    ActiveSheet.Cells(Rows.Count, "I").End(xlUp)(2).Select

                   End If
                   End If
End Sub

Ces deux codes, sur des feuilles différentes fonctionnent. Par contre, l'un après l'autre , pas.... Je suis conscient qu'il faut enlever

Private Sub Worksheet_Change(ByVal Target As Range)

Comment faire donc pour que ces deux Worksheet_change cohabitent?

J'ai testé plusieurs options dont celle-ci avec un Exit Sub mais:

image

J'apprécierais encore une fois votre aide.

Merci par avance.

Patrick.

Bonjour PatPatrouille,

D'abord le code est une reprise de ma proposition auquel Bsalv a mis une boucle.

Donc forcément qu'il trouve des doublons dans la boucle.

Je rappelle que si les modifications se font une par une, il n'existe pas de souci.

Private Sub Worksheet_Change(ByVal Target As Range)
Dim i%
If Not Intersect(Target, Range("A15:A25")) Is Nothing and Target.count= 1 Then
  Application.ScreenUpdating = False
    'Conditions
    If Target = Target(0, 11) Then X = -1 Else X = Target
     Select Case X
      Case Is > 0
      Target.Offset(0, 10) = Format(Now, "hh:mm;@")
      Target.Offset(0, 9) = Format(Now, "dd/mm/yy")
       'case Test, doublon de la colonne I
      Target.Offset(0, 11) = Target
      Case Is = 0
      'RAZ Date/Heure et du Test
      For i = 9 To 11
       Target.Offset(0, i).Clear
       Next i
      Case Else
       'Nothing
     End Select
     Target.Offset(0, 9).Activate
Application.ScreenUpdating = True
End If
End Sub

Bonjour X Cellus,

Mes excuses, j'avais en un premier temps copier la réponse de BsAlv.... Pardon pour ce mal entendu.

Concernant le code, il fonctionne et c'est vraiment top. Mais comme je le dis dans mon précédent message, il entre en conflit avec un code que j'avais déjà créé et me retourne une erreur:

image

Car, effectivement il y a :

Private Sub Worksheet_Change(ByVal Target As Range)

et

Private Sub Worksheet_Change(ByVal Target As Excel.Range)

Ma question était donc de savoir comment faire pour unir ces deux codes sous un seul

Private Sub Worksheet_Change(ByVal Target As Range)

D'avance merci et encore toutes mes excuses.

Patrick.

@X Cellus, il faut connaitre l'histoire de cette question, quelque postes avant votre premier poste j'avais déjà donner cette fameuse macro "change" avec boucle, qui est pour moi une macro de niveau basic. Apparament, on ne peut pas dire la vérité ici ! Ce boucle est nécessaire parce qu'on ne peut pas demander aux utilisateurs de changer les cellules une par une. Je suis certain qu'ils font cela dans 99.9% des cas et dans ces cas votre macro est okay mais un moment donné, ils sont bêtes, rien à faire ... et à ce moment le boucle doit faire son boulot et vous ne pouvez pas chercher des excuses. Il n'y a pas de discussion possible à ce point là.

Bon, pour les doublons, ce n'est pas vraiment nécessaire, mais je blocque les évents un moment et dans le cas où la macro n'est pas bien terminée, il faut réactiver les events avec la macro "Eon"

Private Sub Worksheet_Change(ByVal Target As Range)
     Dim c, cl, s
     Set c = Intersect(Target, Range("A15:A25"))     'les cellules modifiée de cette plage
     Me.Range("I8:I6500").Name = "Scan"     'plage pour vérifier les doublons

     If Not c Is Nothing Then     'il y a des cellules modifiées dans cette plage
          Application.EnableEvents = False 'blocquer les events
          For Each cl In c.Cells     'pour chaque cellule modifiée
               If cl.Offset(, 8).Value = cl.Offset(, 11) Then X = -1 Else X = cl.Offset(, 8).Value     ' si I = L then X=-1 ou X=I
               Select Case X     'dépendant de la valeur de X, on change les cellules J-L
                    Case Is > 0:
                         cl.Name = "ScanValue" 'valeur du scan actuel
                         cl.Offset(0, 9).Resize(, 3) = Array(Format(Now, "dd/mm/yy"), Format(Now, "hh:mm;@"), cl.Offset(, 8).Value)     'J=date, K=heure, L=I
                         fl = Filter([transpose(if(scan=scanvalue,row(scan),"~"))], "~", 0)     'filtrer toutes les lignes avec le même scan-valeur
                         If UBound(fl) > 0 Then s = s & vbLf & vbLf & "Scanvalue : " & cl.Value & " dans cellule " & cl.Address & vbLf & "lignes doublons : " & Join(fl) 's'il y a plusieurs cellules avec le même valeur ...

                    Case Is = 0: cl.Offset(0, 9).Resize(, 3).Clear     'RAZ J-L

               End Select
               Application.Goto cl.Offset(0, 9)     'positionnez dans dernière cellule J modifiée
          Next
          Application.EnableEvents = True

     End If

     If Len(s) > 0 Then MsgBox Mid(s, 3), vbExclamation, "GESTION DES SCANS: DOUBLON"
End Sub

A nouveau,

il faut connaitre l'histoire de cette question, quelque postes avant votre premier poste j'avais déjà donner cette fameuse macro "change" avec boucle

@Bslav. Il faut surtout être honnête. Voilà, ta boucle sur ton code hors du contexte puisque les dates étaient toutes actualisées.

Private Sub Worksheet_Change(ByVal Target As Range)
     Dim c     As Range
     Set c = Intersect(Target, Range("I15:I25"))     'seulement les cellules changées de la plage I15:I25)
     If Not c Is Nothing Then
          Application.EnableEvents = False     'blocquer events
          For Each cl In c.Cells     'boucle ces cellules modifiée
               If cl.Value > 0 Then     'non vide
                    cl.Offset(, 2).Value = Format(Time, "hh:mm;@")     '2 cellules vers droite
                    cl.Offset(, 1).Value = Format(Date, "dd/mm/yy")     '1 cellule vers droite
               Else
                    cl.Offset(, 1).Resize(, 2).ClearContents
               End If
          Next
          Application.EnableEvents = True
     End If
End Sub

inutile de discuter, à la prochain.

BsAlv, X Cellus,

ça me désole quelque peu ces derniers messages. Les deux vous m'avez énormément aidé !! Un forum est un lieu de partage, peu importe qui fait quoi qui fait mieux! Chacun de vous avez apporté de bonnes réponses. La preuve, l'un rejoint l'autre sur la solution et c'est cela que qu'il faut retenir. L'union fait la force les gars!

Sincèrement, si nous habitions la même ville, je vous inviterais les deux à plusieurs bières!! C'est toujours plus sympas de rigoler que de s'e foutre plein la gu....

D'ailleurs, je souhaiterais vous remercier en privé pour votre contribution et le temps employé à trouver une solution pour cette "maudite" macro qui ne veut pas fonctionner :-) Un petit message privé vous seras remis.

Bon, je vais tester le dernier code remis voir si ça marche Bon Dieu!! Je vous tiens au jus.

Et, une fois encore, merci A VOUS DEUX.

Re et sûrement une dernière fois sur ce fil:

On va prendre le code qui fonctionne:

Private Sub Worksheet_Change(ByVal Target As Range)
     Dim c, cl
     Set c = Intersect(Target, Range("A15:A25")) 'les cellules modifiée de cette plage
     If Not c Is Nothing Then 'il y a des cellules modifiées dans cette plage
          Application.ScreenUpdating = False
          For Each cl In c.Cells 'pour chaque cellule modifiée

               If cl.Offset(, 8).Value = cl.Offset(, 11) Then X = -1 Else X = cl.Offset(, 8).Value ' si I = L then X=-1 ou X=I
               Select Case X 'dépendant de la valeur de X, on change les cellules J-L
                    Case Is > 0: cl.Offset(0, 20).Resize(, 3) = Array(Format(Now, "dd/mm/yy"), Format(Now, "hh:mm;@"), cl.Offset(, 8).Value) 'J=date, K=heure, L=I
                    Case Is = 0: cl.Offset(0, 20).Resize(, 3).Clear 'RAZ J-L
               End Select
          Next
          'Application.Goto cl.Offset(0, 9) 'positionnez dans dernière cellule J modifiée
     End If

Exit Sub

End Sub

Maintenant, pour faire simple: sur ce code, imaginons que les cellules qui changent sont sur une autre feuille nommée "test". Si A15:A25 changent dans "test", alors on exécute le reste du code. J'ai testé cela mais sans succès:

     Set c = Intersect(Target, Sheets("test"), Range("A15:A25")) 'les cellules modifiée de cette plage

Une fois cela fait je pense ne plus vous déranger. Puis Je me mettrai en contact avec vous pour vous remercier par le biais d'un petit quelque chose...

Merci.

Patrick.

Bonjour Patrick,

Tu ne semble pas comprendre ce qu'est un évènement et comment il s'applique

L'évènement Change, ne peut s'appliquer qu'à la feuille en question, sinon il faut utiliser cet évènement dans ThisWorkbook

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
End Sub

Dans la sub "Sh" représente l'objet feuille dans laquelle est faite la modification

J'espère que cela pourra t'aider

A+

bonjour PatPatrouille, BrunoM45, le fil,

Un évenement "change" n'est seulement pour les cellules sans formules, donc avec la macro "...Change..." dans le module d'une feuille ou dans thisworkbook, on ne détecte jamais une cellule qui change parce que une autre cellule change de valeur. On ne voit que les cellules changées par intervention physique (humaine, VBA , ...).

On a le choix pour détecter ces changements dans le module d'une feuille, mais cette macro ne détecte que les changements de cette feuille ou bien dans le module de thisworkbook, avec laquelle on couvre toutes les changements de chaque feuille, mais aussi plus difficile à gèrer.

Bon, cette macro est la 2ième option. Pour mieux comprendre le fonctionnement, mettez un point d'arrêt à la première ligne de cette macro avec F9 (Msgbox ...) et puis step-by-step avec F8 pour voire ce qu'il se passe.

Parfois, on n'aime pas qu'un évenement se produit, alors on sait blocqué cela avec "Application.EnableEvents = False" et puis (n'oubliez pas !!!) déblocquer avec "True".

22evenements.xlsb (24.73 Ko)
                   
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
     Dim c, cl, X

     MsgBox "feuille : " & Sh.Name & vbLf & "plage : " & Target.Address, vbInformation, "Modification cellules sans formules"

     Select Case LCase(Sh.Name)     'vérifier le nom de la feuille en MINISCULES

          Case "feuil1"     'vous modifiez quelque chose dans la feuille "Feuil1"
               Set c = Intersect(Target, Sh.Range("A15:A25"))     'les cellules modifiée de cette plage
               If Not c Is Nothing Then     'il y a des cellules modifiées dans cette plage
                    Application.ScreenUpdating = False
                    For Each cl In c.Cells     'pour chaque cellule modifiée

                         If cl.Offset(, 8).Value = cl.Offset(, 11) Then X = -1 Else X = cl.Offset(, 8).Value     ' si I = L then X=-1 ou X=I
                         Select Case X     'dépendant de la valeur de X, on change les cellules J-L
                              Case Is > 0: cl.Offset(0, 20).Resize(, 3) = Array(Format(Now, "dd/mm/yy"), Format(Now, "hh:mm;@"), cl.Offset(, 8).Value)     'J=date, K=heure, L=I
                              Case Is = 0: cl.Offset(0, 20).Resize(, 3).Clear     'RAZ J-L
                         End Select
                    Next
               End If

          Case "feuil2"     'vous modifiez quelque chose dans la feuil2
               Set c = Intersect(Target, Sh.Range("A15:A25"))     'les cellules modifiée de cette plage
               If Not c Is Nothing Then     'il y a des cellules modifiées dans cette plage
                    Application.EnableEvents = False
                    Sheets("Feuil1").Range("O1:O15").Value = "VBA changement sans event " & Format(Now, "hh:mm:ss")
                    Application.EnableEvents = True
                    Sheets("Feuil1").Range("P1:P15").Value = "VBA changement avec event " & Format(Now, "hh:mm:ss")
               End If

     End Select

End Sub

BsAlv,

merci pour cette dernière réponse.

Petit message privé pour te remercier personnellement.

Patrick.

BsAlv,

J'ai étudié tout le code que tu as gracieusement remis avec le fichier annexé. C'est parfait, il fonctionne!! Maintenant, je souhaite l'adapter à mon fichier mais après plus de deux heures d'études, d'essaies, de test... je bloque. Je bloque et je n'arrive pas à avancer malgré plusieurs recherches sur les sites de développement. Une dernière fois, sans volonté d'abuser de ton temps. Faisons simple et adaptons cela. Je voulais vraiment trouver par moi-même la solution mais je n'y arrive pas ce qui est encore plus frustrant.

Ma feuille se nomme SCAN (en majuscules) . Déjà là je bug car dès que je modifie le nom de la feuille, de l'onglet et la macro avec ce nom-là mais plus rien ne se passe.

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
     Dim c, cl, X

     Select Case LCase(Sh.Name)     'vérifier le nom de la feuille en MINISCULES

          Case "SCAN"     'vous modifiez quelque chose dans la feuille "SCAN"

Par la suite, sur la feuille SCAN, ce sont les cellules de i8 à i70 qui peuvent être modifiées sur mon fichier:

Set c = Intersect(Target, Sh.Range("i8:i70"))     'les cellules modifiée de cette plage

Puis, les cellules où doivent apparaître la date et l'heure sont U et V comme dans ton fichier à toi. Par contre je n'ai pas besoin que dans W il y ait une copie de ce qui est dans i. On reste donc uniquement avec la date et l'heure dans U et V quand i est modifiée.

En résumé c'est cela: Quant i est modifiée, U reçoit la date et V reçoit l'heure.

Actuellement, dans ton fichier, quand on modifie A, U reçoit la date, V reçoit l'heure et W reçoit la copie de i.

Finalement, pour simplifier, je n'ai pas besoin de ça:

 Case "feuil2"     'vous modifiez quelque chose dans la feuil2
               Set c = Intersect(Target, Sh.Range("A15:A25"))     'les cellules modifiée de cette plage
               If Not c Is Nothing Then     'il y a des cellules modifiées dans cette plage
                    Application.EnableEvents = False
                    Sheets("Feuil1").Range("O1:O15").Value = "VBA changement sans event " & Format(Now, "hh:mm:ss")
                    Application.EnableEvents = True
                    Sheets("Feuil1").Range("P1:P15").Value = "VBA changement avec event " & Format(Now, "hh:mm:ss")
               End If

     End Select

On reste donc que sur la feuille SCAN.

Voilà, comme déjà indiqué, je te remercie pour tout ton temps.

Je me tiens à ta disposition pour tout complément d'informaion.

Patrick.

Rechercher des sujets similaires à "petite macro qui plante tous"