none
Copy macros document to another document RRS feed

  • Question

  • Hi,

    I want to copy macro enabled document to another document using open xml?

    can any one send the code?

    Wednesday, August 1, 2012 6:33 AM

Answers

  • This sample code copies macros and keymap information from srcDoc (source macro enabled Word document) to destDoc (destination of copy, new macro enabled Word document). I hope this will help.

    Regards,
    Kazunori

    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml.Packaging;
    namespace CtrlInsertMacro
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (WordprocessingDocument destDoc = WordprocessingDocument.Create("destination.docm", WordprocessingDocumentType.MacroEnabledDocument))
                {
                    WordprocessingDocument srcDoc = WordprocessingDocument.Open("macrosource.docm", false);
                    MainDocumentPart mainPart = destDoc.AddMainDocumentPart();
                    // Create the document structure and add some text.
                    mainPart.Document = new Document();
                    Body body = mainPart.Document.AppendChild(new Body());
                    Paragraph para = body.AppendChild(new Paragraph());
                    Run run = para.AppendChild(new Run());
                    run.AppendChild(new Text("This is a copied macro enabled doc. Hit Ctrl+Insert Now."));
                    // Get VBA parts from source document
                    VbaProjectPart vbaSrc = srcDoc.MainDocumentPart.VbaProjectPart;
                    VbaDataPart vbaDatSrc = vbaSrc.VbaDataPart;
                    CustomizationPart keymapSrc = srcDoc.MainDocumentPart.CustomizationPart;
                    // Create VBA parts in destination document
                    VbaProjectPart vbaProjectPart1 = mainPart.AddNewPart<VbaProjectPart>("rId9");
                    VbaDataPart vbaDataPart1 = vbaProjectPart1.AddNewPart<VbaDataPart>("rId1");
                    CustomizationPart customKeyMapPart = mainPart.AddNewPart<CustomizationPart>("rId10");
                    // Copy part contents
                    vbaProjectPart1.FeedData(vbaSrc.GetStream());
                    vbaDataPart1.FeedData(vbaDatSrc.GetStream());
                    customKeyMapPart.FeedData(keymapSrc.GetStream());
                }
            }
        }
    }


    Kazunori Matsuura

    Monday, August 6, 2012 8:38 AM

All replies

  • Hello nikitha.P,

    If the copy destination is not a macro enabled document, Open XML SDK can't copy the macro in the source document file to the destination. Before you insert a VbaProjectPart to the destination document, the document need to be converted to macro enabled. Otherwise, the document is not executable.

    To convert it to "macro enabled", you need to unzip the destination document and replace

    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />

    with

    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.ms-excel.sheet.macroEnabled.main+xml"/>  

    in [Content_Types].xml. And its file extention need to be renamed to ".xlsm". Then you can copy the vba macro from the source docuement to the destination document.

    VbaProjectPart vba = srcDocument.WorkbookPart.VbaProjectPart;
    VbaProjectPart vbaProjectPart1 = dstDocument.Workbookpart.AddNewPart<VbaProjectPart>("rId9");
    vbaProjectPart1.FeedData(vba.GetStream());

    Unfortunately, either of Open XML SDK and System.IO.Packaging can't edit [Content_Types].xml, so that you need to add third party unzip library to your project. 

    Thank you very much for posting your question to the forum!

    Thanks,
    Kazunori



    Wednesday, August 1, 2012 8:53 AM
  • This sample code copies macros and keymap information from srcDoc (source macro enabled Word document) to destDoc (destination of copy, new macro enabled Word document). I hope this will help.

    Regards,
    Kazunori

    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml.Packaging;
    namespace CtrlInsertMacro
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (WordprocessingDocument destDoc = WordprocessingDocument.Create("destination.docm", WordprocessingDocumentType.MacroEnabledDocument))
                {
                    WordprocessingDocument srcDoc = WordprocessingDocument.Open("macrosource.docm", false);
                    MainDocumentPart mainPart = destDoc.AddMainDocumentPart();
                    // Create the document structure and add some text.
                    mainPart.Document = new Document();
                    Body body = mainPart.Document.AppendChild(new Body());
                    Paragraph para = body.AppendChild(new Paragraph());
                    Run run = para.AppendChild(new Run());
                    run.AppendChild(new Text("This is a copied macro enabled doc. Hit Ctrl+Insert Now."));
                    // Get VBA parts from source document
                    VbaProjectPart vbaSrc = srcDoc.MainDocumentPart.VbaProjectPart;
                    VbaDataPart vbaDatSrc = vbaSrc.VbaDataPart;
                    CustomizationPart keymapSrc = srcDoc.MainDocumentPart.CustomizationPart;
                    // Create VBA parts in destination document
                    VbaProjectPart vbaProjectPart1 = mainPart.AddNewPart<VbaProjectPart>("rId9");
                    VbaDataPart vbaDataPart1 = vbaProjectPart1.AddNewPart<VbaDataPart>("rId1");
                    CustomizationPart customKeyMapPart = mainPart.AddNewPart<CustomizationPart>("rId10");
                    // Copy part contents
                    vbaProjectPart1.FeedData(vbaSrc.GetStream());
                    vbaDataPart1.FeedData(vbaDatSrc.GetStream());
                    customKeyMapPart.FeedData(keymapSrc.GetStream());
                }
            }
        }
    }


    Kazunori Matsuura

    Monday, August 6, 2012 8:38 AM
  • Hi,

    Thannks  for your code.But iam getting error near  customKeyMapPart.FeedData(keymapSrc.GetStream());

    coz keymapSrc is null.i need code to copy the content of the document too.i dontwant to create new body ,paragrpah etc..please can u help me?

    Wednesday, September 5, 2012 5:46 AM
  • Hi Nikitha,

    In your case, please remove the following lines from my sample since your document seems not have any key bind information.

    CustomizationPart keymapSrc = srcDoc.MainDocumentPart......
    CustomizationPart customKeyMapPart = mainPart.AddNewPart....
    customKeyMapPart.FeedData(keymapSrc...

    But copying the document contents from the source and pasting it to the destination would be more complicated tasks for Open XML SDK. It would be a better approach to create a master .docm file by Word and to modify it by an Open XML SDK application.

    Thanks,
    Kazunori


    Kazunori Matsuura

    Friday, September 7, 2012 7:27 AM