Ajouter les boutons avec code VBA sur chaque ligne [Résolu/Fermé]

Signaler
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
-
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
-
Bonjour,

Voici ma macro :

Public i As Long
Public V As Long


Sub Macro1()

Dim DL As Long, Obj As Object, Code As String

DL = Cells(Application.Rows.Count, 1).End(xlUp).Row

For i = 1 To DL

'crée le bouton

With Range("K" & i)
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.ColumnWidth, Height:=.RowHeight)
    Obj.Name = "BoutonTest"
End With

V = i

'texte du bouton
    ActiveSheet.OLEObjects(1).Object.Caption = "OK"

'Le texte de la macro
    Code = "Sub BoutonTest_Click_Ligne_" & i & "()" & vbCrLf
    Code = Code & "Rows(V).Interior.Color = RGB(146, 208, 80)" & vbCrLf
    Code = Code & "End Sub"
'Ajoute la macro en fin de module feuille
    With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.Name).CodeModule
        .insertlines .CountOfLines + 1, Code
    End With
    
Next i
End Sub


Les boutons se mettent bien sur chaque ligne. Mais ce qui m'embête, c'est que le code qui est censé colorer la ligne si je clique dessus ne marche pas...

2ème chose, le bouton ne fait pas la taille exacte de la cellule, alors qu'il en censé se redimensionner...

Et enfin une dernière question importante, est ce que si je met cette macro dans un bouton du ruban, elle pourra s'exécuter sur n'importe quel fichier excel vierge? Sinon comment est-ce possible?

Edit : Trouvé pour la question d'utiliser mes macros dans n'importe quel fichier. Merci à ce tuto : https://www.commentcamarche.net/faq/28980-creation-classeur-de-macros-personnalisees-2007

Merci d'avance.

Cordialement.

4 réponses

Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498
Bonjour,

La propriété ColumnsWidth n'utilises pas la même unité que la propriété Width. D'ou le décalage de tailles attendues...
utilise donc :
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.Width, Height:=.RowHeight)


Ensuite, tu nommes tous tes boutons de manière identique :
Obj.Name = "BoutonTest"

ET tu utilises un événement qui ne fonctionnera pas : _Click_Lignexx

Regarde ce code :
For i = 1 To DL

'crée le bouton

With Range("K" & i)
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.Width, Height:=.RowHeight)
    Obj.Name = "BoutonTest" & i
End With

'texte du bouton
    ActiveSheet.OLEObjects(1).Object.Caption = "OK"

'Le texte de la macro
    Code = "Sub BoutonTest" & i & "_Click()" & vbCrLf
    Code = Code & "Rows(" & i & ").Interior.Color = RGB(146, 208, 80)" & vbCrLf
    Code = Code & "End Sub"
'Ajoute la macro en fin de module feuille
    With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.Name).CodeModule
        .insertlines .CountOfLines + 1, Code
    End With
    
Next i



Avant, j'arrivais jamais à finir mes phrases... mais maintenant je
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 60511 internautes nous ont dit merci ce mois-ci

Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498 >
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019

A la place de :
With Range("K" & i)
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.ColumnWidth, Height:=.RowHeight)
    Obj.Name = "BoutonTest" & i
End With

texte du bouton
    ActiveSheet.OLEObjects(1).Object.Caption = "OK"


Essaye :
With Range("K" & i)
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.ColumnWidth, Height:=.RowHeight)
    Obj.Name = "BoutonTest" & i
End With

texte du bouton
    Obj.Object.Caption = "OK"
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Bravo belle maîtrise.

Merci beaucoup. C'est vraiment sympa.

Bonne soirée.
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Mais du coup je me demande quand même comment j'ai pu être assez stupide pour ne pas mettre directement :

Code = Code & "Rows(" & i & ").Interior.Color = RGB(146, 208, 80)" & vbCrLf


Il n'y avait besoin de rien d'autre...
Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498 >
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019

