Création d'un objet ListBox modifiable et dynamique

pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 30 juin 2015 à 16:47
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 28 août 2015 à 20:33
Bonjour,

Pour ce projet j'ai besoin d'un gros coup de main.
Il consiste à créer, via une classe, un objet listbox modifiable. Pour cela, l'objet mListBox va être composé de trois contrôles :
1 ListBox, 1 Frame et 1 TextBox.
Voilà ou j'en suis :
1- code de l'userform :
Option Explicit

Private Sub UserForm_Initialize()
Dim i As Integer, monTop As Single, monLeft As Single

   Me.Height = 450
   Me.Width = 420
   Set monUsf = Me   'ligne indispensable
   For i = 0 To 3
      monTop = IIf(i < 2, 5, 205)
      monLeft = IIf(i And 1, 205, 5)
      maList(i).Affiche i, monLeft, monTop, 200, 200   'ligne indispensable
   Next
End Sub


2- Code du module (Module1)
Option Explicit

Public monUsf As Object
Public maList(3) As New mListBox


3- Code du Module de Classe (mListBox)

Option Explicit

Public WithEvents mTextB As MSForms.TextBox  'événements des textbox
Public WithEvents mListB As MSForms.ListBox  'événements des listbox

Private mLeft As Single, mTop As Single

Private Sub Class_Initialize()
'Un objet "mListBox" est composé de trois contrôles :
   '- 1 listbox appelée "mListBox_" & Num
   '- 1 Frame appelé "mFrame_" & Num
   '- 1 textbox appelé "mTextBox_" & Num
End Sub

Sub Affiche(ByVal Num As Integer, ByVal L As Single, ByVal T As Single, ByVal W As Single, ByVal H As Single)
'dessine les 3 contrôles composant l'objet mListBox dans l'userform (monUsf)
'et affecte les propriétés événementielles (mListB et mTextB)
Dim ListB As Object, TextB As Object, Frme As Object

   'ajout du contrôle ListBox
   Set ListB = monUsf.Controls.Add("forms.ListBox.1")
   Set maList(Num).mListB = ListB
   With ListB
      .Move L, T, W, H
      .Name = "mListBox_" & Num
   End With
   'Ajout du contrôle Frame
   Set Frme = monUsf.Controls.Add("forms.Frame.1")
   With Frme
      .Visible = False
      .Name = "mFrame_" & Num
      .Move L, T + H, 50, 20
      .BorderStyle = 0
   End With
   'ajout du contrôle TextBox
   Set TextB = Frme.Controls.Add("forms.TextBox.1")
   Set maList(Num).mTextB = TextB
   With TextB
      .Name = "mTextBox_" & Num
      .Move 0, 0, 46, 16
   End With
   'libération des variables
   Set ListB = Nothing
   Set Frme = Nothing
   Set TextB = Nothing
End Sub

Private Sub mListB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
'événement MouseDown du contrôle listbox
   '=> Si Frame.Visible Alors on passe la valeur du textbox dans la listbox
      'puis (dans tous les cas) on affiche le Frame
Dim Num As Integer

   'si clic gauche
   If Button = 1 Then
      'on récupère le numéro de la mListBox
      Num = CInt(Split(mListB.Name, "_")(1))
      'interception de la sortie du textbox par la souris
      If monUsf.Controls("mFrame_" & Num).Visible = True Then
         'on enregistre la saisie du textbox dans la listbox
         Call Corrige_Liste(monUsf.Controls("mTextBox_" & Num).Value, X, Y)
      End If
      'stockage des X et Y pour préparer la restitution des données lors de la sortie du textbox
      mLeft = X
      mTop = Y
      'on affiche le Frame au bon endroit
      Affiche_Frame Num, True, X, Y
   End If
End Sub

Private Sub Affiche_Frame(ByVal Num As Integer, ByVal Visib As Boolean, ByVal X As Single, ByVal Y As Single)
'changement de la propriété Visible du Frame (=> Affichage vrai ou faux au bon endroit)
   With monUsf.Controls("mFrame_" & Num)
      .Visible = Visib 'rend visible ou invisible le Frame
      'positionne le Frame en fonction du numéro
      .Move monUsf.Controls(mListB.Name).Left + X, monUsf.Controls(mListB.Name).Top + Y, .Width, .Height
      'Positionne le Frame par dessus la ListBox
      .ZOrder msoBringToFront
       'si visible attribue le focus au textbox
      If Visib Then .Controls("mTextBox_" & Num).SetFocus
   End With
