Automatiser UserForm

Bonjour, j'ai posté plusieurs fois ces dernières semaines.

J'aimerais adapter un UserForm en fonction d'un nombre de cases que je coche. Sur ma feuille d'accueil j'ai des listes et des checkbox pour chaque ligne de la liste, j'aimerais que quand je coche un nombre n de case donc par exemple 2, lorsque j'appuye sur un bouton j'ai sur mon Userform un nombre n de ligne (ici 2) de 3 textbox où je peux indiquer manuellement et automatiquement des informations (nom, heure, et commentaire). Une fois tout entré cela envoie les infos sur certaines cellules d'une autre page.

a b

Ici il y a deux lignes car j'ai coché 2 checkbox, les infos contenues dans ces lignes seront en liens avec les cellules des checkbox.

Savez-vous s'il est difficile de réaliser cela, s'il y a de meilleures alternatives et comment faire. (désolé pour mon schéma paint)

Pour l'instant j'ai un bouton qui ouvre le userform, et j'utilise userform_initialise, savez vous où je devrais déclarer une variable comptant le nombre de checkbox dans la colonne voulue. Je ferais ensuite for i = 1 to n avec n=n+1 pour créer plusieurs lignes.

Salut,

Pour ce qui est de la génération des différentes TextBox, voilà ce que je te propose :

Dim cTxNoms As New Collection
Dim cTxHeures As New Collection
Dim cTxComs As New Collection

Private Sub UserForm_Initialize()

    nb_checkbox = 5

    For i = 1 To nb_checkbox
        Set Tx_nom = Me.Controls.Add("Forms.Textbox.1", "tx_nom_" & i, True)
        With Tx_nom
            .Top = i * 30
            .Left = 6
            .Width = 132
            .FontSize = 11
            .Height = 24
        End With
        cTxNoms.Add Key:=Tx_nom.Name, Item:=New classTxNom
        Set cTxNoms(Tx_nom.Name).TargetTx = Tx_nom

        Set Tx_Heure = Me.Controls.Add("Forms.Textbox.1", "tx_heure_" & i, True)
        With Tx_Heure
            .Top = i * 30
            .Left = 144
            .Width = 132
            .FontSize = 11
            .Height = 24
        End With
        cTxHeures.Add Key:=Tx_Heure.Name, Item:=New classTxHeure
        Set cTxHeures(Tx_Heure.Name).TargetTx = Tx_Heure

        Set Tx_Com = Me.Controls.Add("Forms.Textbox.1", "tx_com_" & i, True)
        With Tx_Com
            .Top = i * 30
            .Left = 282
            .Width = 132
            .FontSize = 11
            .Height = 24
        End With
        cTxComs.Add Key:=Tx_Com.Name, Item:=New classTxCom
        Set cTxComs(Tx_Com.Name).TargetTx = Tx_Com

    Next i

    Me.Height = 60 + (30 * nb_checkbox)

End Sub

Avec en prime l'ajout de chacun de ces TextBox dans un module de classe approprié, avec le code suivant dans chacun des modules de classes (libre à toi de changer ce code si nécessaire en fonction de tes envies) :

Public WithEvents TargetTx As MSForms.TextBox

Private Sub TargetTx_Change()
    MsgBox "Écriture dans la TextBox Com"
End Sub

Pour ce qui est de l'initialisation de ma variable "nb_checkbox", qui correspond au nombre de CheckBox cochées, ça je te laisse voir, ou alors personnellement je changerais comment cela est mis en place car ça ne me semble pas très simple de lier des CheckBox à des cellules fixes, susceptibles de bouger.

Ci-joint le document sur lequel j'ai codé ça.

16classeur-forum.xlsm (43.21 Ko)

Merci, je vais essayer,

