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
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,
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:
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 SubSalut,
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 SubA+
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
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 subIl 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
quand je coche la case de la 2ème ligne, je récupérer les infos de la 1ere ligne
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
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
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 SubNota : 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 SubOn 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.