2 votes

Comment fonctionnent SelectContentControlsByTitle et .item() ?

[L'anglais n'est pas ma première langue]

Je suis en train de développer un document Word dans lequel l'utilisateur saisit des informations dans des champs de texte riche de contrôle de contenu. Ces entrées sont ensuite affichées sous forme de choix dans plusieurs listes déroulantes (boîtes combo) situées plus bas.

Il se présente comme suit :


Emplacements :
[Insérer le lieu 1 ici]
[Insérer l'emplacement 2 ici]
[Insérer l'emplacement 3 ici]
[Insérer l'emplacement 4 ici]
[Insérer l'emplacement 5 ici]

(Le titre CC de chacun d'eux est "LocationMenu")
(La balise CC de chacun d'entre eux doit être "Header")


L'utilisateur peut utiliser un ou plusieurs emplacements.

J'écris une boucle qui vérifie combien de contrôles de contenu ont été remplis, puis utilise les contrôles remplis comme entrées de liste pour la liste déroulante. J'avais prévu d'utiliser le même TITRE pour chaque contrôle de contenu dans mon menu initial, et d'effectuer une boucle dans le fichier .SelectContentControlsByTitle("LocationMenu").Item(x).

Cependant...

Pourquoi est-ce que quand j'essaie ça :

MsgBox (ActiveDocument.SelectContentControlsByTitle("LocationMenu").Item(2).Range.Text)

Je reçois [Insert location 3 here] et pas [Insert location 2 here] ?

Quand j'essaie :

MsgBox (ActiveDocument.SelectContentControlsByTitle("LocationMenu").Item(1).Range.Text)

Je reçois [Insert location 2 here] et pas [Insert location 1 here] ?

(Ce n'est pas non plus un problème d'array-starts-at-0).

Quelqu'un pourrait-il me donner plus de détails sur la façon d'utiliser la partie "item()" du code ? Les gens semblent contourner le problème en mettant un titre unique pour chaque contrôle de contenu et en laissant le .item(x) à .item(1)... mais cela ne fonctionne pas pour ce que j'essaie de faire... Comment utiliser .item(x) ???

merci beaucoup

Voici les pages que j'ai consultées, mais je n'ai pas trouvé de réponse :

http://www.vbaexpress.com/forum/archive/index.php/t-50894.html

http://gregmaxey.com/word_tip_pages/interactive_userforms.html

Le truc de msdn.microsoft.com n'a pas aidé. Je n'ai pas non plus trouvé la réponse sur Stack Overflow...

3voto

retailcoder Points 3056

À propos de la propriété Item et des types de collections itératives

Par convention, Item est une spéciale Property Get membre défini dans les types d'objets de collection qui [peuvent/doivent] contenir des références à des objets.

Si vous pouviez voir la définition de cette propriété getter, vous verriez quelque chose comme ceci :

Public Property Get Item(ByVal index As Variant) As Variant
Attribute Item.VB_Description = "Gets or sets the element at the specified index."
Attribute Item.VB_UserMemId = 0
    'implementation
End Property

Ce Attribute Item.VB_UserMemId = 0 L'attribut caché définit la valeur de l'élément de type COM DispId à 0, ce qui en fait la propriété de la classe membre par défaut .

En d'autres termes, ceci :

Debug.Print myCollection.Item(1).Range.Text

C'est exactement la même chose que ça :

Debug.Print myCollection(1).Range.Text

Les spécificités exactes de la façon dont un Item fonctionne avec un index donné, est spécifique à l'implémentation, c'est-à-dire qu'elle dépend de la manière dont la classe de collection est implémentée.

Mais une chose que toutes les classes de collection ont en commun, c'est un élément caché. [_NewEnum] avec un VB_UserMemId = -4 caché, ce qui indique à VB6/VBA d'utiliser cette méthode pour obtenir une énumérateur pour faire itérer cette collection.

C'est ainsi que les collections peuvent être itérées à l'aide d'une fonction For Each boucle.

Et c'est TRÈS efficace. Par exemple, ~27 fois plus rapide que l'itération d'une collection par index avec une fonction For boucle.

Utilisez-le !

Dim ctrl As ContentControl
For Each ctrl In ActiveDocument.SelectContentControlsByTitle("LocationMenu")
    Debug.Print ctrl.Range.Text
Next

Votre problème (et sa solution)

Maintenant, le problème est que vous pensez à tu itères les éléments de la liste déroulante, mais tu itères vraiment ContentControl articles, et ce que .Range.Text renvoie la valeur actuelle de chacun de ces contrôles (c'est-à-dire que la valeur de l'option ActiveDocument contient plus qu'un seul contrôle de contenu de type liste déroulante intitulé "LocationMenu").

Si vous souhaitez itérer les valeurs de la liste déroulante, vous devez consulter la fonction ContentControl.DropdownListEntries collection :

Dim ctrl As ContentControl
For Each ctrl In ActiveDocument.SelectContentControlsByTitle("LocationMenu")
    Dim ddItem As ContentControlListEntry
    For Each ddItem In ctrl.DropdownListEntries
        Debug.Print ddItem.Text, ddItem.Value
    Next
Next

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X