Extraia programaticamente macro (VBA) de código a partir do Word 2007 docs
-
09-06-2019 - |
Pergunta
É possível extrair todos do código VBA do Word 2007 "docm" documento usando a API?
Eu descobri como inserir o código do VBA em tempo de execução, e como eliminar todo o código VBA, mas não puxe o código real para uma transmissão em sequência ou cadeia de caracteres que posso armazenar (e inserir em outros documentos no futuro).
Quaisquer sugestões ou recursos seria apreciada.
Editar:obrigado a todos, Projetada's resposta foi exatamente o que eu estava procurando.Eu converti o seu código para C#, e foi capaz de chamá-lo a partir de uma biblioteca de classes usando o Visual Studio 2008.
using Microsoft.Office.Interop.Word;
using Microsoft.Vbe.Interop;
...
public List<string> GetMacrosFromDoc()
{
Document doc = GetWordDoc(@"C:\Temp\test.docm");
List<string> macros = new List<string>();
VBProject prj;
CodeModule code;
string composedFile;
prj = doc.VBProject;
foreach (VBComponent comp in prj.VBComponents)
{
code = comp.CodeModule;
// Put the name of the code module at the top
composedFile = comp.Name + Environment.NewLine;
// Loop through the (1-indexed) lines
for (int i = 0; i < code.CountOfLines; i++)
{
composedFile += code.get_Lines(i + 1, 1) + Environment.NewLine;
}
// Add the macro to the list
macros.Add(composedFile);
}
CloseDoc(doc);
return macros;
}
Solução
Você terá de adicionar uma referência para o Microsoft Visual Basic para Applications Extensibility 5.3 (ou qualquer versão que você tem).Eu tenho o VBA SDK e tal, na minha caixa - de modo que este pode não ser exatamente o que o office acompanha.
Você também tem que permitir o acesso ao Modelo de Objeto do VBA especificamente consulte a "Central de confiabilidade" em opções do Word.Isto é, além de todas as outras configurações de segurança de Macro do Office oferece.
Este exemplo irá extrair o código do documento atual vive em - si é uma macro do VBA (e vai exibir-se e de qualquer outro código, bem).Há também um Aplicativo.vbe.Coleção VBProjects para aceder a outros documentos.Embora eu nunca tenha feito isso, eu suponha uma aplicação externa poderia chegar a abrir arquivos utilizando esta coleção VBProjects bem.A segurança é engraçado com essas coisas, por isso pode ser complicado.
Gostaria também de saber qual o formato de arquivo docm é agora - XML, como o docx?Teria que ser uma abordagem melhor?
Sub GetCode()
Dim prj As VBProject
Dim comp As VBComponent
Dim code As CodeModule
Dim composedFile As String
Dim i As Integer
Set prj = ThisDocument.VBProject
For Each comp In prj.VBComponents
Set code = comp.CodeModule
composedFile = comp.Name & vbNewLine
For i = 1 To code.CountOfLines
composedFile = composedFile & code.Lines(i, 1) & vbNewLine
Next
MsgBox composedFile
Next
End Sub
Outras dicas
Você pode exportar o código de ficheiros e, em seguida, leia-los de volta.
Eu tenho usado o código abaixo para me ajudar a manter algumas macros do Excel sob controle de origem (usando o Subversion & TortoiseSVN).Basicamente, as exportações de todo o código para arquivos de texto a qualquer momento eu guardar com o editor do VBA abrir.Eu coloquei os arquivos de texto no subversion para que eu possa fazer comparações.Você deve ser capaz de adaptar-se/roubar alguns isso para trabalhar no Word.
A verificação do registro na CanAccessVBOM() corresponde a "Confiar no acesso ao Projeto do Visual Basic" na configuração de segurança.
Sub ExportCode()
If Not CanAccessVBOM Then Exit Sub ' Exit if access to VB object model is not allowed
If (ThisWorkbook.VBProject.VBE.ActiveWindow Is Nothing) Then
Exit Sub ' Exit if VBA window is not open
End If
Dim comp As VBComponent
Dim codeFolder As String
codeFolder = CombinePaths(GetWorkbookPath, "Code")
On Error Resume Next
MkDir codeFolder
On Error GoTo 0
Dim FileName As String
For Each comp In ThisWorkbook.VBProject.VBComponents
Select Case comp.Type
Case vbext_ct_ClassModule
FileName = CombinePaths(codeFolder, comp.Name & ".cls")
DeleteFile FileName
comp.Export FileName
Case vbext_ct_StdModule
FileName = CombinePaths(codeFolder, comp.Name & ".bas")
DeleteFile FileName
comp.Export FileName
Case vbext_ct_MSForm
FileName = CombinePaths(codeFolder, comp.Name & ".frm")
DeleteFile FileName
comp.Export FileName
Case vbext_ct_Document
FileName = CombinePaths(codeFolder, comp.Name & ".cls")
DeleteFile FileName
comp.Export FileName
End Select
Next
End Sub
Function CanAccessVBOM() As Boolean
' Check resgistry to see if we can access the VB object model
Dim wsh As Object
Dim str1 As String
Dim AccessVBOM As Long
Set wsh = CreateObject("WScript.Shell")
str1 = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & _
Application.Version & "\Excel\Security\AccessVBOM"
On Error Resume Next
AccessVBOM = wsh.RegRead(str1)
Set wsh = Nothing
CanAccessVBOM = (AccessVBOM = 1)
End Function
Sub DeleteFile(FileName As String)
On Error Resume Next
Kill FileName
End Sub
Function GetWorkbookPath() As String
Dim fullName As String
Dim wrkbookName As String
Dim pos As Long
wrkbookName = ThisWorkbook.Name
fullName = ThisWorkbook.fullName
pos = InStr(1, fullName, wrkbookName, vbTextCompare)
GetWorkbookPath = Left$(fullName, pos - 1)
End Function
Function CombinePaths(ByVal Path1 As String, ByVal Path2 As String) As String
If Not EndsWith(Path1, "\") Then
Path1 = Path1 & "\"
End If
CombinePaths = Path1 & Path2
End Function
Function EndsWith(ByVal InString As String, ByVal TestString As String) As Boolean
EndsWith = (Right$(InString, Len(TestString)) = TestString)
End Function