2009-11-16 6 views
3

Je suis présenté avec un puzzle. Là où je travaille, il y a énormément de modèles Word qui contiennent tous un handle d'événement autonew qui contient quelques erreurs. Et cette erreur se trouve dans tous les modèles. Et je me demandais s'il y aurait un moyen d'analyser un répertoire pour les modèles qui contient cette macro et modifier le code de la macro légèrement?vba - numériser des documents pour la macro et remplacer le texte de macro?

Serait-ce possible?

Répondre

8

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.

+0

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? –

+0

Merci pour la mise à jour! Fonctionne très bien! :) –

Questions connexes