Re coucou à toutes et tous,
Pas de signe de vie depuis août, je reviens néanmoins vers vous avec, comme toujours, avec un problème qui est au delà de mes compétences et connaissances en langage VBA
Situation :
J'ai un fichier Macro_Goliath.xlam qui regroupe la totalité de mes macros. Les macros sont inscrites dans des modules, avec public sub. J'ai également une macro inscrite dans le thsiworkbook(avec Private Sub Workbook_SheetActivate). Cette macro a pour fonction de copier des données d'une feuille à l'autre.
J'ai un fichier "Goliath.xlsm" qui en s'ouvrant, charge (à l'aide d'un code VBA) les macros contenues dans le fichier "Macro_Goliath.xlam". Je peux donc les utiliser sans problème. Par contre, la macro contenue dans le thisworkbook (avec Private Sub Workbook_SheetActivate) de Macro_Goliath.xlam ne s'actionne pas quand j'ouvre mon fichier Goliath.xlsm.
Ma question :
Comment puis-faire pour actionner la macro SheetActivate de thisworkbook dans le Macro_Goliath.xlam lorsque que j'ouvre le fichier Goliath.xlsm sans inscrire de code vba dans le fichier goliath.xlsm (C'est très important) ?
Fichiers sources :
Voici mes deux fichiers afin de clarifier mes propos.
En fouillant sur le net pour trouver comment afficher mes macros, je suis tombé sur cette possibilité. Le problème est que en cochant la référence, les macros et l'onglet créé se charge lorsque j'ouvre n'importe quel fichier excel. Or je voudrais que mes macro et l'onglet créé s'ouvre uniquement avec le le fichier Goliath.xlsm
Re : Problème d'ouverture d'une macro complémentaire .xlam
Bonjour.
Le seul moyen de prendre en charge dans un projet VBA l'activation de feuilles d'autres classeurs que celui qui le porte est de déclarer WithEvents une variable As Application dans un module objet, l'initialiser aussi = Application par un Set.
Vous pouvez alors implanter des procédures pour gérer les évènements de cet objet au niveau Excel global.
Accessoirement vous auriez intérêt à renommer le projet VBA du Macro_Goliath.xlam. Il s'appelle toujours encore VBAProject au lieu de, à mon avis, Goliath par exemple. Ça vous permettrait entre autre de l'ajouter comme référence VBA, cette fois, à d'autres classeurs, pour qu'il se charge sans avoir de code à exécuter.
Re : Problème d'ouverture d'une macro complémentaire .xlam
Bonjour Albatros86, JM, Bernard,
Pas trop compris ce que veut dire Dranreb...
Perso dans le fichier .xlam :
1) je créerais un Module de classe nommé Classe1 où je placerais ce code :
Code:
Public WithEvents WB As Workbook
Private Sub WB_SheetActivate(ByVal Sh As Object)
If WB.Name = "Goliath.xlsm" Then
MsgBox "Bonjour Albatros86, le forum !" 'pour tester
'---suite du code---
End If
End Sub
2) je mettrais dans son ThisWorkbook, pour initialiser la classe :
Code:
Dim WB() As New Classe1
Private Sub Workbook_Open()
Dim i%
ReDim WB(Workbooks.Count)
For i = 1 To Workbooks.Count
Set WB(i).WB = Workbooks(i)
Next
End Sub
Edit : la macro complémentaire doit être chargée seulement quand le fichier "Goliath.xlsm" s'ouvre.
De manière que ce fichier soit bien dans la classe créée.
Re : Problème d'ouverture d'une macro complémentaire .xlam
Re,
On peut faire charger le fichier .xlam en tant que macro complémentaire à l'ouverture d'Excel.
Alors cela nécessite une petite gymnastique.
Placez dans le ThisWorkbook du fichier .xlam :
Code:
Dim WB() As New Classe1
Private Sub Workbook_Open()
'temporisation de 5 secondes pour permettre l'ouverture d'un classeur
Application.OnTime Now + 5 / 86400, "ThisWorkbook.InitClasse"
End Sub
Sub InitClasse()
Dim i%
ReDim WB(Workbooks.Count)
For i = 1 To Workbooks.Count
Set WB(i).WB = Workbooks(i)
Next
End Sub
Placez dans son Module de classe :
Code:
Public WithEvents WB As Workbook
Private Sub WB_DeActivate()
ThisWorkbook.InitClasse
End Sub
Private Sub WB_SheetActivate(ByVal Sh As Object)
If WB.Name = "Goliath.xlsm" Then
MsgBox "Bonjour Albatros86, le forum !" 'pour tester
'---suite du code---
End If
End Sub
Re : Problème d'ouverture d'une macro complémentaire .xlam
Re,
Je n'aimais pas du tout cette temporisation de 5 secondes.
Dans ce qui suit j'utilise un document (très) provisoire vierge.
Placez dans le ThisWorkbook du fichier .xlam :
Code:
Private Sub Workbook_Open()
Set DocumentVierge = Workbooks.Add
InitClasse
End Sub
Placez dans un Module standard de ce même fichier :
Code:
Public DocumentVierge As Workbook, WB() As New Classe1 'mémorisation
Sub InitClasse()
Dim i%
ReDim WB(Workbooks.Count)
For i = 1 To Workbooks.Count
Set WB(i).WB = Workbooks(i)
Next
End Sub
Placez dans son Module de classe :
Code:
Public WithEvents WB As Workbook
Private Sub WB_DeActivate()
InitClasse
End Sub
Private Sub WB_Activate()
On Error Resume Next
DocumentVierge.Close False 'on s'en débarrasse...
End Sub
Private Sub WB_SheetActivate(ByVal Sh As Object)
If WB.Name = "Goliath.xlsm" Then
MsgBox "Bonjour Albatros86, le forum !" 'pour tester
'---suite du code---
End If
End Sub
Edit : j'insiste : la macro complémentaire est chargée à l'ouverture d'Excel comme vous l'indiquez au post #5.
Si vous chargez cette macro à l'ouverture du fichier "Goliath.xlsm", utilisez les macros de mon post #7.
À quel sujet ? Quoi qu'il en soit la solution d'un With Events … As Workbook, auquel je n'avais pas pensé, est peut être mieux adapté au besoin du demandeur qu'un With Events … As Application, s'il n'a qu'un seul classeur à piloter avec le .xlam car il ne ciblera ainsi que les évènements de ce classeur là et pas des autres, évitant donc d'avoir à vérifier si les activations de feuille et autres le concernent bien.
Re : Problème d'ouverture d'une macro complémentaire .xlam
Merci pour vos réponses. Je ne les ai pas encore étudiées, essayées. Je le ferai demain.
Néanmoins, j'ai réfléchis à ne solution alternative de dernier recours, sans utiliser de macro complémentaire. Une solution qui permettrai par la même occasion d'avoir plusieurs fichiers goliath.xlsm, utilisé sur des postes différents, au sein d'un même serveur. L'idée d'être plusieurs à utiliser son fichier goliath est nouvelle et permettrai une répartition efficace dans la saisie de données.
Dans un fichier A j'inscris toutes mes macros. Je les exporte, via une macro comme celle-ci dessous :
Code:
Sub ExporterFrmEtModules()
Dim LeFich
For Each LeFich In ThisWorkbook.VBProject.VBComponents
Select Case LeFich.Type
Case 1
ThisWorkbook.VBProject.VBComponents(LeFich.Name).Export "D:\MesMacros\" & LeFich.Name & ".bas"
Case 2
ThisWorkbook.VBProject.VBComponents(LeFich.Name).Export "D:\MesMacros\" & LeFich.Name & ".cls"
Case 3
ThisWorkbook.VBProject.VBComponents(LeFich.Name).Export "D:\MesMacros\" & LeFich.Name & ".frm"
Case 100
ThisWorkbook.VBProject.VBComponents(LeFich.Name).Export "D:\MesMacros\LesFeuilles\" & LeFich.Name & ".cls"
End Select
Next
End Sub
Ce qui me crée des fichiers dans le dossier désiré. Puis, via mon fichier excel B, en l'occurence Goliath.xlsm j'importe les macro via ce code :
Code:
Sub ImporterTousLesFichiersDunRépertoire() '"d'après" SilkyRoad
Dim NomFich
NomFich = Dir("D:\MesMacros\*.*")
Do While NomFich <> ""
Application.VBE.ActiveVBProject.VBComponents.Import (NomFich)
NomFich = Dir
Loop
End Sub
Les codes ne sont pas de moi.
Cette solution pourrais convenir dans le sens où nous pourrions être plusieurs à utiliser le fichier de base goliath.xlsm, en le personnalisant avec nos données propres, tout en ayant les mêmes fonctionnalités via les macros. Cette méthode me permettrait aussi d'ajouter, modifier ou supprimer des macros, et chaque fichier goliath.xlsm chargerai à son ouverture les nouvelles macros en supprimant les dernières. LE désavantage de cette méthode est qu'à chaque ouverture le fichier supprime les anciennes macros et installe les nouvelles macros (je ne sais pas quel serait la perte de temps lors de l'ouverture).
Néanmoins, je vais étudier attentivement vos solutions, tout en adaptant à cette nouvelle donnée : plusieurs fichiers goliath.xlsm, avec les même macro, avec plusieurs utilisateurs sur un même réseau.
Et je vous remercie sincèrement pour votre attention et vos propositions.
Re : Problème d'ouverture d'une macro complémentaire .xlam
Ça me parait plutôt lourd. Voyez aussi ce qu'apporterait de renommer VBAProject en Goliath dans le classeur de macros. Ainsi du fait qu'il ne porterait plus le même nom que les projets des fichiers de données, il y apparaîtrait dans la liste Références disponibles, menu Outils, Référence de VBA et pourrait être coché.
Je pense qu'un objet Workbook ou Application pourrait être déclaré WithEvents dans le module ThisWorkbook du classeur de macros.
Il n'y pas de raison que ça ne marche pas du moment que c'est bien un module objet au même titre qu'un module de classe.
J'utilise quelquefois un objet Application dans des Userform, et ça marche très bien.
Ça me parait plutôt lourd. Voyez aussi ce qu'apporterait de renommer VBAProject en Goliath dans le classeur de macros. Ainsi du fait qu'il ne porterait plus le même nom que les projets des fichiers de données, il y apparaîtrait dans la liste Références disponibles, menu Outils, Référence de VBA et pourrait être coché.
2) je mettrais dans son ThisWorkbook, pour initialiser la classe :
Code:
Dim WB() As New Classe1
Private Sub Workbook_Open()
Dim i%
ReDim WB(Workbooks.Count)
For i = 1 To Workbooks.Count
Set WB(i).WB = Workbooks(i)
Next
End Sub
Edit : la macro complémentaire doit être chargée seulement quand le fichier "Goliath.xlsm" s'ouvre.
De manière que ce fichier soit bien dans la classe créée.
Quand j'essaie cette méthode, excel m'informe à l'ouverture du fichier goliath.xlsm une erreur 404. Objet requis et dans mon éditeur VBa il souligne la ligne suivante : Set WB(i).WB = Workbooks(i)
Une idée ?
EDIT : J'ai par contre tenté la solution qui propose de retarder de 5 secondes l'activation du code.
Code:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Application.OnTime Now() + (TimeValue("00:00:02")) / 20, "ThisWorkbook.Copier"
End Sub
Et là miracle, la macro se lance à l'ouverture. Donc visiblement mes macros de thisworkbook de Macro_Goliath.xlam se lance avant l'ouverture du fichier Goliath.xlsm. Comment faire pour que l'ensemble de mes macros complémentaires se lance après l'ouverture de Goliath.xlsm (histoire de pouvoir utiliser les sheetactivate).
EDIT 2 :
J'ai tenté de renommer aussi le vbaproject de Macro_Goliath comme proposé dans un poste précédent. Il n'y a eu aucun changement
Merci pour toutes les pistes que vous me permettez de tester...
Re : Problème d'ouverture d'une macro complémentaire .xlam
Je confirme que cet exemple de code placé dans ThisWorkbook du classeur de macros est opérationnel :
VB:
Dim WithEvents Excel As Application
Private Sub Workbook_Open()
Set Excel = Application
End Sub
Private Sub Excel_WorkbookActivate(ByVal Wb As Workbook)
MsgBox Wb.Name, vbInformation, "Test"
End Sub
Il y aurait un changement si, dans le projet VBA du classeur de données, vous cochiez le nouveau nom dans la liste références disponibles, menu Outils, Références… Le changement c'est que le classeur de macro s'ouvrirait en l'absence de tout code dans celui de données. Par contre je ne sais pas s'il exécuterait dans la foulée une Excel_WorkbookOpen pour le classeur de données qui aura nécessité son chargement. Mais si ce n'est pas la cas, on pourrait y remédier pour cette première fois exceptionnelle dans la Workbook_Open en y appelant Excel_WorkbookOpen ActiveWorkbook.