Conserver ancienne valeur avec liste intuitive (worksheet.change)

Bonjour à tous,

Alors voilà, je bloque depuis un bon moment sur ce problème...

dans le fichier ci-joint, sur feuille "saisie", j'ai en ligne 1 et 3 une saisie numérique (avec liste standard ou direct tapée à la main), et en ligne 5 et 7 une saisie texte (avec liste par recherche intuitive [on tape la ou les premières lettres avant d'aller chercher les possibilités dans la liste]) .

mon code "worksheets_change" dans feuille "saisie" fonctionne bien si la valeur est directement rentrée dans la cellule (avec la recherche intuitive cela ne fonctionne pas), et que la valeur corresponde aux listes (colonne A feuille "données").

Mon souci est donc le suivant (exemple pour cellule A5 feuille "saisie") :

  • actuellement "alpha", je veux modifier en "béta"
  • avec la recherche intuitive, je tape "b"
  • je clique sur la liste déroulante et choisis "béta"
  • le message d'erreur apparait

en faisant cela, le code prend comme ancienne valeur "b" alors qu'il devrait garder "alpha" tant que la valeur de la cellule ne fait pas partie de la liste de données.

merci à tous ceux qui pourront m'éclairer.

fichier ci-joint

36fichier-trame.xlsm (45.17 Ko)

Bonjour toutes et tous

à tester, voir

dans : Private Sub Worksheet_Change(ByVal Target As Range)

ajouté On Error Resume Next

    If Not oldname = "néant" Then
    On Error Resume Next
    ' ...etc......
    If Not ActiveCell = "néant" Then
    On Error Resume Next
    ' ...etc......

j'ai plus de message d'erreur

crdlt,

André

Bonjour André,

j'ai appliqué tes modifs. Mais lorsque je fait la manip suivante :

  • je saisie "b" en A5
  • je clique sur la liste déroulante
  • je choisis "bravo" dans la liste

le message d'erreur "Erreur d'exécution '1004': La méthode 'Undo' de l'objet '_Application' a échoué" apparait

Re,

à retester

Toujours sur Private Sub Worksheet_Change(ByVal Target As Range)

j'ai mis On Error Resume Next

Dim oldname, name As Variant, cellulename, cellule, newcellule, ........... As Integer

On Error Resume Next

Application.EnableEvents = False

Application.Undo

etc.

plus d'erreur

crdlt,

André

Effectivement, plus de message d'erreur de cette façon. Merci à toi pour cette progression ^^.

Cela dit, ce n'est pas la solution appropriée pour mon code (du moins je ne pense pas).

sur la partie de code :

Application.EnableEvents = False

Application.EnableEvents = True

"oldname" récupère l'ancienne valeur avant modification.

dans le graphique, après une modification dans feuille "saisie", l'ancienne série données (correspondant à l'ancienne valeur) doit être supprimée et une nouvelle série données (correspondant à la nouvelle valeur rentrée) doit être crée.

avec la liste à sélection intuitive, dans feuille "saisie", lorsque je tape "a" puis sélectionne dans la liste "alpha", l'ancienne valeur (oldname) correspond à "a". Donc la partie du code pour supprimer l'ancienne série donnée dans le graphique ne pourra pas être exécuter et tout le reste sera faussé.

il faudrait donc trouver un moyen de conserver l'ancienne valeur tant que la valeur saisie ne se trouve pas dans la liste. (mais je n'arrive pas à cela dans mon code...)

Bonjour,

Ton Dim ne doit pas être après le If, mais tout au début.

Dim oldname, name As Variant, cellulename, cellule, newcellule, oldcellule As Object, lignename, lignecel, colname, ligne, newligne, oldligne, série, oldsérie, newsérie, newdébut, newfin, newdébut2, oldcellule As Integer

dans cette ligne seules name , oldcellule et oldcellule sont typées, toutes les autres sont Variant.

Il faut toutes les typer une à une.

As Object : si ce sont des cellules ou des plage typer au plus près : As Range

oldname = Target

oldname est Variant, ne fait pas confiance à vba pour choisir ce que tu veux. Si c'est la valeur alors = Target.Value

A-priori non gênant actuellement mais comme ça ne correspond pas à ce que tu veux je préfère te le signaler

