VBA – Evénementielle lancée depuis macros personnelles

DoubleZero

XLDnaute Barbatruc
Bonjour à toutes et à tous,

Dans les macros personnelles, j’ai, à titre d’exemple, ce code :

Code:
Sub Aujourdhui()
Selection.Value = Date
End Sub

Depuis un bouton logé en « barre d’outils Accès rapide… », je souhaiterais pouvoir rendre cette macro événementielle, par double clic, dans n’importe quel onglet d’un fichier existant ou nouveau.

Je vous remercie vivement pour votre aide.

A bientôt :)
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonsoir.
À essayer dans le ThisWorkbook d'un classeur de macros, si j'ai bien compris :
VB:
Option Explicit
Dim WithEvents Excel As Application

Private Sub Workbook_Open()
Set Excel = Application
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Set Excel = Nothing
End Sub

Private Sub Excel_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Target.Value = Date
Cancel = True
End Sub
Bonjour.
Précision : Un bouton pourrait sans doute provoquer l'ouverture de ce classeur contenant ça dans son module ThisWorkbook. Cela instaurerait cette règle pour tout le temps où il restera ouvert : Un double clic dans n'importe quelle cellule de n'importe quel classeur y installe la date du jour.
(Voir dans l'aide l'évènement SheetBeforeDoubleClick. On y voit qu'il peut être décrété soit par l'objet ThisWorkbook, uniquement pour son classeur, soit par l'objet Application, pour tous les classeurs. Dans mon exemple c'est par Application, bien qu'il soit instauré dans un ThisWorkbook)
Si ce n'est pas tout à fait ce qui est souhaité, il pourrait ne plus y avoir de bon prétexte à mettre ça dans un module ThisWorbook. À savoir alors: le mot clé WithEvents n'est pas supporté dans un module ordinaire. Mais partout ailleurs, si: un Userform, un module de feuille et bien sûr un module de classe.
 
Dernière édition:

DoubleZero

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

[FONT=&amp]Bonjour à toutes et à tous,[/FONT]

[FONT=&amp]Un très grand merci, Dranreb :D, pour ce superbe travail qui, s'il ne correspond pas à mon souhait, a déjà sa place dans mon coffre aux trésors.[/FONT]

[FONT=&amp]Ma demande en #1 doit être mal formulée :eek:.[/FONT]

[FONT=&amp]Comme précisé, j'ai des macros personnelles (dans "PERSONAL.XSLB").[/FONT]

[FONT=&amp]Pour le fichier, existant ou nouveau, sur lequel je travaille, j'aimerais, à partir de boutons situés en « barre d’outils Accès rapide… », transformer certaines macros "Sub..." en "Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)" ou bien en "Private Sub Worksheet_SelectionChange(ByVal Target As Range)".[/FONT]

[FONT=&amp]Afin d’illustrer mes propos…[/FONT]

[FONT=&amp]Exemple 1 :[/FONT]

Code:
Sub Aujourdhui()
With Selection
.Value = Date
.Offset(, 1) = Time
End With
End Sub

[FONT=&amp]Résultat attendu 1 :[/FONT]


Code:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
With Selection
.Value = Date
.Offset(, 1) = Time
End With
End Sub

[FONT=&amp]Exemple 2 :[/FONT]


Code:
Sub Mois_insérer()
[a1] = "Janvier"
[a2] = "Février"
[a3] = "Mars"
[a4] = "Avril"
[a5] = "Mai"
[a6] = "Juin"
[a7] = "Juillet"
[a8] = "Août"
[a9] = "Septembre"
[a10] = "Octobre"
[a11] = "Novembre"
[a12] = "Décembre"
End Sub

[FONT=&amp]Résultat attendu 2 :[/FONT]


Code:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
[a1] = "Janvier"
[a2] = "Février"
[a3] = "Mars"
[a4] = "Avril"
[a5] = "Mai"
[a6] = "Juin"
[a7] = "Juillet"
[a8] = "Août"
[a9] = "Septembre"
[a10] = "Octobre"
[a11] = "Novembre"
[a12] = "Décembre"
End Sub

[FONT=&amp]La faisabilité de mon objectif n’est pas vitale :rolleyes: et, quoi qu’il en soit, je vous remercie chaleureusement pour votre aide.[/FONT]

A bientôt :):)
 

Pièces jointes

  • 00 - Evénementielle lancée depuis macros personnelles.xls
    55 KB · Affichages: 52