End Sub

Private Sub mTextB_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
'interception de la sortie du textbox par le clavier
Dim Num As Integer
   'quel textbox?
   Num = CInt(Split(mTextB.Name, "_")(1))
   'Qu'elle touche?
   Select Case Asc(UCase(Chr(KeyCode)))
      Case 9, 13 'touche TAB, Entrée
         Corrige_Liste mTextB.Value, mLeft, mTop 'Saisie de la valeur du textbox dans la listbox
         Affiche_Frame Num, False, 0, 0 'masque le Frame
      Case Else 'Autres
   End Select
End Sub

Private Sub Corrige_Liste(ByVal maVal As String, ByVal X As Single, ByVal Y As Single)
'passe mTextB.Value dans mListB

End Sub

Private Sub Class_Terminate()

End Sub


Pour l'instant, plutôt que de vous poser les 1000 questions qui me brulent les doigts, je préfères vous demander simplement si le début vous semble correct.

En second lieu, j'aimerais voir quelques points avec vous et, notamment, qu'elles sont les propriétés indispensables à ajouter, et des petits détails qui viendront en cours de développement...

Merci de votre première lecture.

26 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
30 juin 2015 à 17:59
Bonjour, Franck
Qu'entends-tu exactement par "modifiable" ?
Si, comme je le pense, tu veux superposer la textbox de "modif" à l'article concerné de la listbox, puis affecter à la cellule concernée de la listbox la valeur de la textbox, je crains fort que tu n'aies à te diriger sans attendre vers des calculs assez complexes de hauteurs de textes accompagnés d'autres calculs si listbox de plusieurs colonnes.
VBA n'offre pas à ce propos ce qu'offre VB6 (pour les hauteurs de texte). Tu trouveras toutefois parmi mes sources de quoi te permettre de déterminer cela sous VBA.
Il ne va certes pas s'agir d'une tâche simple. Très loin de là !
Question : pourquoi ne pas plutôt travailler avec des MSFLEXGRID, qui présentent l'énorme avantage de permettre de déterminer (par MouseRow et MouseCol) la cellule sur laquelle on place la souris ?
Ce serait très nettement plus sage.
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 14
Modifié par pijaku le 1/07/2015 à 07:42
Bonjour Jacques,

Qu'entends-tu exactement par "modifiable" ?
Si, comme je le pense, tu veux superposer la textbox de "modif" à l'article concerné de la listbox, puis affecter à la cellule concernée de la listbox la valeur de la textbox, je crains fort que tu n'aies à te diriger sans attendre vers des calculs assez complexes de hauteurs de textes accompagnés d'autres calculs si listbox de plusieurs colonnes.

C'est exactement cela.

VBA n'offre pas à ce propos ce qu'offre VB6 (pour les hauteurs de texte). Tu trouveras toutefois parmi mes sources de quoi te permettre de déterminer cela sous VBA.

Oui, je connais cette source pour l'avoir déjà lue. J'aurais certainement besoin d'un coup de main pour adapter.

Il ne va certes pas s'agir d'une tâche simple. Très loin de là !

Je sais. D'où mon sujet ici même. C'est une tâche très complexe, mais qui vaut certainement le coup. De ce fait, j'ai voulu créer ce sujet pour en faire un "travail" collectif car je ne me sens pas d'y aller tout seul.

Question : pourquoi ne pas plutôt travailler avec des MSFLEXGRID, qui présentent l'énorme avantage de permettre de déterminer (par MouseRow et MouseCol) la cellule sur laquelle on place la souris ?
Ce serait très nettement plus sage.

C'est aussi pour cela que je pose cette question. Je ne connais pas MSFLEXGRID et vais de ce pas me rencarder.

Je reviendrais après te dire ce qu'il en est.
0
Rejoignez-nous