Range("A1:B1", "A3:B3") donne A1:B3. Pour l'union c'est :

Union([A1:B1], [A3:B3])

Quand tu auras fait ces modif on y verra peut-être un peu plus clair.

        Set oldcellule = Sheets("heures").Range("A3:A8").Find(what:=oldname, LookAt:=xlWhole)
        oldligne = oldcellule.Row

et s'il n'a pas trouvé ???

eric

bonjour eric,

et s'il n'a pas trouvé ? alors il faut que "oldname" récupère l'ancienne valeur (la dernière valide dans la liste).

Si "oldname" est une valeur qui ne se trouve pas dans la liste déroulante (=colonne A feuille "données" [voir gestionnaires de noms]) , alors :

Set oldcellule = Sheets("heures").Range("A3:A8").Find(what:=oldname, LookAt:=xlWhole)

ne trouvera rien et la suite du code ne fonctionnera pas correctement.

Il faut trouver le moyen de lui dire : "si olname n'est pas dans liste de données, alors oldname = la valeur d'avant (celle qui était valide)"

Ce n'est pas à moi qu'il faut le dire, c'est à ton programme...

Tu ne le testes même pas.

If oldcellule  is nothing then
'...
else
'...
endif

eric

j' ai essayé de le testé tel que tu me le décris.

Mon problème : je ne trouve pas la bonne façon pour lui dire que

If oldcellule is nothing then

alors

"garde la dernière valeur valide" (c'est cette partie précise que je n'arrive pas à adapter à mon code)

encore merci pour ton aide

J'ai plutôt l'impression que ton principal problème est que lorsque tu déroules la validation par liste tu déclenches l'événement Change alors que pour vba tu es toujours en édition de la cellule.

Et ça il n'aime pas du tout. Un simple Intersect() plante alors qu'il ne devrait pas.

J'essaie de voir comment gérer tout ça..

J'ai plutôt l'impression que ton principal problème est que lorsque tu déroules la validation par liste tu déclenches l'événement Change alors que pour vba tu es toujours en édition de la cellule.

Et ça il n'aime pas du tout. Un simple Intersect() plante alors qu'il ne devrait pas.

J'essaie de voir comment gérer tout ça..

merci à toi

Bon, j'ai préféré ne rien garder, ton code me générait trop d'anomalies n'ayant rien à voir avec le vrai problème..

Je te laisse d'abord contrôler si ça fonctionne comme tu l'entends (résultats dans la fenêtre d'exécution), et remettre tes traitements ensuite selon les cas.

Il y a du code dans ThisWorkbook, dans la feuille et dans un module.

Et pense à tenir compte de tout ce que je t'ai dit sur la déclaration et le typage des variables, c'est important.

eric

19fichier-trame.xlsm (47.96 Ko)

Bon, j'ai préféré ne rien garder, ton code me générait trop d'anomalies n'ayant rien à voir avec le vrai problème..

Je te laisse d'abord contrôler si ça fonctionne comme tu l'entends (résultats dans la fenêtre d'exécution), et remettre tes traitements ensuite selon les cas.

Il y a du code dans ThisWorkbook, dans la feuille et dans un module.

Et pense à tenir compte de tout ce que je t'ai dit sur la déclaration et le typage des variables, c'est important.

eric

Merci à toi eric

Je regarde cela en détail ce week-end et reviendrai ici en fonction.

bonne journée à toi

Arnaud

Bon, j'ai préféré ne rien garder, ton code me générait trop d'anomalies n'ayant rien à voir avec le vrai problème..

Je te laisse d'abord contrôler si ça fonctionne comme tu l'entends (résultats dans la fenêtre d'exécution), et remettre tes traitements ensuite selon les cas.

Il y a du code dans ThisWorkbook, dans la feuille et dans un module.

Et pense à tenir compte de tout ce que je t'ai dit sur la déclaration et le typage des variables, c'est important.

eric

Merci à toi eric

Je regarde cela en détail ce week-end et reviendrai ici en fonction.

bonne journée à toi

Arnaud

salut eric,

j'ai réussi enfin à trouver la bonne solution à mon projet, en me servant pas mal de tes conseils.

encore merci à toi et je boucle le sujet ^^

Rechercher des sujets similaires à "conserver ancienne valeur liste intuitive worksheet change"