La macro qui s'effectue une fois correctement, après plus rien!!

Résolu
bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   -  
bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   -
Bonjours à tous!

J'ai un problème avec mon fichier qui contient plusieurs macro. J'ai une macro qui s'active quand l'on double clic (Worksheet_BeforeDoubleClic) dans la colonne C de la feuille Coordonnées, pour modifier la valeur de cette cellule. J'ai une autre macro qui met les toutes entrées sur cette feuille en majuscule (UCase) aussi.

Elle s'effectue très bien la première fois, mais lorsque je veux modifier une autre valeur en double cliquant dans la colonne, plus rien ne se passe et même que l'autres macros se retrouvant sur cette feuille ne fonctionne plus non plus.

Qu'est-ce passe t'il?

Que puis-je faire pour corriger la situation?

Merci pour d'avance pour votre aide!

Voici les macro qui se retrouve directement sur ma feuille "Coordonnées"

Private dlig As Long
Private PL As Range
Public var As Variant
Option Explicit
  
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

Dim nValue As String
Dim NewVal As String
Dim f As Worksheet
Dim sheetName As String


Application.ScreenUpdating = False

For Each f In ActiveWorkbook.Worksheets
    f.Unprotect
Next

nValue = ActiveCell.Value

If Not Intersect(Target, Range("c5:c" & [a1048576].End(xlUp).Row + 1)) Is Nothing Then
        
    If MsgBox("Voulez-vous mofifier le numéro de ce sondage?", _
        vbYesNo + vbQuestion, "MODIFER") = vbYes Then
            NewVal = UCase$(Application.InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO", Type:=2))
            ActiveCell = NewVal
            
            
            
      
            If InStr(1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then
                sheetName = "CPTU"
            ElseIf InStr(1, nValue, "F") = 1 Then
                sheetName = "FORAGE"
            ElseIf InStr(1, nValue, "Z") = 1 Or InStr(1, nValue, "FZ") = 1 Then
                sheetName = "Piézomètres"
               
            ElseIf InStr(1, nValue, "I") = 1 Then
                sheetName = "Inclinomètres"
                
            Else
                sheetName = ""
                MsgBox "La valeur n'a pas été trouvé dans les autres feuilles! Mettre à jours les feuillets sur la page d'accueil!", vbCritical
            End If
                If Len(sheetName) > 0 Then
                Sheets(sheetName).Columns(1).Replace nValue, NewVal, LookAt:=xlWhole, SearchOrder:=xlByColumns
                End If
            
                
                                   
     
        If var <> Target Then
        var = Target.Value
        MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT"
    
        End If
        
    Else
    
    ActiveCell.Select
    
    End If
    
End If

For Each f In ActiveWorkbook.Worksheets
            f.Protect
        Next

Application.ScreenUpdating = True

ActiveCell.Offset(-1, 0).Select 'Range("B5").Select
 
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

ActiveSheet.Unprotect

If Target.Column >= 3 And Target.Column <= 5 Then
        'desactive les evenements excel: eviter appel recurcif a la suite du passage en majuscule
        Application.EnableEvents = False
        Target = UCase(Target)
    End If
    'active les evenements excel
    Application.EnableEvents = True


If Target.Cells.Count > 1 Then Exit Sub
If Target.Row < 5 Or Target.Column <> 5 Then Exit Sub
If Target.Value = "" Then Cells(Target.Row, 1).ClearContents
If Range("A5") <> "" Then
    dlig = Range("E5").End(xlDown).Row
    Set PL = Range("A5:A" & dlig)
    PL.Value = Range("a5").Value
   
End If


Dim T As Range, i&
Set T = [TableauCoord]
Application.EnableEvents = False
On Error Resume Next 'sécurité
If T.Rows.Count < 4 Then
  Application.Undo 'annulation
Else
  '---suppression des lignes vides---
  For i = T.Rows.Count - 1 To 4 Step -1
    If T(i, 1) = "" Then T(i, 1).EntireRow.Delete
  Next
  '---ajout de ligne---
  If T(T.Rows.Count, 1) <> "" Then
    Application.ScreenUpdating = False
    T(T.Rows.Count, 1).EntireRow.Insert
    T.Rows(T.Rows.Count - 1).FormulaR1C1 = T.Rows(T.Rows.Count).FormulaR1C1
    T.Rows(T.Rows.Count) = ""
    Application.ScreenUpdating = True
  End If
End If

Application.EnableEvents = True

ActiveSheet.Protect

End Sub

Private Sub worksheet_activate()
   
Dim resultat As String
Const Dossier As String = "6.02.06.MT.02."

ActiveSheet.Unprotect
If Range("a5") = 0 Then
    resultat = UCase(InputBox("Entrez le numéro du Bassin Versant!", "Bassin Versant"))
    If resultat <> "" Then
        dlig = Range("E5").End(xlDown).Row
        Set PL = Range("A5:A" & dlig)
        PL.Value = Dossier & resultat
    End If
    
End If

ActiveSheet.Protect
Range("b5").Select


End Sub

3 réponses

  1. PlacageGranby Messages postés 402 Statut Membre 26
     
    Bonjour,

    Je n'ai malheureusement pas le temps de plonger dans ton code.
    Mais, la meilleur façon de trouver le problème est avec une trace pas-à-pas.

    On va dans l'éditeur VBA, et on click dans la marge de gauche pour mettre un point d'arret.

    Ensuite, double click, et regarde ce que le code fait. Tu va voir.
    1 - si la macro s'exécute ou non avec le double click.
    Si elle ne s'exécute pas, c'est un problème relié a l'évènement. Le code n'est pas dans le bon évènement.

    2- si la macro s'exécute, alors tu fais F8 pour suivre pas a pas son exécution pour trouver pourquoi elle n'agit pas comme prévu.

    Bonne chance.
    0
    1. bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   1
       
      Merci beaucoup PlacageGranby!

      Ce que j'ai remarqué, c'est que quand je modifie la valeur d'une cellule en double-cliquant dessus, il va après la ligne
      Activecell = NewVal
      , dans la macro qui se trouve tout de suite après Worksheet_Change.

      Et revient ensuite après la ligne
      If Target.Row < 5 Or Target.Column <> 5 Then Exit [/contents/446-fichier-sub Sub]
      dans ma macro BeforeDoubleClic, à la ligne
      If [/contents/1169-vbscript-les-fonctions-de-chaines-de-caracteres InStr](1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then
      .

      Donc, ce que je comprend, c'est que c'est un changement de valeur. Alors, il va dans la macro qui correspond Worlsheet_Change.

      À cet endroit, j'ai une macro qui fait en sorte que toutes les entrées de données sont mis en majuscule ainsi qu'une macro qui ajoute des lignes à la fin de mon tableau lorsqu'il est plein.

      Quand je double-clic de nouveau sur une nouvelle cellule, plus rien ne se passe, je reste à ligne 1 de la macro BeforeDoubleClic!

      Est-ce ça mon problème, je ne sais pas trop?
      0
    2. PlacageGranby Messages postés 402 Statut Membre 26
       
      Tu commences avec une assignation
      nValue = ActiveCell.Value

      Ensuite, tu saisie la nouvelle info
      NewVal = UCase$(Application.InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO", Type:=2))

      Et tu changes activecell
      ActiveCell = NewVal

      Mais tu utilise
      If InStr(1, nValue, "C") = 1 Or InStr(1, nValue, "M") = 1 Then

      nValue est une variable qui a été assignée une seule fois, donc elle égale encore son ancienne valeur. Tu passe NewVall à ActiveCell, mais jamais a nValue.

      Est-ce voulu ?
      0
      1. bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   1 > PlacageGranby Messages postés 402 Statut Membre
         
        Bonjour PlacageGranby!

        Oui, c'est normal! Pour l'instant ça fonctionne bien!

        J'utilise nValue pour rechercher où est situé la valeur sélectionnée dans mes autres feuilles. Ensuite avec mon inputbox, je lui assigne une nouvelle valeur qui devient ma NewVal et que j'utilise pour remplacer l'ancienne valeur par la nouvelle.

        Peut-être bien que mon code n'est pas très bien écrit, mais ça fonctionne! Je suis débutant en VBA!

        Merci!
        0
  2. ThauTheme Messages postés 1564 Statut Membre 160
     
    Je n'aime pas Application.EnableEvents = False. Si dans ton code il y a une sortie dans laquelle tu as omis de remettre à True, ou si il plante avant la remise à True, les macros événementielles ne fonctionnent plus !
    J'utilise une booléenne comme dans cet exemple :

    Private TEST As Boolean
    
    Private Sub Worksheet_Change(ByVal Target As Range)
    If TEST = True Then Exit Sub
    TEST = True
    'le code...
    TEST = False 'à mettre à toutes les sorties If/Redo/Exit For/Exit sub/etc.
    End Sub

    Dans ton code du Double-Clic tu modifies l'onglet Coordonnées mais aussi d'autres onglets qui contiennent chacun l'événementielle Change avec des Application.EnableEvents = False. Il te faut donc vérifier ton code dans tous les onglets. Je pense que ton problème vient de là...

    l'Avantage de la bolléenne c'est que les autres événementielles continuent de fonctionner même si Test n'a pas été remis à False...

    Autre problème, tu déclares une variable publique dans le composant Feuil2(Corrdonnées).

    Public var As Variant

    Or, les variables publiques doivent être déclarées tout en haut d'un module standard, (Module1 par exemple).

    Pour éviter de déproteger puis reprotéger tes onglets à tout bout de champ, je te recommande ce petit bout de code du composant Thisworkbook :

    Private Sub Workbook_Open()
    Dim O As Object 'déclare la variable O (Onglet)
    
    For Each O In Sheets 'boucle sur tous les onglets du classeur
        O.Protect UserInterfaceOnly:=True 'protège l'onglet en laissant les macros agir
    Next O
    Sheets("Accueil").Select
    End Sub


    L'argument UserInterfaceOnly permet la modification par macro mais pas manuellement...
    0
    1. bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   1
       
      Merci ThauTheme pour la réponse!

      Premièrement, je comprend ce que tu dit par rapport à
      Application.EnableEvents=False
      mais comment modifier mon code avec ta proposition.

      Là, je suis un peu perdue! Est-ce que j'ajoute simplement les lignes de codes tel quelle?

      Pour le
      Public var As Variant
      . Il se retrouve en haut de la feuille Coordonnées. J'ai trouvé ça sur un forum, je voulais que lorsque je modifie une cellule qu'il me renvoie un message du genre "N'oubliez pas de changer le numéro dans la colonne X" à l'écran. Mais ça ne fonctionne pas, même si j'entre de nouveau la même valeur, il m'envoie le message.

      Quel problème, pourrais-je avoir avec le fait qu'il ne soit pas déclaré dans un module?

      Et pour ta proposition pour la protection, ça fonctionne très bien! Mais seulement pour la première modification que j'effectue dans ma feuille Coordonnées. Après, j'ai un message d'erreur parce que ma feuille est vérouillée! Il arrête à la ligne ActiveCell dans le code suivant:
      If var <> Target Then
              var = Target.Value
              MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT"
              ActiveCell.Offset(-1, 0).Select
              End If


      Merci beaucoup!
      0
      1. bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention   1 > bassmart Messages postés 281 Date d'inscription   Statut Membre Dernière intervention  
         
        Bonjours à tous!

        Problème réglé!

        Effectivement, le problème venait de
        Application.EnableEvents=False
        . j'ai ajouté une expression
        Application.EnableEvents=true
        à la fin de ma macro et ça corrigé mon problème.

        Et pour le code proposé par thautheme pour la protection des feuilles, ça marche très bien! C'était encore mon problème de
        Application.EnableEvents=False
        qui fesais tout planter!

        Voici mon code final!:
        Private dlig As Long
        Private PL As Range
        Option Explicit
          
        Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
        
        Dim nvalue As String
        Dim NewVal As Variant
        Dim f As Worksheet
        Dim valueRange As Range
        Dim Cpt As Integer
        
        
        Application.ScreenUpdating = False
        
        
        nvalue = ActiveCell.Value
        
        If Not Intersect(Target, Range("c5:c" & [a1048576].End(xlUp).Row + 1)) Is Nothing Then
                
            If MsgBox("Voulez-vous mofifier le numéro de ce sondage?", _
                vbYesNo + vbQuestion, "MODIFER") = vbYes Then
                
                
                NewVal = UCase(InputBox("Nouveau numéro de sondage?", "MODIFICATION DE NUMÉRO"))
                
                If NewVal = "" Then
                    ActiveCell.Offset(-1, 0).Select
                    Exit Sub
                Else
                    ActiveCell = NewVal
                End If
                
                
                    If InStr(1, nvalue, "C") = 1 Or InStr(1, nvalue, "M") = 1 Then
                        Set valueRange = Sheets("CPTU").Columns(1)
                        
                    ElseIf InStr(1, nvalue, "F") = 1 Then
                        Set valueRange = Sheets("FORAGE").Columns(1)
                        
                    ElseIf InStr(1, nvalue, "Z") = 1 Or InStr(1, nvalue, "FZ") = 1 Then
                        Set valueRange = Sheets("Piézomètres").Columns(2)
                       
                    ElseIf InStr(1, nvalue, "I") = 1 Then
                        Set valueRange = Sheets("Inclinomètres").Columns(2)
                        
                    Else
                        Set valueRange = Nothing
                        MsgBox "La valeur n'a pas été trouvé dans les autres feuilles! Mettre à jours les feuillets sur la page d'accueil!", vbCritical
                    End If
                    
                        If Not valueRange Is Nothing Then
                            valueRange.Replace nvalue, NewVal, lookat:=xlWhole, searchorder:=xlByColumns
                        End If
        
                
                                           
                If NewVal <> nvalue Then
                MsgBox "N'oubliez pas de changer le numéro dans la colonne ABRÉVIATION!", vbExclamation, "IMPORTANT"
                ActiveCell.Offset(-1, 0).Select
                End If
                
            Else
            
            ActiveCell.Offset(-1, 0).Select
            
            End If
            
        End If
        
                
        
        Application.ScreenUpdating = True
        Application.EnableEvents = True
        
         
        End Sub
        0