Excel07: Changer valeur d'une cellule si on change une autre
Résolu
cs_douda06
Messages postés
67
Date d'inscription
Statut
Membre
Dernière intervention
-
cs_douda06 Messages postés 67 Date d'inscription Statut Membre Dernière intervention -
cs_douda06 Messages postés 67 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'ai un fichier Excel avec plusieurs macros, et je veux y integrer une fonctionnalité.
Comment fait t-on SVP pour changer la valeur d'une cellule (cellule texte et/ou data validation combobox) automatiquement dès qu'on change une valeur d'une autre cellule?
1- Si je choisis une valeur parmis une liste sur une cellule précise, dans la même ligne dans la colonne "Type du champs", je veux qu'automatiquement le type devient "Combobox". Et si je mets la date sur une autre cellule, le type devient "Date", etc.
Pour info "Type du champs" est une liste qui contient ces valeurs : (Date, auto, checkbox, texte, liste, selection)
2- Si je mets la valeur "0" dans une cellule précise de la colonne "Minimum" je voudrai que dans la même ligne dans la colonne "Condition" la valeur "Optionel" soit settée, sinon si on a "1", on aura "Obligatoire" à la place.
3- Si je mets une valeur supérieur à "1" dans la colonne "Maximum", je voudrai que dans la même ligne dans la colonne "plusieurs valeurs" on aura True automatquement affichée, sinon si c'est égale à 1 ou a 0, False sera affichée.
J'ai déjà essayé avec la fonction:
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
Mais ça ne change rien, je ne sais pas où la placer et comment lui faire l'appel ! Pourvez vous m'aider?
J'ai mis le fichier de base sur ce lien: https://www.cjoint.com/?0KnnhSR4Lnu
Merci d'avance :)
J'ai un fichier Excel avec plusieurs macros, et je veux y integrer une fonctionnalité.
Comment fait t-on SVP pour changer la valeur d'une cellule (cellule texte et/ou data validation combobox) automatiquement dès qu'on change une valeur d'une autre cellule?
1- Si je choisis une valeur parmis une liste sur une cellule précise, dans la même ligne dans la colonne "Type du champs", je veux qu'automatiquement le type devient "Combobox". Et si je mets la date sur une autre cellule, le type devient "Date", etc.
Pour info "Type du champs" est une liste qui contient ces valeurs : (Date, auto, checkbox, texte, liste, selection)
2- Si je mets la valeur "0" dans une cellule précise de la colonne "Minimum" je voudrai que dans la même ligne dans la colonne "Condition" la valeur "Optionel" soit settée, sinon si on a "1", on aura "Obligatoire" à la place.
3- Si je mets une valeur supérieur à "1" dans la colonne "Maximum", je voudrai que dans la même ligne dans la colonne "plusieurs valeurs" on aura True automatquement affichée, sinon si c'est égale à 1 ou a 0, False sera affichée.
J'ai déjà essayé avec la fonction:
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
Mais ça ne change rien, je ne sais pas où la placer et comment lui faire l'appel ! Pourvez vous m'aider?
J'ai mis le fichier de base sur ce lien: https://www.cjoint.com/?0KnnhSR4Lnu
Merci d'avance :)
3 réponses
Bonjour,
Ou placer la procédure WorkSheet_Change()?
Tout simplement dans le Module de la feuille concernée. Pour cela, clic droit sur l'onglet de cette feuille / Visualiser le code.
Il est inutile d'appeler la fonction événementielle Worksheet_Change, elle s'appelle dès que l'événement est réalisé. En l'occurrence dès qu'une cellule de la feuille concernée change de valeur.
A titre d'exemple, place ce code dans le Module de ta feuille "Feuille_exemple" :
Ou placer la procédure WorkSheet_Change()?
Tout simplement dans le Module de la feuille concernée. Pour cela, clic droit sur l'onglet de cette feuille / Visualiser le code.
Il est inutile d'appeler la fonction événementielle Worksheet_Change, elle s'appelle dès que l'événement est réalisé. En l'occurrence dès qu'une cellule de la feuille concernée change de valeur.
A titre d'exemple, place ce code dans le Module de ta feuille "Feuille_exemple" :
Private Sub Worksheet_Change(ByVal Target As Range) 'Si la colonne de la cellule qui a changé n'est pas la colonne M 'ET si la ligne est la ligne 1 '==> Alors on sort de la procédure. 'cad qu'on ne va cibler que les cellules de la plage M2:Mxxx If Target.Column <> 13 And Target.Row < 2 Then Exit Sub 'On utilise l'événement Change pour ajouter une valeur dans une autre cellule. 'par conséquent, l'ajout de cette valeur va déclencher l'événement Change 'qui lui même va re-déclencher l'événement Change... Etc... 'Donc, il nous faut déactiver les événements Application.EnableEvents = False 'Ici on inscrit simplement "Combobox" dans la cellule de la colonne J même ligne que Target Target.Offset(0, -3) = "ComboBox" 'on réactive les événements : Application.EnableEvents = True End Sub
Bonjour,
En fait, tu peux cibler les cellules "cibles", les "Target", comme bon te semble. Le but est que la macro événementielle ne se déclenche pas à chaque changement de valeur de toutes tes cellules. Tu dois donc, pour cela, cibler la (les) plage(s) "utile(s)".
Dans ton cas, les plages utiles sont toutes les colonnes dont la valeur en ligne 1 se termine par "Type de champs".
Comment les cibler et ne cibler que celles-la?
La cellule en première ligne de cette colonne est donc :
Tu veux savoir si cette cellule contient "Type de champs" mais pas que... :
Comme bien souvent en programmation, on va tester l'inverse et sortir si c'est le cas :
En fait, tu peux cibler les cellules "cibles", les "Target", comme bon te semble. Le but est que la macro événementielle ne se déclenche pas à chaque changement de valeur de toutes tes cellules. Tu dois donc, pour cela, cibler la (les) plage(s) "utile(s)".
Dans ton cas, les plages utiles sont toutes les colonnes dont la valeur en ligne 1 se termine par "Type de champs".
Comment les cibler et ne cibler que celles-la?
Target.Column=> c'est le numéro de la colonne à laquelle appartient ta cellule.
La cellule en première ligne de cette colonne est donc :
Cells(1, Target.Column).
Tu veux savoir si cette cellule contient "Type de champs" mais pas que... :
If Cells(1, Target.Column).Value Like "*" & "Type de champs" Then.
Comme bien souvent en programmation, on va tester l'inverse et sortir si c'est le cas :
If Not Cells(1, Target.Column).Value Like "*" & "Type de champs" Then Exit Sub
Il parait que malgrés ça je ne m'en sors pas avec mes connaissances limitées, j'ai fait ceci, mais ça me donne erreur (VAriable non définit, et Target est selectionné) :
Private Sub CreerCode(SheetName As Variant)
With ThisWorkbook.VBProject.VBComponents(SheetName).CodeModule
.InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)"
'.InsertLines 2, "If Target.Column = 13 And Target.Row < 2 Then Exit Sub"
If Cells(1, Target.Column).Value Like "Lists" Then
.InsertLines 3, "Application.EnableEvents = False"
.InsertLines 4, "Target.Offset(0, 13) = ""combobox"""
.InsertLines 5, "Application.EnableEvents = True"
.InsertLines 6, "End Sub"
End With
End Sub
Est ce qu'il faut importer/ declarer queqlechose?
Private Sub CreerCode(SheetName As Variant)
With ThisWorkbook.VBProject.VBComponents(SheetName).CodeModule
.InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)"
'.InsertLines 2, "If Target.Column = 13 And Target.Row < 2 Then Exit Sub"
If Cells(1, Target.Column).Value Like "Lists" Then
.InsertLines 3, "Application.EnableEvents = False"
.InsertLines 4, "Target.Offset(0, 13) = ""combobox"""
.InsertLines 5, "Application.EnableEvents = True"
.InsertLines 6, "End Sub"
End With
End Sub
Est ce qu'il faut importer/ declarer queqlechose?
Bonjour,
Essaye ceci :
De plus SheetName ne doit pas être le Nom (propriété Name) de la feuille créée, mais son CodeName. Attention à cela également...
Essaye ceci :
Private Sub CreerCode(SheetName As Variant) With ThisWorkbook.VBProject.VBComponents(SheetName).CodeModule .InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)" .InsertLines 2, "If Cells(1, Target.Column).Value Like ""Lists"" Then" .InsertLines 3, "Application.EnableEvents = False" .InsertLines 4, "Target.Offset(0, 13) = ""combobox""" .InsertLines 5, "Application.EnableEvents = True" .InsertLines 6, "End If" .InsertLines 7, "End Sub" End With End Sub
De plus SheetName ne doit pas être le Nom (propriété Name) de la feuille créée, mais son CodeName. Attention à cela également...
Bonjour,
J'ai testé ça marche bien pour un seul champ. Si je veux que ""combobox"" soit généré dans tous les champs qui terminent par Type de champs, je fais comment stp?
J'ai essayé de remplacer
.InsertLines 4, "Target.Offset(0, 13) = ""combobox"""
Par:
.InsertLines 4, "Cells(1,Target.Column).Value Like "*" & "Type de champs" = ""combobox"""
mais j'ai Erreur de Syntax !!
J'ai testé ça marche bien pour un seul champ. Si je veux que ""combobox"" soit généré dans tous les champs qui terminent par Type de champs, je fais comment stp?
J'ai essayé de remplacer
.InsertLines 4, "Target.Offset(0, 13) = ""combobox"""
Par:
.InsertLines 4, "Cells(1,Target.Column).Value Like "*" & "Type de champs" = ""combobox"""
mais j'ai Erreur de Syntax !!
La ligne qui teste et sort si le test est faux est celle-ci :
C'est toi qui a transformé mon code initial.
J'avais mis :
Donc, à tester :
.InsertLines 2, "If Cells(1, Target.Column).Value Like ""Lists"" Then"
C'est toi qui a transformé mon code initial.
J'avais mis :
If Not Cells(1, Target.Column).Value Like "*" & "Type de champs" Then Exit Sub
Donc, à tester :
Private Sub CreerCode(SheetName As Variant) With ThisWorkbook.VBProject.VBComponents(SheetName).CodeModule .InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)" .InsertLines 2, "If Not Cells(1, Target.Column).Value Like ""*Type de champs"" Then Exit Sub" .InsertLines 3, "Application.EnableEvents = False" .InsertLines 4, "Target.Offset(0, 13) = ""combobox""" .InsertLines 5, "Application.EnableEvents = True" .InsertLines 6, "End If" .InsertLines 7, "End Sub" End With End Sub
Merci pour ta réponse pijaku,
le souci pour cette procédure c'est que les feuilles où je dois la poser n'existent pas au premier coup, il faut les générer et seulement après leur édition qu'on peut avoir besoin de cette procédure. Est t-il possible de l'ajouter pour qu'elle soit exécutée après la macro principale qui génère ces feuilles?
le souci pour cette procédure c'est que les feuilles où je dois la poser n'existent pas au premier coup, il faut les générer et seulement après leur édition qu'on peut avoir besoin de cette procédure. Est t-il possible de l'ajouter pour qu'elle soit exécutée après la macro principale qui génère ces feuilles?
Ce code copie la feuille 1 et créée, dans le module de la copie la procédure que je t'ai donné avant :
Dim NomFeuil Sheets(1).Copy After:=Worksheets(Worksheets.Count) NomFeuil = ActiveSheet.CodeName With ThisWorkbook.VBProject.VBComponents(NomFeuil).CodeModule .InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)" .InsertLines 2, "If Target.Column <> 13 And Target.Row < 2 Then Exit Sub" .InsertLines 3, "Application.EnableEvents = False" .InsertLines 4, "Target.Offset(0, -3) = ""ComboBox""" .InsertLines 5, "Application.EnableEvents = True" .InsertLines 6, "End Sub" End With
Dans ta procédure CreationFeuille(), tu réalises plusieurs actions en appelant des fonctions :
'- ajouter la feuille
Set w = AjoutFeuille(c.Value)
'- remplir la feuille
Call RemplirFeuille(w, c)
'- mettre à jour la feuille X
Call MàjFeuilleX(c.Value)
Tu souhaites, en plus de ces actions, insérer, dans chacune des feuilles que tu créées de cette manière, un code "événementiel".
A ta place, je créerai donc une fonction supplémentaire pour créer ces codes. Un peu comme ceci :
Fonction que j'appellerai, dans la procédure principale, comme ceci :
Que fais la fonction CreerCode?
Tout simplement :
Dans le module de la feuille (dont on a passé le CodeName en paramètre de la fonction),
elle insère des lignes les unes après les autres
et y inscrit le code.
.InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)"
en fait, écrit Private Sub Worksheet_Change(ByVal Target As Range) en 1ère ligne du Module
Etc Etc...
'- ajouter la feuille
Set w = AjoutFeuille(c.Value)
'- remplir la feuille
Call RemplirFeuille(w, c)
'- mettre à jour la feuille X
Call MàjFeuilleX(c.Value)
Tu souhaites, en plus de ces actions, insérer, dans chacune des feuilles que tu créées de cette manière, un code "événementiel".
A ta place, je créerai donc une fonction supplémentaire pour créer ces codes. Un peu comme ceci :
Sub CreerCode(NomFeuil As Variant) With ThisWorkbook.VBProject.VBComponents(NomFeuil).CodeModule .InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)" .InsertLines 2, "If Target.Column <> 13 And Target.Row < 2 Then Exit Sub" .InsertLines 3, "Application.EnableEvents = False" .InsertLines 4, "Target.Offset(0, -3) = ""ComboBox""" .InsertLines 5, "Application.EnableEvents = True" .InsertLines 6, "End Sub" End With End Sub
Fonction que j'appellerai, dans la procédure principale, comme ceci :
Public Sub CreationFeuille() ' Crée les feuilles Dim w As Worksheet 'feuille Dim r As Range 'plage de cellules Dim c As Range 'cellule Application.ScreenUpdating = False 'Définir la plage de titres contenant les préfixes du nom des feuilles With Worksheets("Donnees").Cells(1, colNom) Set r = .Resize(1, .End(xlToRight).Column - .Column + 1) End With 'Ajouter et mettre à jour les feuilles For Each c In r.Cells '- ajouter la feuille Set w = AjoutFeuille(c.Value) 'créer le code événementiel Call CreerCode(w.CodeName) '- remplir la feuille Call RemplirFeuille(w, c) '- mettre à jour la feuille X Call MàjFeuilleX(c.Value) Next c Application.ScreenUpdating = True MsgBox "feuilles crées" End Sub
Que fais la fonction CreerCode?
Tout simplement :
Dans le module de la feuille (dont on a passé le CodeName en paramètre de la fonction),
elle insère des lignes les unes après les autres
et y inscrit le code.
.InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)"
en fait, écrit Private Sub Worksheet_Change(ByVal Target As Range) en 1ère ligne du Module
Etc Etc...
Cool, J'ai fait le test, c'est Ok, par contre pour le traitement de la fonction, comment peut t-on éviter de situer les cellules par leur indices comme sur l'exemple : Target.Column <> 13 .. ?
Et ceci parceque j'ai sur le vrai fichier Excel plusieurs colonnes " AA Type du champs" "BB Type du champs" ... ? donc pour les remplir automatiquement, à mon avis, ça serait préférable de ne pas fixer les indices, on peut jouer avec le label de ces colonnes, vu qu'il se terminent tous par "..Type de champs"
Y'a t-il un moyen facile pour le faire?
Et ceci parceque j'ai sur le vrai fichier Excel plusieurs colonnes " AA Type du champs" "BB Type du champs" ... ? donc pour les remplir automatiquement, à mon avis, ça serait préférable de ne pas fixer les indices, on peut jouer avec le label de ces colonnes, vu qu'il se terminent tous par "..Type de champs"
Y'a t-il un moyen facile pour le faire?