Ajouter des arguments à une procédure

Bonjour,

Il y a deux choses différentes dans ce qu'on a évoqué, d'abord la saisie d'un code inexistant : elle déclenche une erreur, récupérée et qui fait sortir de la procédure (mais laisse le faux code en C).

Deux réactions possibles : on annule l'opération ce qui rétablira le code remplacé par un code erroné (sans toucher aux autres données préexistantes). Il faut donc placer la procédure d'annulation dans la gestion d'erreur (sous l'étiquette), l'annulation impose de l'exécuter en interrompant les évènement, faire précéder l'étiquette d'une instruction Exit Sub (sans quoi on annulerait toutes les opérations à chaque fois !). Donc : Exit Sub ; étiquette ; évènements à False ; annulation ; évènements à True.

Et on teste pour vérifier l'absence d'impacts "colatéraux"...

Ou bien, à la saisie d'un faux code, on supprime le faux code et on supprime également les données liées à l'ancien en D E F.

On peut ici aussi utiliser la gestion d'erreur mais n'opérer que la suppression de la valeur erronée en C, qui relancera l'évènement pour supprimer les valeurs erronées. Au lieu de renvoyer à une étiquette, il serait sans doute alors préférable de gérer avec un instruction On Error Resume Next, suivie après la ligne susceptible de déclencher l'erreur d'un test déterminant s'il y a erreur et dans ce cas, on ramène Err.Number à 0 et on efface la cellule sur laquelle on est en train d'intervenir, et on sort. Le retour de la procédure fera le reste.

L'autre problème évoqué est plus délicat, je le laisse de côté pour l'instant, tu as de quoi t'entrainer.

A+

Super merci je vais essayer

J'espère que tes essais se poursuivent dans de bonnes conditions...

J'avais réécrit dans le courant de la nuit (sur papier, lors d'un réveil ponctuel) la procédure pour englober l'ensemble des questions soulevées, mais (désolé) je n'ai pas eu le loisir de pouvoir la trancrire... ça viendra !

A+

Sans mentir j'ai beaucoup de mal, car même si ce code VBA est dans le fichier que je dois rendre pour mon projet, il y a d'autre chose à côté pour mon projet et qui me demande beaucoup de temps malheureusement. Ce soir, très tard surement , je vais essayer d'y travailler dessus avec vos explications. En tout cas vraiment un grand merci parce que vous m'êtes d'une aide immense

Salut !

Vois cette nouvelle version :

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim coul&, n%, r As Range, hd
    If Target.Row < 3 Then Exit Sub
    If Intersect(Target, Me.Columns("C:E")) Is Nothing Then Exit Sub
    For Each r In Intersect(Target, Me.Columns("C:E")).Rows
        If Me.Cells(r.Row, 3) <> "" Then
            On Error Resume Next
            n = WorksheetFunction.Match(Me.Cells(r.Row, 3), [TABLEAU_COULEUR].Columns(1), 0)
            If Err.Number <> 0 Then
                Err.Number = 0
                Me.Cells(r.Row, 3).ClearContents
                Exit Sub
            End If
            coul = [TABLEAU_COULEUR].Cells(n, 4).Interior.Color
            hd = [TABLEAU_COULEUR].Cells(n, 2).Resize(, 2).Value
            Application.EnableEvents = False
            Me.Cells(r.Row, 6).Interior.Color = coul
            Me.Cells(r.Row, 4).Resize(, 2).Value = hd
            Application.EnableEvents = True
        Else
            Application.EnableEvents = False
            Me.Cells(r.Row, 6).Interior.ColorIndex = xlColorIndexNone
            Me.Cells(r.Row, 4).Resize(, 3).ClearContents
            Application.EnableEvents = True
        End If
    Next r
End Sub

