Is it possible to extract all of the VBA code from a Word 2007 ‘docm’ document using the API?
I have found how to insert VBA code at runtime, and how to delete all VBA code, but not pull the actual code out into a stream or string that I can store (and insert into other documents in the future).
Any tips or resources would be appreciated.
Edit: thanks to everyone, Aardvark‘s answer was exactly what I was looking for. I have converted his code to C#, and was able to call it from a class library using 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; }
You’ll have to add a reference to Microsoft Visual Basic for Applications Extensibility 5.3 (or whatever version you have). I have the VBA SDK and such on my box – so this may not be exactly what office ships with.
Also you have to enable access to the VBA Object Model specifically – see the ‘Trust Center’ in Word options. This is in addition to all the other Macro security settings Office provides.
This example will extract code from the current document it lives in – it itself is a VBA macro (and will display itself and any other code as well). There is also a Application.vbe.VBProjects collection to access other documents. While I’ve never done it, I assume an external application could get to open files using this VBProjects collection as well. Security is funny with this stuff so it may be tricky.
I also wonder what the docm file format is now – XML like the docx? Would that be a better approach?