Ajout dynamique d'un controle dans un frame

G

Gigi

Guest
Joyeux Noël et bonsoir au forum!

Je suis en train de devenir fou!
Je cherche à ajouter dynamiquement un contrôle (un label, pour être précis) A L'INTERIEUR D'UN FRAME. Et je n'y parviens pas... :-((

Je passe par la méthode ADD de la manière suivante:

Dim MonControle as Control

Set MonControle = Controls.Add ("Forms.Label.1" , "NouveauLbl" , True)

...et mon label vient se créer dans le Userform et non dans le Frame (y compris bien sûr si ce dernier occupe la totalité du Userform, ou si je force NouveauLbl.left et .top après la création, à des valeurs qui le placent en plein milieu du frame. Il reste définitivement derrière...).

En bref, AU SECOURS!

Merci d'avance et longue vie au forum!

P.S.: Amitiés à Lolo (Gi²)
 
T

tatiak

Guest
Bonjour,
Avant de devenir complètement fou, est-ce qu'on peut dans le cas de ton application positionner le label à la création du Usf et le rendre non visible dans un premier temps (dans private sub userform_activate, par exemple) : label1.visible = false, puis le rendre visible quand on le souhaite : label1.visible = true
On peut même changer d'intitulé par : label1.caption ="Tructrucmachin"
 
G

Gigi

Guest
Hello Tatiak!

Merci pour ta réponse.

En fait, je devrais préciser l'usage que j'ai de cet ajout dynamique.

Je me sers de ce frame et de ces proriétés de scroll pour créer une liste d'affichage de ces labels dont le nombre varie en fonction de certains choix de l'utilisateur. Ce nombre peut à terme devenir très important et m'empêche donc de faire ce que tu me proposes, et qui était d'ailleurs l'option que j'avais initialement retenue (comme quoi, les grands esprits... ;-) ). Quand j'ai essayé de "prépositionner" quelques centaines de labels en vue de les activer si besoin, je me suis retrouvé confronté à un problème de mémoire lors de la compilation...
C'est ce qui me laisse penser que le meilleur moyen consiste non pas à les activer mais à les créer au moment voulu.

Si tu as une autre idée , n'hésite pas!

Amicalement,

Gi².
 
M

myDearFriend!

Guest
Bonjour Gigi, Tatiak, le Forum.

Pour ton problème Gigi, je pense que le code suivant devrait fonctionner :

Dim AutreLabel As MSForms.Label
Dim L As Byte
   For L = 1 To 10
      Set AutreLabel = Me.Controls("Frame1").Add("forms.label.1")
      With AutreLabel
         .Caption = "MonLabel" & L
         .Top = 10 * L
         .Left = 10
      End With
   Next L

Cela dit, je ne comprends pas pourquoi tu ne te contenterais pas d'une simple ListBox, tout à fait adaptée à ce que je viens de lire et plus facile à mettre en oeuvre il me semble...

Cordialement.

Didier_mDF
myDearFriend-3.gif
 
G

Gigi

Guest
Hello myDearFriend, bonjour au forum!

C'est le bon Dieu (ou le Père-Noël! lol) qui t'envoie, et tu portes bien ton pseudo, myDearFriend!!!

Je consulte ta réponse avec un peu de retard et d'un endroit d'où je ne peux essayer ta solution dans l'immédiat, mais elle "sounds good", comme on dit!
Même s'il ne faut pas dire du mal de soi car les autres s'en chargent (!), je suis un âne de n'avoir pas pensé à cette syntaxe!...

Je profite de cette réponse pour t'expliquer l'utilisation de ces fichus labels. Cela me permet effectivement de recréer artificiellement l'équivalent d'une listbox, à ceci près que je peux gérer les couleurs (fore et back) de mes lignes et colonnes, ce que Microsoft semble obstinément refuser de faire faire à ses listbox... A moins que là encore, je sois passé à côté de quelque chose, ce qui ne me surprendrait pas...

Encore mille Merci, j'essaie et je te tiens au courant.

Amicalement,

Gi².

P.S.: LONGUE VIE A CE SUPER FORUM ET AUX GENIES QUI VIENNENT AU SECOURS DE CEUX QUI NE SAVENT PAS!!!
 
G

Gigi