Les changements :

  • On étend la zone d'intersection prise en compte par la macro aux colonnes C à E.
  • Compte tenu que l'intersection peut occuper 3 colonnes au lieu d'une, on ne considère plus la cellule mais la ligne renvoyée en tant que plage (variable r) dans la boucle ForEach... Next. Mais de cette ligne, on tire le numéro de ligne pour tester la cellule en colonne C.
  • Ainsi à partir de changements sur 3 colonnes, on revient sur le contenu de la colonne déterminante en C. Et on peut traiter l'ensemble à partir du contenu de la cellule en C.
  • La gestion d'erreur est modifiée pour traiter immédiatement le cas de faux code saisi en C : si erreur, on efface la cellule, et on sort.
Cet effacement relance la procédure qui trouvant cette cellule vide effacera le reste...
  • Rien de changé sur la suite, sauf que l'interruption des évènements lors des modifications devient obligatoire pour éviter une boucle infinie. Elle est fait très sélectivement pour couvrir les modifications sur les 3 colonnes.
  • En cas d'effacement, l'effacement couvre aussi la colonne F (en considérant la possibilité d'y avoir mis une mention, mais qui concernait alors les valeurs effacées, et donc peut être effacée aussi).

Bon courage.

Merci bien !

Effectivement lors de mes essais, je n'avais absolument penser à changer la zone d'intersection, je ne pensais qu'à mettre des if...

Enfin toujours est il qu'il fonctionne super bien, et qu'il ne me reste plus qu'à insérer la msgbox pour signaler que le code RAL est faux et qu'il faut en entrer un valide.

Merci beaucoup

A mettre dans la condition qui identifie l'erreur, avant le Exit Sub...

Bonsoir,

Voici le code avec l'ajout de la msgbox et des annotations pour confirmation

Merci beaucoup d'avance

Private Sub Worksheet_Change(ByVal Target As Range)                                                                                                             ' Procédure intervenant à chaque changement de valeur dans la feuille, Target est la plage modifiée
    Dim coul&, n%, r As Range, hd                                                                                                                               ' Déclaration des variables

    If Target.Row < 3 Then Exit Sub                                                                                                                             ' Si la plage modifiée ne se situe pas après la ligne 3, la procédure s'arrête

    If Intersect(Target, Me.Columns("C:E")) Is Nothing Then Exit Sub                                                                                            ' Si la plage modifiée ne se trouve pas dans entre les colonnes C et E, la procédure s'arrête

    For Each r In Intersect(Target, Me.Columns("C:E")).Rows                                                                                                     ' Balayage de la plage impactée (si comporte plusieurs cellules)

        If Me.Cells(r.Row, 3) <> "" Then                                                                                                                        ' Si la cellule n'est pas vide alors...
            On Error Resume Next                                                                                                                                ' S'il y a une erreur, la procédure est directement renvoyée à la valeur suivante
            n = WorksheetFunction.Match(Me.Cells(r.Row, 3), [TABLEAU_COULEUR].Columns(1), 0)                                                                    ' Recherche de la ligne où apparaît la valeur exacte du code RAL dans la plage "TABLEAU_COULEUR"

            If Err.Number <> 0 Then                                                                                                                             ' Si le gestionnaire d'erreur en détecte (<>0) alors...
                If MsgBox(Target & " n'est pas un code RAL valide," & Chr(10) & " veuillez en rentrer un autre.", vbExclamation, "Valeur fausse") = vbOK Then   ' Une boîte de dialogue avec "Valeur fausse" en titre apparaît avec la valeur rentrée et un message, Chr(10) = retour à la ligne et vbExclamation = fait apparaitre un point d'exclamation dans la boite de dialogue
                Err.Number = 0                                                                                                                                  ' Le gestionnaire d'erreur est réinitialisé
                Me.Cells(r.Row, 3).ClearContents                                                                                                                ' Les cellules où a lieu l'erreur sont nettoyées
                End If
                Exit Sub                                                                                                                                        ' La procédure s'arrête
            End If

            coul = [TABLEAU_COULEUR].Cells(n, 4).Interior.Color                                                                                                 ' Récupération de la couleur dans la 4ème colonne de la plage "TABLEAU_COULEUR" sur la ligne recherchée précédemment
            hd = [TABLEAU_COULEUR].Cells(n, 2).Resize(, 2).Value                                                                                                ' Récupération du texte dans la 2nde colonne de la plage "TABLEAU_COULEUR" et de la 2nde colonne (soit la 3ème colonne) par rapport la valeur de la ligne recherchée précédemment
            Application.EnableEvents = False                                                                                                                    ' Désactivation des évènements par sécurité
            Me.Cells(r.Row, 6).Interior.Color = coul                                                                                                            ' Affectation de la couleur dans la 3ème colonne après le code RAL
            Me.Cells(r.Row, 4).Resize(, 2).Value = hd                                                                                                           ' Affectattion du texte dans la 1ère et 2nde colonne après le code RAL
            Application.EnableEvents = True                                                                                                                     ' Réactivation des évènements

        Else                                                                                                                                                    ' Si la cellule ne comporte plus de valeur alors...
            Application.EnableEvents = False                                                                                                                    ' Désactivation des évènements par sécurité
            Me.Cells(r.Row, 6).Interior.ColorIndex = xlColorIndexNone                                                                                           ' Supprime la couleur de la 3ème colonne après le code RAL
            Me.Cells(r.Row, 4).Resize(, 3).ClearContents                                                                                                        ' Supprime le texte dans la 1ère et 2nde colonne après le code RAL
            Application.EnableEvents = True                                                                                                                     ' Réactivation des évènements

        End If

    Next r                                                                                                                                                      ' On passe à la ligne suivante

End Sub

Bonsoir,

Juste un point, il faut que tu remplaces Target par Me.Cells(r.Row, 3) dans ton MsgBox. Target pouvant comporter plusieurs cellules il faut pointer la cellule qui est en C... Certes cette erreur ne se produira pas lors d'un effacement et ne peut se produire en principe que lors de la frappe d'un code en C, mais on ne peut toutefois exclure que quelqu'un vienne mettre plusieurs codes par collage...

Sinon le test sur le bouton de la MsgBox, tu peux t'en dispenser, tu n'as qu'un bouton OK et l'utilisateur est dans tous les cas obligé de cliquer OK pour que la boîte disparaisse...

Une petite précision sur la boucle : la variable r est de type Range (mais Range est un type un peu multiforme), on effectue la boucle non pas sur des cellules individualisées, mais sur les lignes de la plage d'intersection, et à partir de la ligne on va pointer la cellule de la ligne en C (même si elle n'est pas comprise dans l'intersection) car c'est sa valeur qui est déterminante. r est la variable objet qui permet de boucler sur les lignes de l'intersection mais pour pouvoir pointer la bonne cellule c'est le numéro de ligne qu'il nous faut, qui est donc renvoyé par r.Row.

Bonne continuation. Cordialement.

Bonjour,

Très bien merci c'est noté

Concernant le test sur le bouton, je suis obligé de le mettre ( je ne comprend pas pourquoi...) car si je le met pas et que j'écris ma ligne de code comme ça :

MsgBox(Me.Cells(r.Row, 3) & " n'est pas un code RAL valide," & Chr(10) & " veuillez en rentrer un autre.", vbExclamation, "Valeur fausse")

J'ai ce message d'erreur qui apparaît : "Erreur de complilation: Attendu : ="

Cordialement

Parce qu'il faut pas mettre de parenthèse dans ce cas : MsgBox est une fonction :

If MsgBox(message, vbExclamation, titre) = vbOK 

ou

a = MsgBox(message, vbExclamation, titre)

utilisation en tant que fonction, pour renvoyer une valeur.

MsgBox message, vbExclamation, titre

utilisation comme procédure d'affichage de message.

Mais MsgBox(message) est accepté [avec seulement le premier argument].

Cordialement.

Super !

Et bien mon code est achevé maintenant, un grand merci à vous MFerrand, vous m'avez énormément aidé pour mon projet de fin d'étude et vous m'avez appris beaucoup de chose dans la programmation VBA.

A bientôt dans un autre sujet !

Bonne continuation.

Rechercher des sujets similaires à "ajouter arguments procedure"