Rien à voir avec la haute couture de saison, voici pour conclure un concept fort utile dès que l'on est amené à gérer à la queue leu leu des hordes sauvages de contrôles.
Dans cet esprit, on disposait déjà d'un outil simple, mais très performant : les groupes
, qui comme le disait le sage, à savoir moi-même, sont aux contrôles ce que les tableaux sont aux variables. Eh bien, on pourrait dire, pour filer la métaphore, que les collections sont aux contrôles ce que les variables structurées sont aux variables : un assemblage d'éléments au besoin hétéroclite, permettant un traitement global là où il fallait auparavant prendre les éléments un par un.
Première bonne nouvelle : tous les contrôles posés sur une feuille appartiennent de droit à la collection de la feuille. Au sein de cette collection, exactement comme dans un groupe, chaque élément est désigné par un numéro d'indice (correspondant ici à l'ordre de création de l'élément dans la feuille).
Pour accéder aux éléments de la collection, on pourra employer la propriété Controls de la Form, par exemple de la manière suivante :
Form1.Controls(5).Visible = False
...qui masquera le sixième contrôle créé sur Form1.
A noter que la propriété Controls n'est pas accessible depuis la fenêtre des propriétés du mode conception, mais uniquement par le code.
Evidemment, prendre les contrôles un par un par leur numéro d'indice, c'est bien, mais le problème se pose vite de savoir à quel numéro s'arrêter (sinon, vlan, c'est le dépassement d'indice direct garanti sur facture). Pour cela, deux solutions :
La propriété Count de la collection Controls, qui dénombre le nombre de contrôles qu'elle contient. Pour rendre visibles tous les contrôles d'une feuille, nous pourrons donc écrire :
For i = 0 to Form1.Controls.Count - 1
Form1.Controls(i).Visible = True
Next i
Mais il y a une autre ruse, bien plus redoutable...
C'est qu'en VB, on dispose d'une instruction de boucle spéciale pour les collections de contrôles. Il s'agit de l'instruction
For Each Truc in Machin
où "Machin" est la collection de contrôles (donc Form1.Controls, par exemple), et "Truc" est une variable qui prendra successivement la valeur de chaque contrôle de la collection. Une telle variable, qui ne contient pas une valeur mais un objet, est appelée... une variable objet. Etonnant, non ? Ce qui nous permettra d'écrire une boucle aussi simple que :
For Each Bidule in Form1.Controls
Bidule.Visible = True
Next Bidule
Quelle que soit la méthode utilisée, parcourir automatiquement toute une série, c'est bien, mais pouvoir déterminer à quel type de contrôle on a affaire, ce serait nettement mieux. Car pour certains traitements, on a besoin de savoir si le contrôle est un bouton, une zone de texte ou tout autre chose avant de pouvoir lui infliger quoi que ce soit.
Eh bien, une fois de plus, VB a tout prévu, par l'instruction :
Typeof Bidule Is Nomtype
Où "Bidule" est un contrôle (ou une variable objet), et "Nomtype" un mot-clé désignant un type (une classe) de contrôles : CommandButton, TextBox, ListBox, etc.
Pour conclure, imaginons un fragment de code verrouillant toutes les zones de texte d'une feuille, sans que ces zones de texte aient nécessairement été créées comme un groupe de contrôle :
For Each Machin In Form1.Controls
If Machin Is TextBox Then
Machin.Locked = True
Endif
Next Machin
Et le tour est joué. Puissant, n'est-il pas ?