3

I'm trying to create a macro in a new dotm word file created with OpenXML. I guess I have to add a VBAProjectPart but I can not go on.

The macro is stored in a string variable : for example

    string tmpMacro = "Private Sub Add_Pages()\nDim tmpPages As Integer\ntmpPages = Selection.Information(wdNumberOfPagesInDocument)\nSelection.EndKey Unit:= wdStory\nDo While Selection.Information(wdNumberOfPagesInDocument) < 10\nSelection.InsertBreak(wdPageBreak)\nLoop\nEnd Sub";

    WordprocessingDocument tmpWD = WordprocessingDocument.Create("myDoc.docm", DocumentFormat.OpenXml.WordprocessingDocumentType.MacroEnabledDocument);
    MainDocumentPart tmpWMP = tmpWGD.AddMainDocumentPart();

    tmpMDP.Document = new Document(new Body());

    tmpWD.Close();
Nigel Irvine
  • 31
  • 1
  • 4

1 Answers1

5

In OpenXML, macros are a combination of binary format and XML relation files.

To verify this for yourself, create a new Word/Excel file, create a new macro, and save it as a macro-enabled document/workbook. Close the file and rename it to end with .zip.

In the main directory, you will find the file [Content_Types].xml, inside of which there are two relation pointers:

  1. <Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/>
  2. <Override PartName="/word/vbaData.xml" ContentType="application/vnd.ms-word.vbaData+xml"/>

To follow these files, locate word/vbaData.xml, inside of which there will be something like:

<wne:vbaSuppData ...namespaces ommitted... >
    <wne:mcds>
        <wne:mcd wne:macroName="PROJECT.NEWMACROS.MACRO1" 
                 wne:name="Project.NewMacros.Macro1" 
                 wne:bEncrypt="00" 
                 wne:cmg="56"/>
    </wne:mcds>
</wne:vbaSuppData>

This is shows that there is some macro named Project.NewMacros.Macro1, but little else. So let's look inside of word/_rels/document.xml.rels:

<Relationships ...namespaces ommitted...>
    <Relationship Id="rId1"
                  Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" 
                  Target="vbaProject.bin"/>
    ...other relationships ommitted...
</Relationships>

This points to word/vbaProject.bin, which is a binary file format.

If you need to add this macro programmatically (e.g. you cannot set everything else up, and add the macro manually), then you could create the macro in a one document manually, and then programmatically copy the binary stream from the manually created vbaProject.bin file into a new vbaProject.bin file.

If you decide to follow the stream copy approach, the answer to this question includes a snippet demonstrating one way to do so.

Community
  • 1
  • 1
Austin Drenski
  • 506
  • 4
  • 10