Bouton a cocher

Bonjour,

J'ai un tableau de maximum 45 ligne à copier coller en fonction de ce que choisit le client.

J'aimerais réaliser des boutons à cocher et dès qu'il coche et qu'il clique sur valider les lignes se copie/colle dans le tableau d'a coté.

J'ai mis en piece jointe ce que j'aimerais

Merci à vous de votre aide.

PS :J'ai mis une ébauche avec trois cases à cocher mais comme je l'ai dit il peut y en avoir jusqu'a 45 )

9test1.xlsx (22.80 Ko)

Bonjour,

J'ai peut-être plus simple comme solution...

Comme tu parles de cases à cocher, tu peux écrire x ou X dans les cases que tu veux copier, ensuite il ne reste qu'à voir celles que tu copies

Sinon tu vas un peu t'embêter si tu dois créer autant de cases à cocher que tu n'as de lignes à copier, c'est impensable pour un fichier de 1000 lignes par exemple, sinon pour le point info, tu dois pouvoir parcourir tous les contrôles de ta feuille, et ils ont une propriété BottomRightCell qui permet de savoir quelle cellule se trouve en haut à droite de ton contrôle.

Voici un bout de code qui parcourt tous tes OLEObject de ta Feuil2 et qui affiche les addresses des cellules qui se trouve en haut à droite :

Sub test()
Dim ctrl As OLEObject
For Each ctrl In Feuil2.OLEObjects
    MsgBox (ctrl.BottomRightCell.Address)
Next ctrl
End Sub

Comment faire simple quand on peut faire compliquer !

Ahah merci

Bonjour,

Une autre piste un peu plus complexe car avec un module de classe !

La coche d'une case à cocher transfère les données de la ligne correspondante, la décoche supprime les données de la ligne correspondante. Si tu rajoutes des cases à cocher et afin que celles-ci soient intégrées au tableau, change de feuille et reviens sur la feuille afin d'exécuter la sub "CaseACocher()" située dans le Module1, cette dernière est appelée à l'ouverture du classeur et à l'activation de la feuille :

Bonjour,

Une autre piste un peu plus complexe car avec un module de classe !

La coche d'une case à cocher transfère les données de la ligne correspondante, la décoche supprime les données de la ligne correspondante. Si tu rajoutes des cases à cocher et afin que celles-ci soient intégrées au tableau, change de feuille et reviens sur la feuille afin d'exécuter la sub "CaseACocher()" située dans le Module1, cette dernière est appelée à l'ouverture du classeur et à l'activation de la feuille :

Test1 Module de Classe.xlsm

Pas mal du tout

Moi qui commençait à m'intéresser aux modules de classe, tu tombes bien!

Du coup si je comprends bien...

Tu définis d'abord ta classe Chk via le Dim as new Classe1 pour faire un type d'objet personnalisé...

Et après... tu utilises Set Chk(I).GroupeChk = Ctrl.Object pour définir des objets appartenant à la classe GroupeChk ?

Je dois avouer que comme je débute avec ça j'ai encore du mal à digérer les lignes de code, j'ai regardé des explications mais comme je n'en n'ai pas encore codé... Je n'arrive pas encore à assimiler la syntaxe etc...

Bonjour Ausecour,

Tu définis d'abord ta classe Chk via le Dim as new Classe1 pour faire un type d'objet personnalisé...

La déclaration en tête de module permet une portée de niveau classeur.

Et après... tu utilises Set Chk(I).GroupeChk = Ctrl.Object pour définir des objets appartenant à la classe GroupeChk ?

chaque appel de la classe...

Set Chk(I).GroupeChk = Ctrl.Object

...crée une instance de cette classe donc, une instance pour chaque case à cocher ce qui fait que chaque fois qu'un clic est fait sur une des case à cocher, la classe est appelée (le ou les événements correspondants s'y trouvant sont exécutés).

On utilise un tableau quand on souhaite que tous les contrôles aient le même événement. Si il n'y avait que 3 cases à cocher (à priori 45 en tout d'après les dires de NyfaDu86), j'aurai pu utiliser ce code :

Dim Case1 As New Classe1
Dim Case2 As New Classe1
Dim Case3 As New Classe1

Sub CaseACocher()

    Set Case1.GroupeChk = Feuil2.OLEObjects("CheckBox1").Object
    Set Case2.GroupeChk = Feuil2.OLEObjects("CheckBox2").Object
    Set Case3.GroupeChk = Feuil2.OLEObjects("CheckBox3").Object

End Sub