Dranreb

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Dans ce cas il convient de manipuler les objets définis par la référence "Microsoft Visual Basic for Apllications Extensibility 5.3"
Retrouvé ça dont j'avais presque oublié l'existence. À adapter donc.
VB:
Sub RemplacerLignesVBC(Module As String, ZC As String, ByVal RgZ As Range, Optional ByVal N As Long = 0)
Dim V As Variant, Z As String, ZAct As String, L As Long, C As Long, Lf As Long, Cf As Long, Sh As Shape
V = RgZ.Value: Z = ""
If IsArray(V) Then
   For L = 1 To UBound(V, 1): Z = Z & IIf(Z <> "", vbLf, "") & V(L, 1): Next L
Else
   Z = V: End If
If N = 0 Then
   C = InStr(Z, vbLf): If C = 0 Then C = Len(Z) + 1
   While C > 0: N = N + 1: C = InStr(C + 1, Z, vbLf): Wend
   N = N + 1 'intervalles lignes + 1
   End If
L = 1: C = 1: Lf = -1: Cf = -1
With ActiveWorkbook.VBProject.VBComponents(Module).CodeModule
   If .Find(ZC, L, C, Lf, Cf) Then
      ZAct = Replace(.Lines(L, N), vbCrLf, vbLf)
      If ZAct = Z Then MsgBox "Le code actuel est déjà celui-ci.", _
         vbInformation, "Visual Basic for Application": Exit Sub
      Set Sh = ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 10, _
         Rows(ActiveWindow.ScrollRow).Top + 10, 10, 10)
      Sh.Fill.ForeColor.RGB = RGB(0, 0, 194)
      With Sh.TextFrame.Characters.Font: .Name = "Consolas": .FontStyle = "Gras": .Size = 12: .ColorIndex = 2: End With
      For C = 1 To Len(ZAct) Step 255
         Sh.TextFrame.Characters(C).Insert Mid$(ZAct, C, 255): Next C
      Sh.TextFrame.AutoSize = True
      For C = 1 To Max(Len(Z), Len(ZAct))
         If Mid$(Z, C, 1) <> Mid$(ZAct, C, 1) Then Exit For
         Next C
      If MsgBox("Le code actuel est différent à partir du " & C & "ième caractère :" _
         & vbLf & """" & Replace(Mid$(ZAct, C, 40), vbLf, "{Lf}") & "…"" à remplacer par :" _
         & vbLf & """" & Replace(Mid$(Z, C, 40), vbLf, "{Lf}") & "…""" _
         & vbLf & "Confirmez le remplacement de ce code.", _
         vbOKCancel + vbInformation, "Visual Basic for Application") = vbOK Then
         C = 1
         Do
            Cf = InStr(C, Z, vbLf): If Cf = 0 Then Cf = Len(Z) + 1
            If N > 0 Then .ReplaceLine L, Mid$(Z, C, Cf - C) Else .InsertLines L, Mid$(Z, C, Cf - C)
            L = L + 1: N = N - 1: C = Cf + 1: Loop Until C > Len(Z)
         End If
      Sh.Delete
   Else
      MsgBox """" & ZC & """ n'a pas été trouvé dans le module """ & Module & """.", _
         vbCritical, "Visual Basic for Application"
      End If
   End With
End Sub
 

DoubleZero

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonjour à toutes et à tous,

A nouveau un très grand merci, Dranreb :D, pour ces lignes de code.

Je souhaiterais vous poser la question suivante : avez-vous vu « ma photo » :eek: ?

Il faut savoir que je n’ai pas seulement l’apparence :rolleyes: d’un âne… j’ai, également, les caractéristiques qu’on lui réserve :(.

Par conséquent, je suis bien incapable de trouver où placer le code, lancer son exécution et l’adapter à mon besoin.

Mais, comme déjà mentionné hier, à 19h49, la faisabilité de mon objectif n’est pas vitale :).

A bientôt :):)
 

job75

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonjour chère ânesse, salut Bernard,

Mets ces 2 macro dans le "Module1" de "PERSONAL.XSLB" :

