VBA listes déroulantes et boucles

Bonjour!

J'ai actuellement un problème avec des listes déroulantes :

J'ai en feuille1 une liste qui ressemble à çà:

---A---B

1--1----

2--1---1

3--1---2

4--1---3

5--1---4

6--2----

7--2---1

Etc. Etc. Etc.

Je voudrais rentrer en feuille2 tous les nombres de la colonne B de la feuille1 dont le nombre de la même ligne et colonne A est 1 (1;2;3;4...)

J'ai pour cela rentré le code suivant qui marche MAIS il ne va pas jusqu'au bout ou, des fois, il ne sort pas de la première boucle (je travail en déboggage avec F8, ça m'evite de redémarrer excel dans ces cas la)

Voici le code :

Private Sub ComboBox1_Change()

Dim i As Integer
I=17          'le tableau en feuille1 commence en fait en ligne 19
Sheets("Feuil1").Select
Do Until Selection.Cells(i, 1).Formula = "1"
       i = i + 1
Loop

i = i + 1   ' pour ajuster le tir...

Do While Selection.Cells(i, 1).Fomula = "1"   'j'ai aussi essayé avec until et <>
        ComboBox1.AddItem(ActiveSheet.Cells(i, 2).FormulaLocal)   'ou 
         i = i + 1.                                                                              '.Formula
Loop

End Sub

-- 07 Juil 2011, 14:06 --

Quelqu'un verrait l'erreur du code? Ou si quelque chose ne va pas?!

Je suis preneur pour toute remarque même les fautes d'orthographe (enfin celles du code XD)

Merci à tous!

Bonjour

Je ne suis pas apte à contrôler ta macro.

Une solution par formules

Cordialement

87classeur2.zip (3.37 Ko)

Salut Sym et le forum

Quelqu'un verrait l'erreur du code ? Ou si quelque chose ne va pas ?! 

Pour dépanner un code, il faut savoir ce qu'il doit faire. Et si le code est "faux"...

Private Sub ComboBox1_Change()
Dim i As Integer
I=17          'le tableau en feuille1 commence en fait en ligne 19
Sheets("Feuil1").Select
Do Until Selection.Cells(i, 1).Formula = "1"
       i = i + 1
Loop

Tout ce que je peux faire, c'est "critiquer" ce bout de code, tant pis pour toi

Tu déclares i en integer => vaut mieux le déclarer en long

tu initialises i à 17 alors qu'il doit commencer à 19 ???

tu sélectionne la feuille "Feuil1" : sert qu'à ralentir ton code

Tu fait une boucle jusqu'à ce qu'elle trouve le chiffre 1 en formule ??? et tu t'étonnes qu'excel ne trouve pas l'égalité ?

Sur une boucle comme ça : utiliser une égalité ... si excel ne la voit pas, il va jusqu'à la fin de la feuille (ou, comme tu as déclaré ta variable ligne en entier, jusqu'au dépassement de valeur d'un entier = 32767). c'est pour ça que je n'utilise pas les boucles infinies (do, while).

en sachant ce qu'est supposé faire ta macro, on ne devrait pas avoir de difficulté à la corriger.

A+

Bonsoir!

A vrai dire cela ne me dérange pas de recevoir des critiques, mais en l'occurrence, excuse moi de trouver répliques à quasi toutes

je te remercie cependant pour le long à la place de l'integer ; à vrai dire je connais pas trop la difference

Sinon, pour le i commençant à 17, c'est jusque que lorsque j'ai commencé la macro, je voulais juste savoir comment évoluait le bazar, (je rappel que je débute )...

Ensuite, j'active la feuille 1 d'abord car le tableau se trouve en feuille 1 alors que la liste déroulante (le comboBox1) se trouve en feuille 2.. Si c'est bien çà que tu avais compris, je veux bien plus d'explications

Enfin, pour les boucles while et until, çà fait pas longtemps que je maitrise et j'aime beaucoup ; çà change des for-next et des if &Cie Mais j'avais pensé à leur faire une porte de sortie (genre i = 12 tu sors) jusqu'à ce que... Je trouve la solution!

Private Sub ComboBox1_[b]Click[/b]()

ComboBox1.Clear

Dim i As [b]Long[/b]  ';-)
[b]I=19  [/b]        'le tableau en feuille1 commence en fait en ligne 19
Sheets("Feuil1").Select
Do Until [b]ActiveSheet[/b].Cells(i, 1).Formula = "1"
     [b] If i = 22 then         'une petite marge quand même au cas où
            MsgBox "çà marche pas!"
            Exit Do
      Else[/b]
             i = i + 1
      [b]End If[/b]
Loop

i = i + 1   ' pour ajuster le tir...

Do While [b]ActiveSheet[/b].Cells(i, 1).Fomula = "1"   
 [b] If i = 34 then '22+12 ;-)
            MsgBox "çà marche pas!"
            Exit Do
      Else[/b]       
            ComboBox1.AddItem(ActiveSheet.Cells(i, 2).FormulaLocal)  
            i = i + 1.
     [b] End If   [/b]                                                                           
Loop

End Sub
 

voilà

Sinon, pour Amadeus, le fichier que tu as donné est quasiment çà, à part que par nombre en colonne A, il n'y aura jamais plus que 12 nombres en colonne B et ils commencent tous par 1 et sont dans l'ordre...

Quant à la feuille 2, c'est exactement çà mais en liste déroulante

Sur ce, merci pour vos réponses,

J'attend vos remarques avec impatience

-- 07 Juil 2011, 22:06 --

Je me permet de dire ce problème Résolu mais j'attend toutefois vos éventuelles remarques =)

Salut Sym et le forum

A vrai dire cela ne me dérange pas de recevoir des critiques, mais en l'occurrence, excuse moi de trouver répliques à quasi toutes

hors de question que je t'excuse : si je critique ton travail, il me semble normal que tu puisses critiquer le mien ! Si je n'accepte pas que tu me rendes la pareille, je n'ai rien à faire ici, sur ce forum (n'espère pas, je compte m'incruster longtemps )!

je te remercie cependant pour le long à la place de l'integer ; à vrai dire je connais pas trop la difference

integer : 2 octets pour définir un nombre de -32768 à +32767

Long : 4 octets pour définir un nombre de -2147483648 à +-2147483647

D'après une discussion sur un forum, de toute façon, Excel ne calcule que sur des longs. Pour un gain ridicule (2 octets en RAM), on risque un dépassement de capacité en cas de fausse manip. Pour éviter tout risque, je déclare mes variables nombres entiers en Long.

Sinon, pour le i commençant à 17, c'est jusque que lorsque j'ai commencé la macro, je voulais juste savoir comment évoluait le bazar

Se donner une marge de manœuvre est loin d'être idiot. Ça permet de rajouter un titre par exemple.

Ensuite, j'active la feuille 1 d'abord car le tableau se trouve en feuille 1 alors que la liste déroulante (le comboBox1) se trouve en feuille 2.. Si c'est bien çà que tu avais compris, je veux bien plus d'explications

On a tous commencé par les macros "apprentissage" (nouvelle macro). Le code que fournit Excel est le reflet exact des opérations que tu as effectuées.

Tu inscrit 1 en A1 Feuil1, puis 2 en C1 Feuil2. Excel te donne :

Sheets("Feuil1").Select
ActiveCell.FormulaR1C1 = "1"
Range("A2").Select
Sheets("Feuil2").Select
Range("C1").Select
ActiveCell.FormulaR1C1 = "2"
Range("C2").Select

Le même résultat, avec un code qui ne comporte pas de lignes "parasites" :

Sheets("Feuil1").Range("A1") = 1
Sheets("Feuil2").Range("C1") = 2

C'est plus concis, plus clair, mais surtout, le temps de traitement n'est pas du tout le même. Sur une (ou dix) instruction(s), ce n'est pas significatif. Mais le traitement de 10000 lignes de données et on a un traitement en minutes, contre un traitement en secondes.

Enfin, pour les boucles while et until, çà fait pas longtemps que je maitrise et j'aime beaucoup ; çà change des for-next et des if &Cie. Mais j'avais pensé à leur faire une porte de sortie (genre i = 12 tu sors) jusqu'à ce que... Je trouve la solution!

Faut être réaliste : un code est purement personnel ! C'est pour ça qu'il y a souvent plusieurs réponses à une question donnée.

Je préfère les boucles For...Next, parce qu'elles sont finies. Mais quand je navigue dans l'inconnu, j'utilise aussi des Do...Loop. Mais je cherche toujours un moyen d'en sortir, si ce que j'avais prévu ne fonctionne pas comme je m'y attends. Ce qui fait beaucoup plus d'instructions qu'un simple For...Next.

Dim I As Long

ComboBox1.Clear
I = 19

With Sheets("Feuil1")
    Do Until .Cells(I, "A") = 1
        If I = 22 Then
            MsgBox "ça marche pas!"
            Exit Sub
        Else
            I = I + 1
        End If
    Loop

    I = I + 1

    Do While .Cells(I, 1) = 1
        If I = 34 Then
            MsgBox "ça marche pas!"
            Exit Sub
        Else
            ComboBox1.AddItem (.Cells(I, 2))
            I = I + 1
        End If
    Loop
End With

Ton code, tel que je le conçois, donc, avec quelques petites différences

Les déclarations sont en tête de la macro : Je les mets juste sous la ligne de titre : quelque soit l'endroit, VBA fait un premier passage pour les déclarer si elles ne le sont pas.

Mes variables commencent toujours par une majuscule : je tape tout en minuscule. À la validation de la ligne de code, comme la variable est déclarée, si VBA ne me met pas la majuscule, c'est que j'ai une erreur. Pas besoin d'attendre le début de l'exécution pour qu'Excel m'avertisse (je m'oblige à déclarer mes variables - Option Explicit)

With Sheets("Feuil1") : mettre Sheets("Feuil1") en préfixe. Si VBA rencontre un terme commençant par un caractère de liaison, il met le préfixe devant. ainsi ComboBox1.AddItem (.Cells(I, 2)) se lit :

ComboBox1.AddItem (Sheets("Feuil1").Cells(I, 2))

Do Until .Cells(I, "A") = 1 : continuer la boucle jusqu'à ce que la valeur (propriété par défaut) de la cellule A ligne I soit égale à 1

J'évite autant que possible les 1 quand j'utilise des I : une erreur est si vite arrivée, et tard dans le dépannage, ils ont tendance à se confondre (pour moi )

Ce n'est pas la formule de A qui t'intéresse, mais son contenu. même si dans ce cas c'est la même chose.

Exit Do : sortir de la boucle Do. Dans ce code, on a pas trouvé de 1 dans les cellules 19, 20, 21, pourquoi continuer la macro ? Je sais, ta deuxième boucle nous fait la même chose, et le résultat est le même. Mais il faut rester logique quand on fait un code : imagine que derrière tu ais un traitement qui doit te couper des données importantes et les mettre ailleurs => si tu ne fais que sortir de ta boucle, tu peux avoir des pertes d'information.

N'hésite jamais à me critiquer . Je me permets souvent de critiquer et j'attends la même chose de tout lecteur d'un de mes postes (seulement de manière constructive, dire c'est nul, n'importe quel imbécile peut le faire sur tout code, mais ça n'apporte rien ).

Si dans ce que je tentes d'expliquer je m'y prends de manière incompréhensible, demande.

A+

Bonjour!

Alors là plus de remarques ^^ je voudrais juste être clair..

lorsqu'il trouve un i qui se balade dans le code alors que tu as définis un I, il va le changer tout seul? Comme il fait déjà avec des mots connus comme until, cells, sheet, range etc.? Mais donc pourquoi il ne le ferait pas? Seulement si j'ai justement oublié de le déclarer?

Sinon pour le With Sheet("feuil1") c'est super cool, je conaissais pas =)

mais pour les histoires de long et de integer, si c'est juste une question de place ; autant prendre un integer, quite à faire bugger le système autant que ce soit tout de suite XD perso, dans ce cas la, je n'aurais jamais i>100... mais vaut mieux prendre le réflexe tout de suite

Sinon pour l'histoire de sortie, tu voudrais que je mette ma deuxième boucle dans le 1er If de la 1ère boucle? Mais si c'est la deuxième qui plante? En plus ça nous fera une mega imbrication du style :

With
   Do until
      If
      Else
         Do while
            If
            Ellse
            End if
         Loop
      End if
   Loop 

Vous allez me dire... Pk pas?

Salut Sym et le forum

lorsqu'il trouve un i qui se balade dans le code alors que tu as définis un I, il va le changer tout seul ?

Oui, s'il est déclaré.

- Comme il fait déjà avec des mots connus comme until, cells, sheet, range etc.?

Tout à fait. et comme pour mes variables, si la majuscule n'apparaît pas, tu sais que tu as fait une faute de frappe, tout de suite, sans attendre de lancer la macro por qu'Excel te le révèle.

- Seulement si j'ai justement oublié de le déclarer ?

2 solutions : soit il ne se passe rien, soit tu à coché "Déclaration des variables obligatoires" dans le menu Option (ou tu as en tête du module Option Explicit) et Excel te prévient qu'il ne peut pas exécuter ton code au lancement de la macro, parce qu'il y a une variable non définie.

La déclaration des variables est une petite contrainte, mais ça fait gagner un temps fou en dépannage.

- mais pour les histoires de long et de integer, si c'est juste une question de place ; autant prendre un integer

Comme je l'ai dit : un code est personnel. Quand à la question de la place, il faut se remettre dans le contexte : on avait un maximum de 640 ko. 1 octet (Byte) ou 4 (Long) pouvait avoir une répercution sur la RAM et sur le traitement. Maintenant, la RAM est de l'ordre du Gigaoctet...

- mais vaut mieux prendre le réflexe tout de suite

C'est la décision que j'ai prise...

- Sinon pour l'histoire de sortie, tu voudrais que je mette ma deuxième boucle dans le 1er If de la 1ère boucle ?

Non ! Je dis simplement que si la bonne réponse à une boucle n'est pas trouvée, pourquoi continuer l'exécution de la macro ?

Dans ta macro, ce n'est pas très important : si I atteint 22, on lui ajoute 1 et on passe à la boucle suivante qui comme A23 ne contient pas de 1, finira la deuxième boucle avant de l'avoir commencée.

Cependant sur un code conséquent, le fait de ne pas trouver une variable essentielle au déroulement correct de l'algorithme, si tu n'arrêtes pas la macro, continue le code de manière erronée.

C'est pour ça que je conseille d'arrêter le code, et de déclarer les variables dans le type pour lequel elles sont prévues. Variant ne devant être réservé que quand la variable doit recevoir plusieurs types.

Moins tu laisses de possibilités à Excel, moins tu risques l'application de la Loi de Murphy !

Mais c'est une conception personnelle, due à l'arrachage de quelques cheveux pour avoir chercher pendant des heures, pourquoi j'avais perdu des données, alors que ça semblait correct pendant les tests.

A+

Rechercher des sujets similaires à "vba listes deroulantes boucles"