For each.....Bizarrerie!!!

Résolu
Signaler
Messages postés
3
Date d'inscription
dimanche 21 janvier 2007
Statut
Membre
Dernière intervention
27 juin 2007
-
Messages postés
3
Date d'inscription
dimanche 21 janvier 2007
Statut
Membre
Dernière intervention
27 juin 2007
-
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

Messages postés
1079
Date d'inscription
jeudi 14 novembre 2002
Statut
Membre
Dernière intervention
1 janvier 2012

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
Messages postés
4822
Date d'inscription
lundi 11 novembre 2002
Statut
Membre
Dernière intervention
15 novembre 2016
14
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

 
Messages postés
797
Date d'inscription
mardi 7 juin 2005
Statut
Membre
Dernière intervention
23 février 2011
7
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
Messages postés
3877
Date d'inscription
mardi 19 mars 2002
Statut
Membre
Dernière intervention
23 août 2018
19
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
Messages postés
3
Date d'inscription
dimanche 21 janvier 2007
Statut
Membre
Dernière intervention
27 juin 2007

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.
Messages postés
3
Date d'inscription
dimanche 21 janvier 2007
Statut
Membre
Dernière intervention
27 juin 2007

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.