excel macro à la coche d'une case

gaston gaston
1 621 contributions
Membre depuis le 01/03/2001
Envoyé le 22/06/2023 à 15:40 Modifié par gaston


Bonjour,

Dans Excel, on a une feuille où, dans la colonne A se trouvent des cases à cocher, puis dans les colonnes B à G, on met différentes données.
Comment faire une macro qui copie les cellules B à G d'une ligne cochée et les colle à la dernière ligne non vide d'une autre feuille, mais que cette macro ne se déclenche qu'au moment où l'on coche la case de la cellule A de cette ligne (disons que c'est l'action de cocher qui provoquerait la macro).
(Je ne sais pas si c'est très clair ?)


carpe diem
Bipbipcoyote Bipbipcoyote
4 325 contributions
Membre depuis le 06/03/2001
Envoyé le 23/06/2023 à 02:12 Modifié par Bipbipcoyote


Bonjour,
Admettons
1. que le tableau où on doit trouver la dernière ligne va de J à O
2. que les checkbox soient des activeX et que l'on vérifie leurs noms dans les propriétés, en principe c'est un nom standard incrémenté
3. il faut noter que cocher ou décocher la case ne provoque pas l'événement Change sur la feuille même si on lie une cellule dans les propriétés de la checkbox
4. donc on peut faire ceci (il faudra affiner par la suite, car on a vite fait de cocher ou décocher, peut être masquer la case une fois qu'on l'a utilisée avec un CheckBox1.Visible = False, ou CheckBox1.Enabled = False ou encore faire une comparaison de données pour vérifier si on n'a pas déjà encodé etc...) pour éviter un double encodage
5. Je livre ici une piste toute simple avec 2 cases à cocher. Note qu'il suffit de recopier autant de fois que l'on veut les Sub CheckBox?_Change, il suffit d'incrémenter le nom de la checkbox et modifier l'adresse de la Cellule....
Private Sub CheckBox1_Change()
If CheckBox1 = True Then
Call Remplir_Tableau(Range("A1").Address)
'CheckBox1.Visible = False
'CheckBox1.Enabled = False
End If
End Sub
Private Sub CheckBox2_Click()
If CheckBox2 = True Then
Call Remplir_Tableau(Range("A2").Address)
End If
End Sub
Sub Remplir_Tableau(MaCellule As String)
'de J1 à 01 il y a des titres
If Range("J2") = "" Then
Range("J2") = Range(MaCellule).Offset(0, 1)
Range("K2") = Range(MaCellule).Offset(0, 2)
Range("L2") = Range(MaCellule).Offset(0, 3)
Range("M2") = Range(MaCellule).Offset(0, 4)
Range("N2") = Range(MaCellule).Offset(0, 5)
Range("O2") = Range(MaCellule).Offset(0, 6)
Else
Range("J1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 1)
Range("K1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 2)
Range("L1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 3)
Range("M1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 4)
Range("N1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 5)
Range("O1").End(xlDown).Offset(1, 0).Value = Range(MaCellule).Offset(0, 6)
End If
End Sub

ATTENTION : pour que le xlDown fonctionne il faut qu'il y ait au moins 2 lignes remplies, on ne trouve xlDown que sur la 3ème ligne, mais on peut mettre des titres sur la ligne 1, prévoir le cas spécial de la seconde ligne avec un IF mescellules ne sont pas remplies, on les remplit en dur (sans end(xldown) )
Visitez mon Site Google est mon ami, il répond mieux que moi, posez lui d'abord vos questions
gaston gaston
1 621 contributions
Membre depuis le 01/03/2001
Envoyé le 25/06/2023 à 19:57 Modifié par gaston


Bonjour,

merci pour ta réponse, je comprends à peu près.
Le hic, c'est lorsqu'on a plus de 10000 lignes (et je crois que ça peut être le cas !), s'il faut recopier les sub CheckBoxn_Change autant de fois qu'il y a de lignes, fichtre... [:o]

Pour le xlDown, à la limite, il suffirait donc d'avoir une ligne de titres et une autre de sous-titres ?

Pour le tableau où on doit trouver la dernière ligne, il est vide au départ: il ne sert qu'à recueillir les copié-collé, mais on peut y mettre une ligne de titre et une 2ème ligne bidon, si ça simplifie.

Pour le reste, est-ce qu'il ne serait pas faisable, par exemple, de lancer la macro simplement en cliquant sur une cellule donnée et que cette macro détermine le numéro de ligne de cette cellule active pour pouvoir copier la plage de B à G de cette ligne, pour la coller (pourquoi pas si ça simplifie), à partir de la colonne B de l'autre feuille.
Ou alors pareil mais carrément en sélectionnant la plage B à G d'une ligne et en copiant-collant la sélection.
Ou alors encore, lancer une macro qui demande un numéro de ligne puis effectue le copié-collé de la plage B à G en fonction de ce numéro
carpe diem
Bipbipcoyote Bipbipcoyote
4 325 contributions
Membre depuis le 06/03/2001
Envoyé le 26/06/2023 à 01:31 Modifié par Bipbipcoyote


Bonjour,
ok, alors on va récupérer l'événement double clic dans une case, le plus simple est sans doute dans la colonne A. Dans le code de la feuille on a donc ceci

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim MaLettre As String
MaLettre = Mid(Target.Address, 2, 1)
If MaLettre = "A" Then 'On vérifie si on a bien cliqué dans une case de la colonne A
UserForm1.Show
End If
Target.Offset(0, 1).Select 'sinon la cellule en colonne A reste en mode édition
End Sub

On crée alors un USERFORM avec autant de textbox que l'on a de données
la procédure ci-dessus se produit quand le formulaire est activé (=affiché) et l'on a aussi 2 boutons de commande, l'un pour recopier les données, l'autre pour fermer le formulaire (on peut se contenter aussi de la croix en haut à droite mais bon un bouton est peut être plus compréhensible)
Et lorsque le formulaire s'active on récupère les valeurs à copier

Private Sub UserForm_Activate()
TextBox1.Value = ActiveCell
TextBox2.Value = ActiveCell.Offset(0, 1)
TextBox3.Value = ActiveCell.Offset(0, 2)
TextBox4.Value = ActiveCell.Offset(0, 3)
TextBox5.Value = ActiveCell.Offset(0, 4)
TextBox6.Value = ActiveCell.Offset(0, 5)
End Sub

Private Sub Recopier_Click()
Range("J1").End(xlDown).Offset(1, 0).Value = CLng(TextBox1)
Range("K1").End(xlDown).Offset(1, 0).Value = CLng(TextBox2)
Range("L1").End(xlDown).Offset(1, 0).Value = CLng(TextBox3)
Range("M1").End(xlDown).Offset(1, 0).Value = CLng(TextBox4)
Range("N1").End(xlDown).Offset(1, 0).Value = CLng(TextBox5)
Range("O1").End(xlDown).Offset(1, 0).Value = CLng(TextBox6)
End Sub

Private Sub Fermeture_Click()
Unload UserForm1
End Sub

ATTENTION que le contenu d'une TextBox, comme son nom l'indique c'est TOUJOURS du texte donc le type de la donnée c'est un String, si tu travailles avec des nombres, il faut donc convertir les données dans le bon format, idem pour les dates etc...

Ici, il n'y a plus de souci avec le nombre de lignes tu peux en avoir autant que tu veux...et pour répondre à ton observation, oui on peut utiliser un titre et un sous titre pour remplir les 2 premières lignes

Fichier sur CJoint
Attention, avec les nouvelles moutures d'Excel comme il y a des macros, via l'explorateur de fichiers, tu dois faire un clic droit sur le fichier - puis propriétés - et il y a une case à cocher nommée "débloquer" sans cela tu ne sais plus activer les macros

Et sans doute que l'on peut faire la recopie directement avec le double clic sans passer par un userform mais je trouve cela élégant et l'utilisateur se rend compte que quelque chose se passe et il peut toujours fermer le formulaire s'il se rend compte qu'il ne devait pas faire cette recopie ou tu peux mettre un simple MsgBox "Vous venez de recopier les données de la ligne en cours" mais là, je vois déjà la question suivante que l'on va te poser : "est ce qu'on peut annuler ce que l'on vient de faire ?"
Visitez mon Site Google est mon ami, il répond mieux que moi, posez lui d'abord vos questions

Discussion trop ancienne

Cette discussion a été automatiquement fermée car elle n'a plus reçue de nouveau message depuis trop longtemps.

Nous vous suggérons de créer un nouveau message

« Retour sur la liste des messages de ce forum