Tu étais partie avec l'idée de construire ta macro grâce à une variable publique.
Du coup cette idée t'es apparue comme LA bonne, et tu n'as pas cherché autre chose.
ça m'arrive tout le temps.
C'est à ça qu'aide, parfois, un second regard, généralement le lendemain...ou par un autre sur le forum ;-)
A++
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Pensez-vous qu'il serait possible d'avoir 2 valeurs pour le nom du bouton, le bouton serait au départ nommé "PAS OK" et lorsque je clique dessus il se transformerait en "OK". Si je reclique à nouveau, il se remettrait en "PAS OK". Etc. J'ajoute que lorsque le bouton est sur "PAS OK", il faudrait que la ligne ne soit pas colorée.

Merci beaucoup.
Messages postés
6992
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
28 octobre 2020
564
Bonjour,

un petit salut a pijaku

Pour faire ce que tu veux faire, il faut d'abord faire ton code pour qu'il soit opérationnel comme ceci:

Sub BoutonTest1_Click()
If BoutonTest1.Caption = "PAS OK" Then
Rows(1).Interior.Color = RGB(146, 208, 80)
BoutonTest1.Caption = "OK"
Else
Rows(1).Interior.Color = xlNone
BoutonTest1.Caption = "PAS OK"
End If
End Sub


après il suffit de le retranscrire comme cela:

Option Explicit
Public i As Long
Public V As Long
Sub Bouton1_Clic()
Macro1
End Sub
Sub Macro1()
Dim DL As Long, Obj As Object, Code As String

DL = Cells(Application.Rows.Count, 1).End(xlUp).Row

For i = 1 To DL

'crée le bouton

With Range("K" & i)
    Set Obj = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=.Left, Top:=.Top, Width:=.ColumnWidth, Height:=.RowHeight)
    Obj.Name = "BoutonTest" & i
End With

'texte du bouton
    Obj.Object.Caption = "OK"
'texte du bouton
    ActiveSheet.OLEObjects(1).Object.Caption = "OK"

'Le texte de la macro
    Code = "Sub BoutonTest" & i & "_Click()" & vbCrLf
     Code = Code & "If BoutonTest" & i & ".Caption = ""PAS OK"" Then" & vbCrLf
    Code = Code & "Rows(" & i & ").Interior.Color = RGB(146, 208, 80)" & vbCrLf
    Code = Code & "BoutonTest" & i & ".Caption = ""OK""" & vbCrLf
    Code = Code & "Else" & vbCrLf
    Code = Code & "Rows(" & i & ").Interior.Color = xlNone" & vbCrLf
    Code = Code & "BoutonTest" & i & ".Caption = ""PAS OK""" & vbCrLf
    Code = Code & "End If" & vbCrLf
    Code = Code & "End Sub"
'Ajoute la macro en fin de module feuille
    With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.Name).CodeModule
        .insertlines .CountOfLines + 1, Code
    End With
    
Next i
End Sub


Le plus dure c'est les double cote, mais quand tu as pigé ça va tout seul
Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498
Bonjour Le Pivert,

Merci du coup de main.

Personnellement, ce qui me gène dans ce genre de choses, c'est la multiplication des contrôles sur la feuille. En grand nombre, le fichier n'est plus stable et risque fort de planter définitivement avec perte des données...

Pourquoi faire des boutons lorsqu'une simple MFC suffit à résoudre la chose?

Il suffit en effet de saisir OK ou PAS OK en colonne K pour parvenir au même résultat.

Je déconseille donc vivement la solution VBA dans ce sujet.

Mais bon, ta macro résoud le problème posé ici.

A++
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Super !

Merci beaucoup, c'est exactement ce que je voulais. En plus, ça m'a permis d'apprendre pas mal de trucs !

Juste une chose, voilà je me pose la question, sachant qu'en fait, je créé une macro qui sera utilisée par n'importe quel fichier excel donc dans PERSONAL.xlsb étant donné qu'elle doit être utilisable juste après une extraction de mon logiciel de gestion. Ma macro qui créé les boutons est intégrée à une macro qui fait plein de mises en forme.

