.net - ejemplos - macros en word 2010
Programe automáticamente el código macro(VBA) de los documentos de Word 2007 (2)
¿Es posible extraer todo el código de VBA de un documento Word 2007 "docm" utilizando la API?
He encontrado cómo insertar código VBA en tiempo de ejecución y cómo eliminar todo el código VBA, pero no extraer el código real en una secuencia o cadena que puedo almacenar (e insertar en otros documentos en el futuro).
Cualquier consejo o recurso sería apreciado.
Editar : gracias a todos, la respuesta de Aardvark fue exactamente lo que estaba buscando. He convertido su código a C # y pude llamarlo desde una biblioteca de clase 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;
}
Deberá agregar una referencia a Microsoft Visual Basic para Aplicaciones Extensibilidad 5.3 (o la versión que tenga). Tengo el SDK de VBA y tal en mi caja, por lo que puede que no sea exactamente con lo que se envía la oficina.
También debe habilitar el acceso al Modelo de objetos VBA específicamente; consulte el "Centro de confianza" en las opciones de Word. Esto se suma a todas las otras configuraciones de seguridad Macro que proporciona Office.
Este ejemplo extraerá código del documento actual en el que vive: es una macro de VBA (y se mostrará a sí mismo y a cualquier otro código). También hay una colección Application.vbe.VBProjects para acceder a otros documentos. Aunque nunca lo hice, supongo que una aplicación externa podría abrir archivos usando esta colección de VBProjects también. La seguridad es divertida con esto, así que puede ser complicado.
También me pregunto qué formato de archivo docm es ahora: ¿XML como el docx? ¿Sería eso 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
Puede exportar el código a los archivos y luego volver a leerlos.
He estado usando el siguiente código para ayudarme a mantener algunas macros de Excel bajo el control de código fuente (usando Subversion & TortoiseSVN). Básicamente, exporta todo el código a archivos de texto cada vez que lo guardo con el editor de VBA abierto. Puse los archivos de texto en subversión para poder hacer diffs. Debería poder adaptar / robar algo de esto para trabajar en Word.
La comprobación de registro en CanAccessVBOM () corresponde al "Acceso de confianza al proyecto 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