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
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 :)

3 réponses

pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
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" :

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

1
pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
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?
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

1
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
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?
0
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
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 !!
0
pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
Modifié par pijaku le 17/11/2014 à 07:49
Bonjour,

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...
0
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
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 !!
0
pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
17 nov. 2014 à 11:48
La ligne qui teste et sort si le test est faux est celle-ci :

.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
0
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
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?
0
pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
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
0
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
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
0
pijaku
Messages postés
12257
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
3 septembre 2021
2 694
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 :
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...
0
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
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?
0