Code:
Sub CréerMacro()
'adapter les paramètres MacroCopiée, MacroDestination, lig1, lig2
Dim MacroCopiée$, MacroDestination$, lig1$, lig2$, t$
MacroCopiée = "Aujourdhui"
MacroDestination = "Worksheet_BeforeDoubleClick"
lig1 = "Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As boolean)"
lig2 = "Cancel = True"
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
  On Error Resume Next
  .DeleteLines .ProcBodyLine(MacroDestination, 0), .ProcCountLines(MacroDestination, 0)
  On Error GoTo 0
  With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule '"Module1" à adapter
    t = .Lines(.ProcBodyLine(MacroCopiée, 0), .ProcCountLines(MacroCopiée, 0))
  End With
  .AddFromString t
  .InsertLines .ProcBodyLine(MacroCopiée, 0) + 1, lig1
  .InsertLines .ProcBodyLine(MacroCopiée, 0) + 2, lig2
  .DeleteLines .ProcBodyLine(MacroCopiée, 0), 1
End With
End Sub

Sub Aujourdhui()
With Selection
.Value = Date
.Offset(, 1) = Time
End With
End Sub
On peut la lancer la macro CréerMacro telle quelle.

On peut aussi la paramétrer avec les paramètres MacroCopiée, MacroDestination, lig1, lig2.

A+
 

Dranreb

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonjour.
C'est auto jugement est certes très humble mais très pessimiste et sûrement très exagéré. Mais le peu qu'il exagère ne saurait, il me semble, rester définitif, ce serait une question d'amour propre.
￾Écrit ça dans un nouveau module Module1:
VB:
Option Explicit

Sub Toto()
MsgBox "Youpi"
End Sub

Sub EssRempCode()
RemplacerLignesVBC "Module1", "Sub Toto()", ActiveSheet.[A1], 1
End Sub
Mis en cellule A1: "Sub Tata()" (oui parce que j'avais écrit cette procédure pour remplacer surtout des valeurs dans des instructions Const calculées à une époque, dans une phase de recherche, et mes instructions Const étaient fabriquées par concaténation dans des cellules).
Après exécution de EssRempCode, "Sub Toto" y est remplacé par "Sub Tata" dans Module1.
 
Dernière édition:

job75

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Re,

J'ai un peu bataillé avec les ProcBodyLine et ProcStartLine... Ceci est mieux :

Code:
Sub CréerMacro()
'adapter les paramètres MacroCopiée, MacroDestination, lig1, lig2
Dim MacroCopiée$, MacroDestination$, lig1$, lig2$, t$
MacroCopiée = "Aujourdhui"
MacroDestination = "Worksheet_BeforeDoubleClick"
lig1 = "Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)"
lig2 = "Cancel = True"
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
  On Error Resume Next
  .DeleteLines .ProcStartLine(MacroDestination, 0), .ProcCountLines(MacroDestination, 0)
  On Error GoTo 0
  With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule '"Module1" à adapter
    t = .Lines(.ProcStartLine(MacroCopiée, 0), .ProcCountLines(MacroCopiée, 0))
  End With
  .AddFromString t
  .InsertLines .ProcBodyLine(MacroCopiée, 0) + 1, lig1
  If lig2 <> "" Then .InsertLines .ProcBodyLine(MacroCopiée, 0) + 2, lig2
  .DeleteLines .ProcBodyLine(MacroCopiée, 0), 1
End With
End Sub

Sub Aujourdhui()
With Selection
.Value = Date
.Offset(, 1) = Time
End With
End Sub
Précision supplémentaire, affecter au bouton logé en « barre d’outils Accès rapide…» la macro CréerMacro ou lui affecter une macro qui appelle cette macro si elle est paramétrée.

Edit : ajouté If lig2 <> "" Then au cas où ligne2 = "" (pas de 2ème ligne insérée).

A+
 
Dernière édition:

job75

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Re,

Bien entendu pour l'exemple 2 du post #4 modifier comme suit :

Code:
Sub CréerMacro()
'adapter les paramètres MacroCopiée, MacroDestination, lig1, lig2
Dim MacroCopiée$, MacroDestination$, lig1$, lig2$, t$
MacroCopiée = "Mois_insérer"
MacroDestination = "Worksheet_BeforeRightClick"
lig1 = "Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As boolean)"
lig2 = "Cancel = True"
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
  On Error Resume Next
  .DeleteLines .ProcStartLine(MacroDestination, 0), .ProcCountLines(MacroDestination, 0)
  On Error GoTo 0
  With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule '"Module1" à adapter
    t = .Lines(.ProcStartLine(MacroCopiée, 0), .ProcCountLines(MacroCopiée, 0))
  End With
  .AddFromString t
  .InsertLines .ProcBodyLine(MacroCopiée, 0) + 1, lig1
  If lig2 <> "" Then .InsertLines .ProcBodyLine(MacroCopiée, 0) + 2, lig2
  .DeleteLines .ProcBodyLine(MacroCopiée, 0), 1
End With
End Sub

Sub Mois_insérer()
Dim i As Byte
For i = 1 To 12
Cells(i, 1) = Application.Proper(Format("1/" & i, "mmmm"))
Next
End Sub
A+
 

DoubleZero

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Re-bonjour, bonjour, job75 :D,

Un autre grand MERCI, Dranreb :D, pour la patience déployée afin de m'aider.

Un grand MERCI, job75 :D, de répondre également "présent" à mon appel.

Je ne manquerai pas de vous faire connaître, au plus vite, les résultats obtenus.

A bientôt :D:)
 

