Ajouter les boutons avec code VBA sur chaque ligne

Résolu/Fermé
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 - Modifié par Kuartz le 24/09/2015 à 15:20
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 - 25 sept. 2015 à 17:10
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.
A voir également:

4 réponses

pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743
Modifié par pijaku le 24/09/2015 à 15:35
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
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
24 sept. 2015 à 16:02
Ca marche beaucoup mieux merci ! Petite chose encore, quand j'ai plusieurs ligne, le premier bouton s'appelle "OK" mais les autres s'appellent CommandButton1, je comprend pas...
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019
Modifié par pijaku le 24/09/2015 à 16:12
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"
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
24 sept. 2015 à 16:07
Bravo belle maîtrise.

Merci beaucoup. C'est vraiment sympa.

Bonne soirée.
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
24 sept. 2015 à 16:12
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...
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019
24 sept. 2015 à 16:23
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++
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 728
24 sept. 2015 à 18:20
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
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743
25 sept. 2015 à 09:14
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++
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 11:03
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.
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 11:05
Vous pensez que si je déclare DL sur "ThisWorkbook" de PERSONAL.xlsb en public ça peut marcher?
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 11:28
Laissez tomber, j'ai trouvé une autre solution. Merci.
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 728
25 sept. 2015 à 11:17
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!
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 11:30
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.
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 11:31
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?
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019
Modifié par pijaku le 25/09/2015 à 11:54
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, "/", "")
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 728
25 sept. 2015 à 11:55
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

0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743
Modifié par pijaku le 25/09/2015 à 11:58
Salut,

Ou plutôt :

Public madate As Date

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

Sub Macro2()
'syntaxe SaveAs à vérifier...
ThisWorkbook.SaveAs ThisWorkbook.Name & madate
End Sub
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
Modifié par Kuartz le 25/09/2015 à 14:03
Dans ma macro, j'ai :

Recommence:

DATE_ECHEANCE = InputBox("Entrer la date d'échéance des factures concernées au format jj/mm/aaaa.", "Date d'échéance")

If DATE_ECHEANCE = "" Then
MsgBox ("Vous devez entrer une date d'échéance pour poursuivre le traitement.")
GoTo Recommence
End If

If Not IsDate(DATE_ECHEANCE) Then
MsgBox ("Le format entré n'est pas une date, entrer une date valide au format jj/mm/aaaa.")
GoTo Recommence
End If

If DATE_ECHEANCE <> Format(DATE_ECHEANCE, "dd/mm/yyyy") Then
MsgBox ("La date n'est pas au format jj/mm/aaaa, entrer un date au format jj/mm/aaaa.")
GoTo Recommence
End If


Comment je dois faire si je déclare mon InputBox en public? Comment j'appelle mon Inputbox dans ma macro?

J'imagine qu'intégrer un calendrier pour choisir la date est quelque chose de très complexe?
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019
Modifié par pijaku le 25/09/2015 à 14:17
1- on va éviter les GoTo. Pourquoi? Cela donne un code pas très clair et difficile à maintenir.
En plus, ça allonge le nombre de lignes de code...
Essaye ceci :
Do
DATE_ECHEANCE = InputBox("Entrer la date d'échéance des factures concernées au format jj/mm/aaaa.", "Date d'échéance")
Loop While DATE_ECHEANCE = "" Or Not IsDate(DATE_ECHEANCE) Or DATE_ECHEANCE <> Format(DATE_ECHEANCE, "dd/mm/yyyy")


2- ce n'est pas ton InputBox que tu déclares, mais la variable qui en stocke le résultat. Donc DATE_ECHEANCE doit être déclarée comme public.
En entête d'un module "standard" (premiéres lignes en haut du module, avant toute Sub ou Function), place cette ligne :
Public DATE_ECHEANCE As String

Ainsi, une fois que tu auras implémenté ta variable grâce au code donné précédemment, tu pourras t'en resservir partout dans le projet. Dans tous les modules, y compris le ThisWorkbook, les modules de feuilles, standards, partout quoi...

3- Non, intégrer un calendrier n'est pas très compliqué. Tu en trouves de très bien fait sur le net qui ne demandent que l'insertion d'un module de classe.
Si tu le souhaites, je peux tenter de t'en trouver un.
0
Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019 61
25 sept. 2015 à 14:29
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.
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > Kuartz Messages postés 850 Date d'inscription vendredi 13 février 2015 Statut Membre Dernière intervention 15 février 2019
Modifié par pijaku le 25/09/2015 à 14:51
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é...
0