Passer des collections d'une forme d'user à une autre Formulaire d'user

J'ai passé plusieurs jours à essayer de déterminer s'il faut utiliser des arrays ou des collections pour transmettre de multiples variables d'une forme d'user à une autre. Après quelques jours d'expérience avec des arrays, j'ai trouvé que les collections seraient peut-être plus faciles à utiliser. Cependant, je continue à avoir des erreurs. Par exemple, je reçois une erreur Variable not defined lorsque j'utilise le code suivant:

  Public totalCats As New Collection ' then in a private sub totalCats.Add(txtTotalCats.Text) ' and in a totally different userform, because that's my main goal with this: Private Sub UserForm_Activate() For i = 1 To totalCats.Item(1) Next End Sub 

Est-ce que je fais quelque chose de mal à get cette erreur? En outre, je reçois un type de 91 d'erreur User-defined type not defined lorsque je ne reçois pas cette erreur de compilation antérieure.

Quelqu'un peut-il m'aider? J'ai vraiment besoin d'get cela là où je peux mettre les choses dans une collection et être en mesure de l'appeler à partir de n'importe quel formulaire d'user dans le programme. Si vous avez besoin de code plus pertinent, je serai ravi de l'afficher.

Edit : réparé partiellement par Tim Williams commentaire, maintenant il y a une erreur d'exécution en lisant: Invalid procedure call or argument

La ligne de code à laquelle il indique est:

With objLbl .Caption = Chr(10) & frmCatNames.catNames.Item(i) & " section " & i End With

Bien sûr, il y a d'autres choses dans le With, mais je pense que la façon dont j'ai appelé la collection catNames est le problème.

Le problème est originaire d'ailleurs dans le code que vous n'avez pas inclus dans votre question, mais il y a des problèmes de ménage généraux que je peux voir et certains peuvent être.

Déclaration d'objects avec une instanciation automatique

C'est quand vous incluez une déclaration As New dans la déclaration. Total public en tant que nouvelle collection. En général, c'est une mauvaise idée car toute reference à l'object, y compris un contrôle pour tester s'il n'y a rien, entraînera l'initialisation de l'object. Donc, vous ne pouvez pas tester pour voir si c'est défini avant de tenter de faire quelque chose avec lui. L'instanciation explicite de la Collection résout ce problème

 Public totalCats As Collection 'Just before you load the Collection... Set totalCats = New Collection For Each nextMember in mObject.Members With totalCats .Add nextMember, nextMember.Name End With Next nextMember 

Ensuite, vous pouvez faire une bonne erreur de ménage, par exemple

 If Not frmCatNames.catNames Is Nothing Then With objLbl .Caption = Chr(10) & frmCatNames.catNames.Item(i) & " section " & i End With Else 'Handle error... End If 

Cycle de vie de la collection dans un object userForm

Une collection déclarée à l'intérieur d'une class userForm est définie à Rien du time que le module soit réembedded. Par exemple, si un nouveau contrôle est ajouté au moment de l'exécution. Si vous vérifiez Tools \ Options \ General Notify avant la perte d'état, VBE vous en informera.

Cycle de vie des objects UserForm

Je ne suis pas sûr de ce que frmCatNames est parce que ce code est manquant, mais il devrait s'agir d'une instance d'une class de formulaire que vous avez créée en ajoutant un module de formulaire dans VBE. Vous pouvez également créer automatiquement une class de formulaire. Par exemple, si vous avez un module de formulaire appelé UserForm1, vous pouvez en appeler une instance avec

 UserForm1.Show 

Mais il vaut mieux l'incliner explicitement comme ça

 Dim f As UserForm1 Set f = New UserForm1 f.Show 

L'object f se comportera alors de la manière dont vous vous attendez à ce que frmCatNames se comporte. Je ne peux pas dire de votre question quel est cet object, mais il doit s'agir d'un object qui est tapé dans votre module de class de formulaire et créé comme cela.

Il y a un peu plus de détails dans la deuxième réponse ici …