Seulement voilà, macro terminée. Ok tout est beau et mis en forme. Mais, par exemple il faut que l'utilisateur puisse supprimer une ligne ou en rajouter une si ça le chante. Si je supprime une ligne, je clique sur le bouton OK de la ligne d'en face, évidemment, c'est la ligne du dessous qui se colore en vert puisque i n'a pas changé dans le bouton. Un moyen de contrer cela?

Comment je peux faire si l'utilisateur rajoute une ligne pour qu'un bouton se mette en face et ait la même fonction, c'est à dire de colorer la ligne si je clique sur OK?

Merci d'avance.
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Vous pensez que si je déclare DL sur "ThisWorkbook" de PERSONAL.xlsb en public ça peut marcher?
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Laissez tomber, j'ai trouvé une autre solution. Merci.
Messages postés
6992
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
28 octobre 2020
564
Je crois que pijaku t'as donné la solution. Ca que tu veux faire, va ressembler à une usine à gaz. Tout est possible en vba, jusqu'à une certaine limite. Excel possède des outils natifs, il faut t'en servir!
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
C'est exact, c'était une usine à gaz. Du coup j'ai fais une coloration et un "OK" automatique dans ma colonne avec un bouton dans le ruban. Beaucoup plus simple. Beaucoup plus stable.
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
J'ai une dernière question (pardon d'abuser de vos connaissances), dans ma macro, j'ai une InputBox qui demande une date. Cette date sert à mettre à titre sur la ligne 1. J'ai une deuxième macro qui enregistre le fichier, est-ce que je peux me resservir de la valeur de l'InputBox pour donner un nom au fichier?
Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498 >
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019

Si la variable qui stocke la réponse de l'InputBox est déclarée Public en entête d'un module standard, la réponse est oui.
Attention toutefois, les / des dates ne sont pas forcément bons pour les noms de fichier sous Windows. Dans ce cas, utiliser la fonction Replace :
Replace(mavar, "/", "")
Messages postés
6992
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
28 octobre 2020
564
en complément de pijaku, voici un exemple:

Dim madate As Date
madate = Application.InputBox("Entrez votre date", "Date", FormatDateTime(Date, vbShortDate), Type:=1)
Range("A1").Value = madate

Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Ah oui d'accord, je n'avais pas vu les choses comme ça. C'est vraiment super merci beaucoup pour les explications. Je ne suis qu'un débutant en VBA qui commence à me débrouiller sur certains trucs mais j'ai soif d'apprendre tout ce que je peux apprendre.

Pour le calendrier, si tu ne considère pas ça comme de l'abus, je veux bien de l'aide. Les gens qui se serviront de mon fichier sont nombreux et j'avoue qu'un calendrier est le meilleur moyen d'être sûr d'avoir le format de date que je veux. En plus, ça a très clairement la classe.

Merci encore 1000 fois pour tout ce que vous faites.
Messages postés
12186
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
15 octobre 2020
2 498 >
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019

Essaye ce fichier.
Je travaillais dessus il y a quelques temps, il n'est pas fini, donc il peut encore y avoir des bugs.
Si cela te convient, on peut essayer de le débugger pour toi et t'expliquer comment t'en servir.
Le fichier

Faudra juste ne pas être trop pressé...
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Je suis pas du tout pressé, mais ça m'intéresse. L'InputBox suffira pour l'instant. En ce qui concerne le fichier pour tester, toutes mes macros sont dans PERSONAL.XLSB car il faut qu'elles marchent de partout.... Je sais pas trop comment vous faire un fichier test.
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Je viens de comprendre le truc. C'est atroce. En fait, le code ne peut renommer le fichier que si celui-ci n'est pas ouvert. Mais c'est pourtant ce fichier ouvert que je veux renommer... Comment faire?
Messages postés
850
Date d'inscription
vendredi 13 février 2015
Statut
Membre
Dernière intervention
15 février 2019
38
Je vais créer un nouveau sujet si ça ne vous dérange pas à ce sujet là.