Mediante programación extracto de macros (VBA) de Word 2007 docs
-
09-06-2019 - |
Pregunta
Es posible extraer todo el código VBA de Word 2007 "docm" documento utilizando el API?
He encontrado cómo insertar el código de VBA en tiempo de ejecución, y cómo a borrar todo el código de VBA, pero no tire el código real a cabo en una secuencia o cadena que puede almacenar (y de inserción en otros documentos en el futuro).
Consejos y recursos se agradece.
Editar:gracias a todos, Un oso hormiguero's respuesta fue exactamente lo que yo estaba buscando.He convertido a su código para C#, y fue capaz de llamar desde una biblioteca de clases usando 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;
}
Solución
Usted tendrá que agregar una referencia a Microsoft Visual Basic para Aplicaciones de Extensibilidad 5.3 (o cualquier versión que tengas).Tengo el VBA SDK y tal en mi caja, por lo que este puede no ser exactamente lo que la oficina de buques con.
También tienes que habilitar el acceso al Modelo de Objetos de VBA específicamente - ver el "Centro de Confianza" en opciones de Word.Esto es en adición a todos los demás configuración de seguridad de Macros de Office proporciona.
En este ejemplo se va a extraer el código del documento actual que se vive en - es en sí misma una macro de VBA (y se mostrará a sí misma y de cualquier otro código).También hay una Aplicación.vbe.VBProjects colección para tener acceso a otros documentos.Aunque nunca he hecho, supongo que una aplicación externa podría llegar a abrir los archivos con esta VBProjects colección así.La seguridad es muy divertido con estas cosas así que puede ser difícil.
También me pregunto lo que el docm formato de archivo ahora - XML como la docx?Tendría que ser un mejor enfoque?
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
Otros consejos
Usted puede exportar el código a los archivos y, a continuación, lea de nuevo.
He estado utilizando el siguiente código para que me ayude a mantener algunas de las macros de Excel bajo control de código fuente (utilizando Subversion & TortoiseSVN).Básicamente, las exportaciones de todo el código en archivos de texto en cualquier momento puedo guardar con el editor de VBA abierto.Puse los archivos de texto en la subversión de modo que yo pueda hacer comparativas.Usted debe ser capaz de adaptar/robar parte de este trabajo en Word.
El registro de verificación en CanAccessVBOM() corresponde a la "Confiar en el acceso a Proyectos de Visual Basic" en la configuración de seguridad.
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