For each.....Bizarrerie!!!

Résolu
cf91 Messages postés 3 Date d'inscription dimanche 21 janvier 2007 Statut Membre Dernière intervention 27 juin 2007 - 25 juin 2007 à 23:12
cf91 Messages postés 3 Date d'inscription dimanche 21 janvier 2007 Statut Membre Dernière intervention 27 juin 2007 - 27 juin 2007 à 07:05
Salut à tous,
Je fais mes armes en VBA sous Access2000 et il m'arrive un drôle de truc:
Dans un formulaire Formulaire1, qui contient par exemple 64 contrôles texte et ouvert en mode création, je veux effacer tous ces contrôles avec la sub suivante:

Public Sub del_ctrls()

Dim ctrl As Control

For Each ctrl In Forms!Formulaire1.Controls
     DeleteControl Forms!Formulaire1.Name, ctrl.Name
Next ctrl

End Sub

Le résultat est que seul un contrôle sur deux disparait. Il en reste donc 32.
Et ainsi de suite à chaque fois que je lance la sub, jusqu'à 0.
Si quelqu'un a une explication, je l'en remercie par avance.

6 réponses

cs_moustachu Messages postés 1079 Date d'inscription jeudi 14 novembre 2002 Statut Membre Dernière intervention 1 janvier 2012
26 juin 2007 à 08:47
Bonjour,

Peut être que VBA est un peu "perdu" lorsque tu lui dis de parcourrir une collection de controle que tu supprimes au fur et à mesure.

++
Moustachu
3
cs_Exploreur Messages postés 4822 Date d'inscription lundi 11 novembre 2002 Statut Membre Dernière intervention 15 novembre 2016 14
26 juin 2007 à 08:47
Salut,

C'est un problème d'index....Si tu connais le nombre de contrôles indéxés, je pense que le code devrait ressemblé à cela :

Public Sub del_ctrls()

Dim ctrl As Control

For Each ctrl In Forms!Formulaire1.Controls
     DeleteControl Forms!Formulaire1.Name, ctrl(INDEX).Name
Next ctrl

End Sub

A+
Exploreur

 Linux a un noyau, Windows un pépin

 
3
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
26 juin 2007 à 09:36
L'explication est logique en tous cas, c'est bien un pb d'index.

Ta boucle défile en fait tous les contrôles un par un, du 1 au 64.
Sauf que quand tu supprimes un contrôle, tous les index sont diminués de 1, et à la fin de la boucle, tu as plus 1. Pas très clair dit comme ça, un exemple.

Boucle = 1
Control 1
Suppression du control 1
Le control 2 devient le contro l, le 3 devient le 2, etc ...
Boucle = 2
Suppression du Control 2
Control 3 devient control 2, etc ...
Boucle = 3

Ta boucle ne supprime donc qu'un control sur deux.

Pour résoudre le pb, il faudrait une fois que tu supprimes un control, pouvoir faire -1 à ta boucle, comme ça, elle reprendrait au bon index la suppression, mais avec une boucle For Each, je crois que c'est impossible.

L'idée, ça serait peut être alors de créer une boucle du style Do while : Tant qu'il y a un control sur la feuille, supprimer le control ayant l'index 1
De mémoire, la collection Controls contient tous les controls d'une feuille, et doit posséder une propriété Count.
A partir de là, ça doit pouvoir se faire.

Je n'ai pas le temps de tester, mais l'idée est là normalement (si j'ai réussi à l'exposer clairement ^^)

Molenn
3
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 22
26 juin 2007 à 11:48
C'est un problème qui arrive souvent lorsqu'on efface des choses, comme des lignes dans une feuille Excel, des items dans une Listbox, ...
Dans ces cas-là, il est préférable de commencer par la fin, ce qui donnerait quelque chose comme
For I = Forms!Formulaire1.Controls.Count To 1 Step - 1
    'vérification du type de contrôle si nécessaire
       'effacer le contrôle
       DeleteControl Forms!Formulaire1.Controls(I)
.....

Je n'ai pas testé mais ça devrait ressembler à ça...

MPi
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cf91 Messages postés 3 Date d'inscription dimanche 21 janvier 2007 Statut Membre Dernière intervention 27 juin 2007
26 juin 2007 à 14:07
Grand merci à vous quatre pour la rapidité et la précision de vos réponses. C'est très clair. Je m'y remets dès que possible. J'étais vraiment coincé.
A+ et respect à ceux qui savent et qui partagent.
3
cf91 Messages postés 3 Date d'inscription dimanche 21 janvier 2007 Statut Membre Dernière intervention 27 juin 2007
27 juin 2007 à 07:05
Si ça peut servir à quelqu'un, la boucle ci-dessous marche, je l'ai testée:

For i = Forms!Formulaire1.Controls.Count - 1 To 0 Step -1
  
'vérification du type de contrôle si nécessaire
 'effacer le contrôle
   
    DeleteControl Forms!Formulaire1.Name, Forms!Formulaire1.Controls(i).Name

Next

Encore merci.
3
Rejoignez-nous