Excel07: Changer valeur d'une cellule si on change une autre
Résolu/Fermé
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
-
13 nov. 2014 à 13:02
cs_douda06 Messages postés 67 Date d'inscription jeudi 25 octobre 2007 Statut Membre Dernière intervention 1 avril 2015 - 17 nov. 2014 à 18:44
cs_douda06 Messages postés 67 Date d'inscription jeudi 25 octobre 2007 Statut Membre Dernière intervention 1 avril 2015 - 17 nov. 2014 à 18:44
3 réponses
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
13 nov. 2014 à 13:17
13 nov. 2014 à 13:17
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
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
14 nov. 2014 à 08:01
14 nov. 2014 à 08:01
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
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
14 nov. 2014 à 18:19
14 nov. 2014 à 18:19
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?
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
14 nov. 2014 à 18:54
14 nov. 2014 à 18:54
Et pour cette instruction j'ai aussi une erreur:
.InsertLines 2, "If Cells(1, Target.Column).Value Like "*" & "Type de champs" Then Exit Sub"
Comme ci on ne peut pas insérer ce genre d'instructions, mais je ne sais pas pourquoi !!
.InsertLines 2, "If Cells(1, Target.Column).Value Like "*" & "Type de champs" Then Exit Sub"
Comme ci on ne peut pas insérer ce genre d'instructions, mais je ne sais pas pourquoi !!
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
Modifié par pijaku le 17/11/2014 à 07:49
Modifié par pijaku le 17/11/2014 à 07:49
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...
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
17 nov. 2014 à 11:33
17 nov. 2014 à 11:33
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 !!
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
17 nov. 2014 à 11:48
17 nov. 2014 à 11:48
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
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
13 nov. 2014 à 15:22
13 nov. 2014 à 15:22
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?
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
13 nov. 2014 à 15:56
13 nov. 2014 à 15:56
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
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
13 nov. 2014 à 16:34
13 nov. 2014 à 16:34
Est ce que ce code il faut le placer dans le module de la macro qui génère les feuilles? ou dans la feuille même "Controles".
Et les ".InsertLines" je dois les remplacer par la procédure Worksheet_Change ? c'est bien ça? Peux tu bien m'expliquer, merci
Et les ".InsertLines" je dois les remplacer par la procédure Worksheet_Change ? c'est bien ça? Peux tu bien m'expliquer, merci
pijaku
Messages postés
12263
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
4 janvier 2024
2 751
13 nov. 2014 à 16:43
13 nov. 2014 à 16:43
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...
cs_douda06
Messages postés
67
Date d'inscription
jeudi 25 octobre 2007
Statut
Membre
Dernière intervention
1 avril 2015
13 nov. 2014 à 19:14
13 nov. 2014 à 19:14
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?