Rattacher un contrôle créé dynamiquement à un module de classe

Bonjour,

Je connais peu les modules de classe, mais apparemment ce serait la solution à mon problème.

Voila, je crée sur un userform des labels et une checkbox dynamiques. Je voudrais que lorsque je clique sur la case à cocher, le calcul (voir copie écran) écart soit actualisé du montant de l'opération.

Je ne sais pas comment créer mon contrôle dynamique pour le rattacher au module de classe.

Est-il possible sinon d'ajouter un appel à la fonction de calcul dans le with :

Mon code: pour créer la case à cocher:

Set CheckPointage = Usf_ComptesPointer.Controls.Add("Forms.CheckBox.1", "ChxPointe" & Compteur, True)
With CheckPointage
.Top = topctl
.Left = 920
End With
Merci d'avance

image1

Bonsoir jvoitu

Pourquoi faire simple quand on veut faire compliqué

Avec une ListView, vous avez tout ce qu'il faut et c'est simple à gérer

A+

Bonjour,

Merci je vais regarder car je ne connais pas listwiew non plus.

En fait, je suis retraité et je me suis lancé dans ce projet sans trop de connaissances informatiques. Cà m'occupe et me maintient l'esprit.

Bonjour le retraité

Très bonne idée ça, de ce maintenir l'esprit

A+

Bonjour,

Merci pour la suggestion de la listwiew. Ce n'est pas intuitif mais j'y suis arrivé et çà fonctionne. Me reste à travailler la mise en forme et les formules de calcul.

Je mets mon code sous l'image. Depuis 2006, il y a peut-être d'autres solutions, notamment pour placer la case à cocher ailleurs que dans la première colonne et vous aurez peut-être des suggestions pour améliorer ce que j'ai fait

le résultat:

test listwiew

le code que j'ai utilisé

Private Sub UserForm_Initialize()

' pour afficher les chexcbox à gauche dans la première colonne
Me.ListView1.CheckBoxes = True

' Selection de la zone de recherches
Application.Goto reference:="Tbl_Comptejoint[Pointée]" ' référence de la plage ou je vérifie si l'opération est pointée ou non

' Création de la liste
i = 1

With ListView1

' les en tête
With .ColumnHeaders
.Clear
.Add , , "Pointée", 40 ' 40 est la largeur de colonne
.Add , , "Date", 100
.Add , , "Tiers", 110
.Add , , "Catégorie", 100
End With

' création des lignes et colonnes, pour chaque opération non pointée (la cellule de référence est vide), j'ajoute une ligne dans la liste
For Each Cell In Selection
If Cell = "" Then

' remplissage première colonne
With .ListItems
.Add , , "" ' je ne mets rien pour garder la checkbox seule dans sa colonne
End With
'remplissage de chaque ligne
.ListItems(i).ListSubItems.Add , , Cell.Offset(0, -6)
.ListItems(i).ListSubItems.Add , , Cell.Offset(0, -4)
.ListItems(i).ListSubItems.Add , , Cell.Offset(0, -3)
End If
i = i + 1
Next Cell
End With

' par défaut les checkbox sont d'sactivées

For i = 1 To ListView1.ListItems.Count
ListView1.ListItems(i).Checked = False
Next i

' pour afficher la liste détaillée
ListView1.View = lvwReport

End Sub

' au click dans la case à cocher

Private Sub ListView1_ItemCheck(ByVal Item As MSComctlLib.ListItem)
If Item.Checked = True Then MsgBox "pointée"
End Sub

Salut,

La case à cochée est non déplaçable, elle ne peut être qu'au début

Pour ce qui est du code, évite d'utiliser de la macro Excel4 (Microsoft n'en veut plus) et les Select

