1

I need to copy a VBA macro project from a template file into several office files. I tried using an approach similar to the one found in OpenXML SDK Inject VBA into excel workbook, and here, https://social.msdn.microsoft.com/Forums/lync/en-US/ab65277e-f0fb-4f2b-bfdc-e141abb8404f/copy-macros-document-to-another-document?forum=oxmlsdk.

However, I cannot make the following code work.

private static void cloneVbaPart(string src, string dst)
        {
            using (WordprocessingDocument srcDoc = WordprocessingDocument.Open(src, false))
            {
                var vbaPart = srcDoc.MainDocumentPart.VbaProjectPart;

                using (WordprocessingDocument dstDoc = WordprocessingDocument.Open(dst, true))
                {
                    var partsToRemove = new List<OpenXmlPart>();
                    foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<VbaProjectPart>()) {
                        partsToRemove.Add(part);
                    }
                    foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<CustomizationPart>())
                    {
                        partsToRemove.Add(part);
                    }
                    foreach (var part in partsToRemove)
                    {
                        dstDoc.MainDocumentPart.DeletePart(part);
                    }
                    
                    var vbaProjectPart = dstDoc.MainDocumentPart.AddNewPart<VbaProjectPart>();

                    using (Stream data = vbaPart.GetStream())
                    {
                        vbaProjectPart.FeedData(data);
                    }
                    using (Stream data = vbaPart.VbaDataPart.GetStream())
                    {
                        vbaProjectPart.FeedData(data);
                    }
                }
            }
        }

When I copy the VbaDataPart, the target file becomes unreadable by Word. If I don't, the macro project and code seem to be there, but they don't actually work.

braX
  • 11,506
  • 5
  • 20
  • 33
bananabr
  • 147
  • 11

1 Answers1

1

Found the problem. I was feeding the VbaDataPart into the target's vbaProjectPart and not into its vbaDataPart.

Final code is the following:

        private static void cloneVbaPart(string src, string dst)
        {
            using (WordprocessingDocument srcDoc = WordprocessingDocument.Open(src, false))
            {
                var vbaPart = srcDoc.MainDocumentPart.VbaProjectPart;

                using (WordprocessingDocument dstDoc = WordprocessingDocument.Open(dst, true))
                {
                    var partsToRemove = new List<OpenXmlPart>();
                    foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<VbaProjectPart>()) {
                        partsToRemove.Add(part);
                    }
                    foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<CustomizationPart>())
                    {
                        partsToRemove.Add(part);
                    }
                    foreach (var part in partsToRemove)
                    {
                        dstDoc.MainDocumentPart.DeletePart(part);
                    }
                    
                    var vbaProjectPart = dstDoc.MainDocumentPart.AddNewPart<VbaProjectPart>();
                    var vbaDataPart = vbaProjectPart.AddNewPart<VbaDataPart>();

                    using (Stream data = vbaPart.GetStream())
                    {
                        vbaProjectPart.FeedData(data);
                    }
                    using (Stream data = vbaPart.VbaDataPart.GetStream())
                    {
                        vbaDataPart.FeedData(data);
                    }
                }
            }
        }
bananabr
  • 147
  • 11