Dans le module de classe, j'ai utiliser le mot "GroupeChk" pour indiquer qu'il y a plusieurs objets qui vont appeler cette classe (cette appellation est pour moi, chacun fait comme il l'entend !)

Dans le module de classe, j'utilise :

With ActiveSheet

    .Range(.Cells(Lig, 14), .Cells(Lig, 24)).Value = IIf(GroupeChk.Value = True, .Range(.Cells(Lig, 2), .Cells(Lig, 12)).Value, "")

End With

mais généralement, on évite de faire appel à un objet extérieur à la classe (ici, la feuille active) de façon à ce que le code soit "encapsulé" mais comme les cases à cocher se trouvent sur une feuille et qu'elles sont cochées ou décochées avec la souris j'ai pris cette liberté car il y a peu de risque d'avoir des erreurs mais admettons que maintenant, je décide de mettre un bouton sur une autre feuille qui va cocher une des cases et bien la classe va être appelée et une mauvaise manip va être faite car les valeurs transférées se feront sur la feuille active (là où se trouve le bouton) et non sur la feuille qu'on souhaite. Tu peux tester dans le module d'une autre feuille (en ayant au préalable entré des valeurs bidon de B à L) avec ce code pour voir le résultat :

Private Sub CommandButton1_Click()

    Feuil2.OLEObjects("CheckBox1").Object.Value = True

End Sub

Afin de faire en sorte que la classe soit encapsulée, il suffit de lui passer la feuille cible et dans ce cas, il ne peut plus y avoir d'erreur !

Exemple, le code dans le module de classe :

Public WithEvents GroupeChk As MSForms.CheckBox
Public Fe As Worksheet

Private Sub GroupeChk_Click()

    Dim Lig As Long

    Lig = GroupeChk.TopLeftCell.Row

    With Fe

        .Range(.Cells(Lig, 14), .Cells(Lig, 24)).Value = IIf(GroupeChk.Value = True, .Range(.Cells(Lig, 2), .Cells(Lig, 12)).Value, "")

    End With

End Sub

où je vient de rajouter une variable WorkSheet (Fe) et donc, maintenant ce n'est plus ActiveSheet mais "With Fe" dans la procédure événementielle ce qui fait qu'on est sûr de viser la bonne feuille et la classe ne fait plus appel à un objet extérieur à elle.

Dans la procédure d'affectation, il faut passer la feuille aux instances de classe comme ceci :

Dim Case1 As New Classe1
Dim Case2 As New Classe1
Dim Case3 As New Classe1

Sub CaseACocher()

    Set Case1.GroupeChk = Feuil2.OLEObjects("CheckBox1").Object
    Set Case2.GroupeChk = Feuil2.OLEObjects("CheckBox2").Object
    Set Case3.GroupeChk = Feuil2.OLEObjects("CheckBox3").Object

    Set Case1.Fe = Worksheets("Feuil2")
    Set Case2.Fe = Worksheets("Feuil2")
    Set Case3.Fe = Worksheets("Feuil2")

End Sub

ou dans le tableau :

Sub CaseACocher()

    Dim Ctrl As OLEObject
    Dim I As Integer

    Erase Chk

    For Each Ctrl In Feuil2.OLEObjects

        If TypeName(Ctrl.Object) = "CheckBox" Then

            I = I + 1: ReDim Preserve Chk(1 To I)
            Set Chk(I).GroupeChk = Ctrl.Object
            Set Chk(I).Fe = Worksheets("Feuil2")

        End If

    Next Ctrl

End Sub

Merci pour toutes ces explications

J'ai commencé à entendre parler d'encapsulation de classes en regardant des cours sur Java la semaines dernière, mais ce n'était pas encore bien clair...

En tout cas je vois mieux l'intérêt de l'encapsulation grâce à ton exemple, et je vois mieux à quoi sert ta création d'instances.

Je voulais voir si on pouvait passer par dessus ce comportement par défaut comme en Java, du coup j'ai fait un programme rapide, si on clique sur la première case à cocher (au lieu de copier on affiche un msgbox) et ça ne fait bien que la messagebox, parfait

Même en ne mettant rien ça marche, le simple fait de faire apparaître CheckBox1_Click, ça passe par-dessus la méthode de la classe, pas mal pas mal...

Bonne journée

EDIT:

Ah, en fait après d'autres tests, ça ne marche pas exactement comme ça... ça appelle un des deux, ou bien les deux programmes, mince

Il faudra que je fasse différemment alors, peut-être voir si un code est associé à l'évènement en question dans le contrôle, mais compliqué... instancier manuellement les checkbox me semble la seule solution si je veux éviter ça visiblement

Ah, en fait après d'autres tests, ça ne marche pas exactement comme ça... ça appelle un des deux, ou bien les deux programmes,

Je ne connais pas Java mais si tu utilises et la procédure événementielle propre à la case à cocher ( CheckBox1_Click() ) et la procédure dans le module de classe, les deux seront exécutées, à savoir que la procédure "CheckBox1_Click()" appelle elle aussi une classe

Rechercher des sujets similaires à "bouton cocher"