Private Sub UserForm_Initialize()
  Dim RngSearch As Range
  Dim Ind As Long
  ' pour afficher les chexcbox à gauche dans la première colonne
  Me.ListView1.CheckBoxes = True
  ' Définri la plage à utiliser
  Set RngSearch = Range("Tbl_Comptejoint[Pointée]")
  ' Paramétrer la ListView
  With Me.ListView1
    ' les en tête
    With .ColumnHeaders
        .Clear
        .Add , , "Pointée", 40                ' 40 est la largeur de colonne
        .Add , , "Date", 100
        .Add , , "Tiers", 110
        .Add , , "Catégorie", 100
    End With
    ' création des lignes et colonnes, pour chaque opération non pointée (la cellule de référence est vide), j'ajoute une ligne dans la liste
    For Each Cell In RngSearch
      If Cell = "" Then
        ' remplissage première colonne
        .ListItems.Add , , ""                   ' je ne mets rien pour garder la checkbox seule dans sa colonne
        'remplissage de chaque ligne
        Ind = Me.ListView1.ListItems.Count - 1
        .ListItems(Ind).ListSubItems.Add , , Cell.Offset(0, -6)
        .ListItems(Ind).ListSubItems.Add , , Cell.Offset(0, -4)
        .ListItems(Ind).ListSubItems.Add , , Cell.Offset(0, -3)
        .ListItems(Ind).Checked = False
      End If
    Next Cell
  End With
  ' pour afficher la liste détaillée
  ListView1.View = lvwReport
End Sub

A+

Rebonjour et merci pour ces précisions

J'ai bien compris le rngSearch, un peu moins le ind.

Je pense qu'il s'agit de l'indice de la ligne créée, auquel cas cela résoudrait le problème sur lequel je bute, à savoir récupérer le numéro de ligne pour faire les calculs. Je ne trouvais rien sur la création des index et des clés dans le listview.

Je regarde çà ce week end et revient vers toi.

Merci

Salut,

Oui "Ind" est la variable raccourci de "Index"

Bonjour jvoitu, Salut Bruno,

Voici un exemple avec un module de classe qui gère un jeu d'évènements sur des checkboxes et l'affectation après le contrôle créé dynamiquement :

'Module de classe nommé MaClasse

public withevents CHK as msforms.checkbox

private sub CHK_change()
msgbox "chgt"
end sub

'Module Userform

dim tCtrl() as new MaClasse, Compteur as long 'en tête de module

sub Inconnu() 'là où il y a création
Compteur = Compteur + 1
Set CheckPointage = Usf_ComptesPointer.Controls.Add("Forms.CheckBox.1", "ChxPointe" & Compteur, True)
With CheckPointage
.Top = topctl
.Left = 920
End With
redim preserve tCtrl(1 to Compteur)
set tCtrl(Compteur).CHX = CheckPointage
end sub

Il faut bien sûr insérer le code de la macro Inconnu au bon endroit dans votre code.

Cdlt,

Re merci

Je regarde tout çà et çà va le faire

avec deux solutions, listview et module de classe, je vais surement trouver mon bonheur.

Bonjour à vous deux

Je travaille d'abord sur la listview de bruno et je me heurte à un problème (multiselect à false dans les paramètres). En effet, quelque soit la façon dont je m'y prends, ce sont toujours les infos de la première ligne que je récupére.

3Gb, je regarde ta solution demain

Avant check

avant check

quand je coche la case de la 2ème ligne, je récupérer les infos de la 1ere ligne

check

ensuite le calcul se fait correctement avec le code

Private Sub ListView1_ItemCheck(ByVal Item As MSComctlLib.ListItem)
' activation de la case à cocher
If Item.Checked = True Then
ind = ListView1.ListItems.Item(ListView1.SelectedItem.Index).Index

If ListView1.ListItems.Item(ind).SubItems(8) = "" Then
credit = 0
Else
credit = ListView1.ListItems.Item(ind).SubItems(8)
End If
If ListView1.ListItems.Item(ind).SubItems(7) = "" Then
debit = 0
Else
debit = ListView1.ListItems.Item(ind).SubItems(7)
End If
MsgBox debit & ", " & credit
Me.LblPointerComptes_Ecart = Me.LblPointerComptes_Ecart - debit + credit
End If

' désactivation de la case à cocher

If Item.Checked = False Then
ind = ListView1.ListItems.Item(ListView1.SelectedItem.Index).Index

If ListView1.ListItems.Item(ind).SubItems(8) = "" Then
credit = 0
Else
credit = ListView1.ListItems.Item(ind).SubItems(8)
End If
If ListView1.ListItems.Item(ind).SubItems(7) = "" Then
debit = 0
Else
debit = ListView1.ListItems.Item(ind).SubItems(7)
End If
MsgBox debit & ", " & credit
Me.LblPointerComptes_Ecart = Me.LblPointerComptes_Ecart + debit - credit
End If

'ind = Nothing
End Sub
apres check

mais, j'ai beau cocher, décocher, ce sont toujours les infos de la 1ère ligne que je raméne. je tourne en rond depuis ce matin.

Merci d'avance