job75

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Re DoubleZero,

Je pense que tu le sais bien mais je rappelle quand même que sur Excel 2007/2010 il faut avoir coché l'option Accès approuvé au modèle d'objet du projet VBA (onglet Fichier-Options-Centre de gestion de la confidentialité-Paramètres...-Paramètres des macros).

A+
 

DoubleZero

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonjour, Dranreb, job75, le Forum,

Mes essais d'hier n'étant pas concluants, j'ai tout recommencé ce matin et... de bourrique, je vais passer à chèvre :rolleyes: !

@ job75 :) :


Le code déposé en #7 provoque cette erreur :

"Erreur d'exécution '9' :
L'indice n'appartient pas à la sélection."

Cette ligne est surlignée :

attachment.php


Cependant…

- lancé une seconde fois, plus aucun message n’apparaît et le double clic fonctionne parfaitement ;

- lancé une troisième fois depuis un nouvel onglet du même fichier, l’erreur réapparaît pour disparaître après un quatrième appel de macro.

En résumé, la macro doit être lancée, systématiquement, à deux reprises avant d’être opérationnelle.

Les codes déposés en #9 et #10 présentent les mêmes symptômes…

...Mets ces 2 macro dans le "Module1" de "PERSONAL.XSLB"...

Non : elles sont ici :D :

attachment.php


Je te remercie "beaucoup très fort" d’avoir allégé le code du clic droit (Exemple 2, déposé en #4).

@ Dranreb :) :

...Écrit ça dans un nouveau module Module1...

Non : c'est là :D :

attachment.php


Je ne sais pas comment procéder afin de rendre opérationnel le code déposé en #8.

L’appel de la macro « Toto » fonctionne mais l’appel de la macro « EssRempCode » m’adresse cette erreur et l'onglet dans lequel je me trouve ne comporte aucune événementielle.

attachment.php



Job75 et Dranreb, je vous renouvelle mes chaleureux remerciements :eek:.

A bientôt :):)
 

Pièces jointes

  • job75 - N° 7 (12h51) - Module - Copie.JPG
    job75 - N° 7 (12h51) - Module - Copie.JPG
    10.9 KB · Affichages: 155
  • Dranreb - N° 8 - Module - Copie.JPG
    Dranreb - N° 8 - Module - Copie.JPG
    11 KB · Affichages: 161
  • Dranreb - N° 8 (12h56) - Copie.JPG
    Dranreb - N° 8 (12h56) - Copie.JPG
    44.2 KB · Affichages: 169
  • job75 - N° 7 (12h51) bis - Copie.JPG
    job75 - N° 7 (12h51) bis - Copie.JPG
    19.5 KB · Affichages: 164
Dernière édition:

job75

XLDnaute Barbatruc
Re : VBA – Evénementielle lancée depuis macros personnelles

Bonjour DoubleZero :)

Tu nous remercies c'est gentil mais si ça beugue chez toi il faut y porter remède !!

J'ai testé sans problème ma solution sur Excel 2003 et Excel 2010.

Je ne vois vraiment pas comment chez toi cette ligne peut produire un bug :

Code:
With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
Mais sur Excel 2007 il y a parfois des choses bizarres, alors essaie :

Code:
With ActiveWorkbook.VBProject.VBComponents(ActiveWorkbook.ActiveSheet.CodeName).CodeModule
Par ailleurs je n'ai pas vraiment compris où tu places tes macros.

Dépose donc le fichier avec les macros et celui où tu veux créer la macro événementielle.

A+
 

Statistiques des forums

Discussions
312 839
Messages
2 092 678
Membres
105 508
dernier inscrit
Albator