Guest
Bonsoir le forum, bonsoir myDearFriend.

MyDearFriend, ta recette fonctionne à merveille! Cool!
Je continue donc à te mettre à contribution!
Connaitrais-tu un moyen, lors de la création de mes labels, d'ajouter dynamiquement du code permettant de gérer leurs événements _Click et _DblClick. Quelque chose du genre:

ThisWorkbook.VBProject.VBComponents("Userform1").CodeModule.InsertLines. /adresse de la ligne/, "Private Sub Label1_Click()" ...etc,

Le problème que je rencontre (et qui me paraît difficilement contournable, comme ts les pb que je rencontre d'ailleurs! :)), c'est qu' Excel sort automatiquement du mode Run lorsqu'on rajoute du code pour le recompiler... Tu penses qu'on peut y arriver?

J'ai essayé de tricher en préparant les procédures correspondantes à l'avance pour une dizaine de labels, mais l'événement n'est pas géré comme il le devrait... Rien ne se passe par exemple lors d'un click, même si la procédure correspondante est effectivement écrite, et a priori, compilée (peut-être ne la compile-t-il pas vraiment en tant que procédure événementielle s'il ne connaît pas encore l'existence du contrôle associé...).

Merci encore pour ta "soluce", et merci d'avance pour ta réponse.

Amicalement,

Gi².
 
M

myDearFriend

Guest
Bonsoir Gigi,

J'essayais de te mettre en garde dans mon dernier message : ce que tu essaies de réaliser là, me paraît plus qu'aléatoire... La création de contrôles et code associé de façon dynamique est quelque chose de très délicat à mettre en oeuvre (pour moi en tout cas !). Par ailleurs, tu tentes de créer des contrôles dynamiques sur des contrôles déjà existant, ce qui va fragiliser davantage ton projet il me semble... Sauf erreur de ma part, ce que tu vas créer de façon dynamique (je pense aux lignes de code notamment), tu vas devoir le détruire ensuite pour ne pas provoquer un plantage par surcharge de code au prochain lancement...

Pour reprendre l'exemple précédent, j'imagine qu'il conviendrait d'écrire quelque chose comme ça dans un module de code :

'Variable de niveau module permettant de mémoriser la ligne à partir de laquelle le code est ajouté
Dim DebutAjoutLignes As Integer

'Pour la constrution des labels et le code associé
Sub Construction()
Dim AutreLabel As MSForms.Label
Dim L As Byte
Dim Lign As Integer
   For L = 1 To 10
      Set AutreLabel = UserForm1.Controls("Frame1").Add("forms.label.1")
      With AutreLabel
         .Caption = "MonLabel" & L
         .Top = 10 * L
         .Left = 10
      End With
      With ThisWorkbook.VBProject.VBComponents("UserForm1").CodeModule
         Lign = .CountOfLines
         If L = 1 Then DebutAjoutLignes = Lign
         .InsertLines Lign + 1, "Private Sub Label" & L & "_Click()"
         .InsertLines Lign + 2, " MsgBox ""Clic sur "" & Label" & L & ".Caption"
         .InsertLines Lign + 3, "End Sub"
         .InsertLines Lign + 4, "Private Sub Label" & L & "_DblClick(ByVal Cancel As MSForms.ReturnBoolean)"
         .InsertLines Lign + 5, " MsgBox ""Double-clic sur "" & Label" & L & ".Caption"
         .InsertLines Lign + 6, "End Sub"
      End With
   Next L
End Sub

'Pour détruire le code créé dynamiquement après traitement
Sub DestructionLignesCode()
Dim L As Integer
   With ThisWorkbook.VBProject.VBComponents("UserForm1").CodeModule
      For L = .CountOfLines To DebutAjoutLignes + 1 Step -1
         .DeleteLines L
      Next L
   End With
End Sub

Voilà, j'espère que tu pourras tenter ta chance sur la base de ces quelques lignes, je ne pense malheureusement pas pouvoir t'aider davantage sur le sujet et je me permets de te le répèter : cette façon de faire ne me semble pas viable...

Bon courage toutefois.

Cordialement.

Didier_mDF
myDearFriend-3.gif
 

Discussions similaires

Statistiques des forums

Discussions
314 653
Messages
2 111 589
Membres
111 208
dernier inscrit
estalavista