Oui, vous pouvez le faire. Vous pouvez accéder au projet VBA de tout document en utilisant:
Application.VBE.ActiveVBProject.VBComponents
Votre projet doit avoir une référence à « Microsoft Visual Basic pour Applications Extensibilité ».
Pour exécuter le code, vous devez activer l'option "Faire confiance au projet Visual Basic" dans Word, en utilisant
Outils-> Macro-> (onglet Trusted Publishers) Sécurité
La collection VBComponents
contient tous les modules standard, modules de classe, formulaires et modules "document" que contient le projet. Si vous l'utilisez sur Google, vous trouverez de nombreuses informations sur la façon d'y accéder/de les modifier.
EDIT: OK, un peu plus de détails. Cette méthode va rechercher tous les VbComponents
d'un document à la recherche d'une méthode avec le nom spécifié, et effectuer une recherche/remplacement dans le premier qu'il trouve.
Public Sub ReplaceInProject(ByVal oDocument As Document, ByVal strMethodName As String, ByVal strFindText As String, ByVal strReplaceWithText As String)
' For each module (of any type - could use oVbComponent.Type to restrict
' this to certain types of module)
Dim oVbComponent As VBComponent
For Each oVbComponent In oDocument.VBProject.VBComponents
Dim oCodeModule As CodeModule
Set oCodeModule = oVbComponent.CodeModule
' See if we can find the method in this module
Dim ixStartLine As Long
ixStartLine = FindMethodStartLine(oCodeModule, strMethodName)
If ixStartLine > 0 Then
' Get all the text of the method
Dim numLines As Long
numLines = oCodeModule.ProcCountLines(strMethodName, vbext_pk_Proc)
Dim strLines As String
strLines = oCodeModule.Lines(ixStartLine, numLines)
' Do the find/replace
strLines = Replace(strLines, strFindText, strReplaceWithText)
' Replace the method text.
oCodeModule.DeleteLines ixStartLine, numLines
oCodeModule.InsertLines ixStartLine, strLines
End If
Next oVbComponent
End Sub
Private Function FindMethodStartLine(ByVal oCodeModule As CodeModule, ByVal strMethodName As String) As Long
FindMethodStartLine = 0
' ProcStartLine will raise an error if the method is not found;
' we'll just ignore the error and return -1
On Error Resume Next
FindMethodStartLine = oCodeModule.ProcStartLine(strMethodName, vbext_pk_Proc)
End Function
Notez que cela ne fonctionne qu'avec Sub
et Function
méthodes, pas la propriété Get/Set/Let
parce que je utilise vbext_pk_Proc
. C'est un PITA dont vous avez besoin d'être explicite à ce sujet. Franchement, l'ensemble de l'API pour le composant CodeModule
semble presque conçu pour frustrer. Par exemple, alors que l'objet VbComponent
a une méthode Find
(que vous pensiez être un moyen pratique de trouver le texte que vous recherchez), il renvoie en réalité True
ou False
(!). Utile, je ne pense pas!
Les concepteurs de cette API devaient avoir une très mauvaise gueule de bois quand ils l'ont fait.
Merci :) J'ai donc ajouté ceci à mon projet et importé Microsoft.Vbe.Interop, mais savez-vous comment charger une macro à partir d'un document Word dans une zone de texte dans mon projet Visual Studio? Puis éditez le texte et puis enregistrez-le à nouveau? Ou serait-il préférable de générer un fichier Word avec la macro, puis il suffit de copier la macro de ce document sur le prochain? –
Merci pour la mise à jour! Fonctionne très bien! :) –