j'ai déja mes checkbox liés aux cases avec .address et quand je déplace les cellules, les checkbox sont bien liés et déplacés correctement. Le plus dur va être de compter le nombre de checkbox dans une colonne et lier chaque ligne de txtbox au contenu des cellules. J'ai une page archive automatisé donc j'ai déja le reste du code à envoyer (le but de ce userform est d'archiver ce que je vais cocher en ajoutant un commentaire).

Pour boucler sur toute les CheckBox présentes sur ta feuille, tu peux utiliser une boucle For (en supposant que les seules CheckBox utilisées sur la feuille servent à gérer ces listes d'opérations, ou alors utiliser un tag particulier pour ces CheckBox là), un peu de cette manière là :

    For i = 1 To 6
        OLEObjects("CheckBox" & i).Object.Value = True
    Next i

Avec 6 le nombre à modifier en fonction de ton nombre d'opérations.

Tu peux aussi utiliser une boucle For Each en bouclant sur toutes les CheckBox de la feuille, en affinant sur les CheckBox souhaitées.

Merci beaucoup, j'en utilise plusieurs sur une feuille, je les mets par colonnes, ducoup ca ferait :

sheets("Accueil").Range("D:D")OLEObjects("CheckBox" & i).Object.Value = True

ou alors je peux préciser dans les parenthèses avec i d'autres données comme la rangée ?

Bonjour,

lorsque je coche une case, il écrit VRAI dans la colonne lié, ducoup j'ai fait ça :

Private Sub Userform_Initialize()
    Call Valider
End Sub

Sub Valider()
    Dim NombreCkb As Integer, Colonne As Range
    Colonne = Sheets("Accueil").Range("D:D")
    NombreCkb = Application.WorksheetFunction.CountIf(Colonne, VRAI)

End Sub

Cependant le seul moyen pour que la fenêtre s'ouvre c'est quand je ne met aucun code dans les userform. Je ne sais pas trop comment utiliser les UserForm, mon UserForm s'appelle FenVal. Je fais FenVal.show quand je clique sur le bouton, ça m'envoie à ce code, mais pourquoi en première ligne c'est Userform_Initialize et pas FenVal_Initialize. Faut il déclarer quelque part dans le code que je parle bien du bon userform. Et Pourquoi ça ne fonctionne pas ?

ça semble être ces deux lignes qui posent problème (erreur 91):

    Colonne = Sheets("Accueil").Range("D:D")
    NombreCkb = Application.WorksheetFunction.CountIf(Colonne, VRAI)

C'est bon, j'avais oublié set, cependant en faisant un debug.print, j'ai NombreCkb = 0

Modifié, j'ai mis true au lieu de vrai et ca marche

J'ai réussi grâce à vous a créer le bon nombre de cases, de plus j'ai réussi a les lier au nombre de checkbox.

Est-il possible de définir le contenu d'une txtbox en fonction d'une cellule dans les modules de classes ? (j'ai enlevé les messages, c'est relou ça s'affiche à chaque caractères ^^) Y a-t-il pour ça une fonction qui contrairement à "Private Sub TargetTx_Change()" execute des le début.

Ou serait-ce mieux de le mettre directement dans le code principal afin de varier le contenu en fonction des cellules ? genre tx_heure & i = Cells (...)

Update : J'ai ça, je préfère rester dans le programme principal :

j = 4
For i = 17 To 40
    If activecells.Value = "TRUE" Then
        For e = 1 To NombreCkb
            Tx_nom & e.value = cells(i-2,j).value
            Tx_Heure & e.value=cells(i-1,j).value
        Next e
    End If
Next i
End Sub

Évidemment, Tx_nom & e.value ne marche pas, est-ce la bonne fonction et comment dire que c'est Tx_nom1 ou Tx_nom2 avec e comme chiffre

Bonjour à tous,

Est-il possible de définir le contenu d'une txtbox en fonction d'une cellule dans les modules de classes ? (j'ai enlevé les messages, c'est relou ça s'affiche à chaque caractères ^^) Y a-t-il pour ça une fonction qui contrairement à "Private Sub TargetTx_Change()" execute des le début.

Oui, c'est possible mais ce n'est pas l'utilisation classique d'un module de classe qui doit en principe contenir le moins d'éléments en statique.

Pour le faire dès le début, il faut le faire à l'initialisation de l'userform par exemple.

Pour identifier un contrôle en fonction de son nom, il faut cette syntaxe :

me.controls("Tx_nom" & e).value = cells(i, j).value

C'est un exemple...

Voici un essai d'adaptation de l'excellent code de BibuNesco :

'Module userform
dim UX as new UserformX
Private Sub UserForm_Initialize()
nb_checkbox& = 5 '<<< à calculer
UX.Configure Me, nb_checkbox, "nom", "heure", "com"
with Me
    .Height = 12 + (30 * nb_checkbox)
    .width = 12 + (138 * 3)
end with
End Sub

'Module de classe "UserformX"
dim tTx() as new classTx
private sub Configure(UF as userform, NbChecked as long, paramarray Cols())
tCols = Cols
if NbChecked < 1 then exit sub
if isempty(tCols) then exit sub else tCols = application.transpose(application.transpose(tCols))
redim tTx(1 to NbChecked, 1 to ubound(tCols))
For i = lbound(tTx) To ubound(tTx)
    for k = lbound(tTx, 2) to ubound(tTx, 2)
        sname$ = "tx_" & tCols(k) & "_" & i
        Set Tx = UF.Controls.Add("Forms.Textbox.1")
        With Tx
            .name = sname
            .Top = 6 + (i - 1) * 30
            .Left = 6 + (k - 1) * 138
            .Width = 132
            .FontSize = 11
            .Height = 24
        End With
        Set tTx(i, k).TargetTx = Tx
    next k
Next i
end sub

'module de classe classTx
Public WithEvents TargetTx As MSForms.TextBox

Private Sub TargetTx_DoubleClick()
DoubleClick TargetTx
End Sub

private sub DoubleClick(tx as msforms.textbox)
with tx
    select case .backcolor
        case is > 10000: .backcolor = 255
        case else: .backcolor = RGB(255, 255, 255)
    end select
end with
end sub

Il est à noter que la classe pour utiliser les évènements des textbox est intégrée dans la classe UserformX.

Pour l'instant, on ajoute des textbox en fonction du nombre de checkbox, dont le calcul n'apparait pas dans le code. Pour ajouter des lignes en fonction d'une plage, c'est possible mais il semble qu'il faille un peu changer de méthode et notamment la procédure Configure.

Cdlt,

Je trouve le code assez compliqué, je vais essayer de comprendre mais avant j'aimerais essayer de mettre les valeures, en utilisant :

i=4
j=18
me.controls("Tx_nom_" & e).value = cells(i, j-2).value

J'obtiens :

a = 1
j = 4
For i = 17 To 40
    If Cells(i, j) = "TRUE" Then
        Me.Controls("Tx_nom_" & a).Value = Cells(i, j - 2).Value
        Me.Controls("Tx_heure_" & a).Value = Cells(i, j - 1).Value
        a = a + 1
    End If
Next i

L'Userform s'ouvre correctement et "TRUE" devrait marcher car il marche déjà plus en haut pour définir e max

C'est bon, j'ai juste du en lever les guillemets à TRUE. Merci beaucoup à vous

Salut Whyph,

Oui, le code est compliqué ! la seule différence avec le précédent est qu'on variabilise la création des contrôles et qu'on passe par un tableau (2 dimensions : pour les lignes - nombre de checkboxes - et les colonnes - pour l'instant figées à 3 - "nom", "heure" et "com") plutôt que par une collection.

Mais ensuite, il aurait été plus simple je pense d'adapter le code pour se focaliser sur la plage plutôt que sur les checkboxes.

En tout cas, bravo pour la résolution du problème et bon courage pour la suite !

Cdlt,

Rechercher des sujets similaires à "automatiser userform"