Modification macro dans bouton VBA à grande échelle de façon neutre
Boujour à tous,
Je suis confronté depuis quelques jours à un problème que je n'arrive pas du tout à régler même avec l'IA.
Je dois modifier des macro dans des boutons VBA pour un grand nombre de fichiers (<300) pour ce faire j'ai écrit le code que vous pouvez trouver ci-joint. Le problème est que la macro à insérer dans mon bouton est un fichier ".xlam", qui est dans mon C:\....\appdata\roaming\microsoft\addin. Ce qui se passe est que lorsque je change le nom de ma macro mon bouton va chercher le lien dans mon "C", toutefois je souhaiterais que d'autre collègue puisse utiliser ces boutons.
Pour essayer de résumé, je voudrais trouver comment migrer le nom de bouton VBA de manière neutre, c'est à dire en désactivant mon AddIn. Ex : le bouton sera renomme "
nomprojetVBA.module.programme" sans attache à un fichier particulier.
Merci d'avance pour votre aide !!
Public Sub NettoyerEtMigrerBoutons()
Const ADDIN_FULL As String = "nomprojetVBA.module.programme"
Const ADDIN_SUPP As String = "nomprojetVBA.module.programme"
Const ADDIN_RENOM As String = "nomprojetVBA.module.programme"
Dim fd As FileDialog
Dim f As Variant
Dim wb As Workbook, Migration_bouton As Workbook
Dim ws As Worksheet, wsPres As Worksheet
Dim shp As Shape, btn As Button
Dim logRow As Long
Dim nbErr As Long
Dim i As Long
Dim c As Range
Dim modificationFaite As Boolean
On Error GoTo ErreurFichier
Set Migration_bouton = ThisWorkbook
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = True
.Filters.Clear
.Filters.Add "Fichiers Excel", "*.xlsm;*.xlsb;*.xlsx"
.Title = "Sélectionnez les fichiers des collègues à réparer"
If .Show <> -1 Then Exit Sub
End With
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
For Each f In fd.SelectedItems
Set wb = Nothing
modificationFaite = False
'--- Ouverture fichier
Set wb = Workbooks.Open(f, UpdateLinks:=0, ReadOnly:=False)
Application.EnableEvents = True
DoEvents
Application.EnableEvents = False
For Each ws In wb.Worksheets
For i = ws.Shapes.Count To 1 Step -1
Set shp = ws.Shapes(i)
If shp.OnAction <> "" Then
'--- 1. Détection et nettoyage du bouton SUPPRIMER FEUILLE
If InStr(1, shp.OnAction, "supprimer_feuille", vbTextCompare) > 0 Then
shp.OnAction = ADDIN_SUPP
modificationFaite = True
End If
'--- 2. Détection et nettoyage du bouton BOUTON4 / TOUT
If InStr(1, shp.OnAction, "bouton4_cliquer", vbTextCompare) > 0 _
Or InStr(1, shp.OnAction, "Tout", vbTextCompare) > 0 Then
shp.OnAction = ADDIN_FULL
modificationFaite = True
End If
'--- 3. Nettoyage de l'ancien bouton obsolète si présent
If InStr(1, shp.OnAction, "Enregistrer_Excel", vbTextCompare) > 0 Then
shp.Delete
modificationFaite = True
End If
End If
Next i
Next ws
On Error Resume Next
wb.RemovePersonalInformation = False
' Si des modifications ont été apportées, on force la sauvegarde, sinon on ferme juste
If modificationFaite Then
wb.Close SaveChanges:=True
Else
wb.Close SaveChanges:=False
End If
On Error GoTo 0
GoTo FichierSuivant
ErreurFichier:
nbErr = nbErr + 1
If Not wb Is Nothing Then wb.Close SaveChanges:=False
On Error GoTo 0
FichierSuivant:
Next f
'======================
' RESTAURATION EXCEL
'======================
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
MsgBox "Nettoyage terminés ! Erreurs : " & nbErr, vbInformation
End SubBonsoir,
si vous copiez/collez le code dans votre fichier (via insertion, module dans la partie VBA), il y sera intégré, donc plus besoin d'aller le chercher ailleurs.
Bonjour,
Effectivement, comme dit par Doux rêveur, si vous souhaitez vous affranchir de la dépendance à l'addin XLAM, il faut d'une manière ou d'une autre transférer le code de l'addin dans le classeur en question. (si j'ai bien compris le problème).
Dans la mesure du possible il faudrait mieux simplement rediffuser un fichier "propre".
Sinon il faut donner il me semble "l'accès approuvé au model d'objet VBA" (autorisation élevée) pour pouvoir manipuler le code VBA et les objets (modules/classes etc) depuis le VBA lui-même.
... a voir donc selon moi il faudrait d'abord réexpliquer votre besoin.
Bonjour,
Je pense avoir très mal expliqué effectivement.
J'ai un fichier ".xlam" que j'ai transmis à l'ensemble de mes collègues, ils ont tous enregistré le fichier dans leur "C:\....\appdata\roaming\microsoft\addin" et l'on ajouté dans les compléments (coché).
Les macro du ".xlam" doivent être associé à des boutons déjà créer dans un grand nombre de fichier. (remplacement des macros dans les boutons : "NomFeuilleduBouton!macro" par "Nomprojetxlam.module.macro"). Le problème est que j'effectue la migration, ainsi au lieu que les boutons récupèrent "Nomprojetxlam.module.macro" (ce que j'arrive à lire dans les boutons) , ils associent automatiquement mon lien "C:\....\appdata\roaming\microsoft\addin".(ce que mes collègues lisent dans leurs boutons).
Si j'essai de faire comme vous dîtes, c'est à dire de couper le lien vers le AddIn quand je fais ma migration on déplaçant le code dans un autre module, Excel va essayer de lié le bouton à ma feuille de migration "'Feuillemigration!nouveaunommodule.macro" ainsi si la feuille de migration est fermé personne ne peux utiliser les macro.
Ainsi, j'aurais aimé savoir si il était possible d'écrire un "shp.Oneaction" sans lien ni vers la feuille de migration ni vers mon "C". Je sais qu'une des solutions serait que chaque collègue fasse la migration de son côté mais pour nous ce n'est pas possible car trop complexe.
Je vous remercie pour votre aide et de m'avoir répondu rapidement, en espérant avoir apporter plus de précision.
Ah oui c'est plus clair, je pense avoir compris votre soucis.
Mais ça me surprend, moi quand j'affecte (une macro à moi) :
selection.onaction = "PERSONAL.XLSB!RibbonMacros.OpenFileSafely"à une shape, ça garde bien ce chemin pour la macro, ça ne remplace pas par l'adresse de mon classeur PERSONAL... Si vous pouviez partager un fichier avec une shape et un onaction lié à votre xlam que l'on voit si le problème est bien là ? merci
Voici ce que j'obtiens quand je migre le nom de mes boutons avec "shp.Oneaction = "nomprojetVBA.module.programme"", mais quand mes collègues essaient de leurs côté ils ont ce lien dans le nom de la macro : "C:\....\appdata\roaming\microsoft\addin".
Ce que j'obtiens quand je copie la macro dans un nouveau module dans ma feuille de migration
Et vous ne voulez pas rajouter la macro dans un module du fichier et envoyer ce fichier à vos collègues ? Alors ils n'auraient plus besoin du module externe.
Hum intéressant, c'est vraiment lors du transfert de fichier que cela change. Bon je ne peux pas tester de mon côté.
Une solution à laquelle je pense est de passer par Application.Run "chemin de la commande". Ainsi c'est écrit "en dur" dans une string et Excel n'utilisera pas de référence inconnue.
Donc la solution, en gros serait celle-ci :
Actuellement, vous avez vos boutons avec
shp.OnAction = "cheminMacro"Sauf que cheminMacro est changé automatiquement lors du transfert de classeur. Il faudrait plutôt procéder ainsi :
On crée dans le classeur une fonction d'exécution locale, par exemple
Public Sub LancerMaMacro()
Application.Run "nomprojetVBA.module.programme" ' ex: Application.Run "monAddin.xlam!module.OpenFileSafely"
End SubPuis au bouton on affecte la macro locale LancerMaMacro et non plus la référence au xlam, comme c'est local le chemin ne casse pas.
shp.OnAction = "LancerMaMacro"