Salut jvoitu,

Tu ne pourrais pas joindre ton fichier anonymisé, je pourrais répondre plus facilement

Edit : erreur de jugement

A+

Si bien sur. J'ai supprimé les prénoms, et les chiffres sont de toute façon complétement fantaisistes. C'est surtout parce que je ne suis pas un pro. Alors ne vous moquez pas trop de la façon dont je m'y suis pris

28comptes.zip (1.33 Mo)

Bonsoir jvoitu,

Très sympa ta petite appli

Voici le code, différent de ce que je pensais, mais simple à comprendre, je pense

Private Sub ListView1_ItemCheck(ByVal Item As MSComctlLib.ListItem)
  Dim Ind As Integer
  ' Récupérer l'index de la ligne
  Ind = Item.Index
  ' Récupérer la valeur numérique du Crédit et Débit
  If Me.ListView1.ListItems(Ind).SubItems(8) = "" Then
    dblCredit = 0
  Else
    dblCredit = CDbl(Replace(Me.ListView1.ListItems(Ind).SubItems(8), " ", ""))
  End If
  If ListView1.ListItems(Ind).SubItems(7) = "" Then
    dblDebit = 0
  Else
    dblDebit = CDbl(Replace(ListView1.ListItems(Ind).SubItems(7), " ", ""))
  End If
  ' Si la ligne est cochée ou décochée, faire le cumul
  If Me.ListView1.ListItems(Ind).Checked = True Then
    Me.LblPointerComptes_Ecart = CDbl(Me.LblPointerComptes_Ecart) - dblDebit + dblCredit
  Else
    Me.LblPointerComptes_Ecart = CDbl(Me.LblPointerComptes_Ecart) + dblDebit - dblCredit
  End If
End Sub

Nota : attention à vouloir additionner des variables "String" il faut les convertir et les mettre dans les variables appropriée

Ne met pas en commentaire "Option Explicit",
certes cela t'oblige à déclarer tes variables, mais tu auras beaucoup moins de soucis dans le développement

A+

Bonjour,

Super, c'est nickel. J'ai consulté des dizaines de discussion sur ce point, sur différents sites sans portant trouver ind = item.index. J'ai trouvé des combinaisons de listview1.listitem(listitem.index).index et j'en passe, sous toutes les formes possibles, mais pas celle ci pourtant si simple.

Concernant les variables string, je n'avais pas fait attention dans la mesure ou les calculs se faisaient.

Pour l'option explicit, en fait je la remets qd j'ai trouvé comment faire. Je teste souvent différentes formules trouvées sur le net et çà m'évite de déclarer tout de suite les variables que je garderai. Qd j'ai trouvé, je décoche explicit.

Encore merci à toi.

Il me reste à prévoir des boutons pour ajouter, modifier des opérations( çà devrait aller) et à voir ensuite comment rafraichir la listview aprés modification.( ce sera peut-être plus délicat, on verra)

Je vais aussi tester la solution de 3GB.

Un grand merci à vous deux

bonsoir,

j'ai commencé à travailler sur la solution de 3GB, et bien sur, je me heurte au même type de problème pour récupérer les données de calcul. J'ai réussi à associer le contrôle dynamique au module de classe en suivant les instructions.

Je récupère aussi le numéro de compteur du checkbox (solution probablement tarabiscottée), et ensuite je cale pour récupérer les montants.

Voila le code que j'ai mis dans le module de classe:

Public WithEvents CHK As MSForms.CheckBox

Private Sub CHK_Change()

Ind = Mid(CHK.Name, 10)

MsgBox Ind
End Sub

Comment ensuite récupérer les montants inscrits dans les labels dynamiques?

Merci d'avance à 3GB

Bonsoir,

Voici un exemple pour récupérer le caption d'un label :

Public WithEvents CHK As MSForms.CheckBox

Private Sub CHK_Change()
Ind = Mid(CHK.Name, 10)
MsgBox userforms(userforms.count - 1).controls("Label" & Ind).caption
End Sub

On peut éventuellement faire un test d'existence du label si nécessaire.

Cdlt,

C'est bon j'y suis arrivé. Je mets tout çà au propre et je joins les fichiers avec les deux solutions.

Encore merci à vous deux

Voila donc les deux fichiers un avec module de classe, l'autre avec listview.

Encore merci à vous deux.

Rechercher des sujets similaires à "rattacher controle cree dynamiquement module classe"