Copy VBA module when joining documents using C#

Hello. I use the following code to combine multiple documents. This works fine.

I am wondering how this works with documents that contain macros. What I notice now is that if the first document is docm, those macros are kept in the combined file. If the first is docx, and a docm is added, the result is a document without macros.

I want to be clear to the user about this.So I have the folowing questions:

Is it even possible to combine two or more docm files, or should I not allow that?
Is it advisable to combine docm and docx files?

private void AppendDoc(Aspose.Words.Document dstDoc, Aspose.Words.Document srcDoc)
    {
        srcDoc.FirstSection.HeadersFooters.LinkToPrevious(false);
        srcDoc.FirstSection.PageSetup.SectionStart = SectionStart.NewPage;
        dstDoc.AppendDocument(srcDoc, ImportFormatMode.KeepSourceFormatting);
    }

@EdAspose

You can join/combine DOCX and DOCM using Aspose.Words. Could you please ZIP and attach your input DOCX and DOCM along with expected output document? We will investigate the issue and provide you more information on it.

asposetest_1.zip (16.4 KB)

Here is a test setup, I included the linqpad code. I used doc files, one with and one without macros. If I combine the two, the order is important:

first with macro, second without: combined has macro
first without macro, second with macro: combined has no macro

@EdAspose

Please note that Document.AppendDocument does not copy the macros from source document to destination document. However, we have logged this feature request as WORDSNET-19556 in our issue tracking system. You will be notified via this forum thread once this feature is available.

However, you can read the macro from one document and copy it into another document. Please read the following article about working with macros.
Working with VBA Macros

Ok thank you.

So when a docM is appended to a docX file, I could in theory do the following:

  • create a new vba project in de target doc (because it does not have macros yet)
  • add modules from the append docM to the new vba project

I am not too familiar with macros. Would it be advisable to do this? I would only want to support this for my users if it is a safe operation. I have users that combine sometimes 8 documents.

@EdAspose

Yes, your understanding is correct. Following code example shows how to copy macro from one document into another. Hope this helps you.

string sourceDocNormalPath = MyDir + @"source_doc_normal.doc";
string sourceDocMacroPath = MyDir + @"source_doc_with_macro.doc";

Document docNormal = new Document(sourceDocNormalPath);
Document docMacro = new Document(sourceDocMacroPath);

Console.WriteLine(docNormal.HasMacros); 
Console.WriteLine(docMacro.HasMacros); 

Document docTarget1 = new Document(sourceDocNormalPath);
AppendDoc(docTarget1, new Document(sourceDocMacroPath));


if (docMacro.VbaProject != null)
{
    // Create a new VBA project.
    VbaProject project = new VbaProject();
    project.Name = docMacro.VbaProject.Name;
    docTarget1.VbaProject = project;

    foreach (VbaModule md in docMacro.VbaProject.Modules)
    {
        Console.WriteLine(md.SourceCode);
        if (md.Name != "ThisDocument")
        {
            // Create a new module and specify a macro source code.
            VbaModule module = new VbaModule();
            module.Name = md.Name;
            module.Type = VbaModuleType.ProceduralModule;
            module.SourceCode = md.SourceCode;

            // Add module to the VBA project.
            docTarget1.VbaProject.Modules.Add(module);
        }

    }
}

docTarget1.Save(MyDir + "output.docm");

Thank you very much for that sample.
Somehow I cannot compile that code on my end; would you know why?

2019-11-17_11-51-00.jpg (91.7 KB)

@EdAspose

It seems that you are using old version of Aspose.Words. Please use the latest version of Aspose.Words for .NET 19.11.

@EdAspose

We will add ability to clone VbaProject and VbaModule for your requirement as shown in following code examples. Please share if you are satisfied with the proposed solution. We will then add the described functionality in upcoming release.

Document sourceDoc = new Document(MyDir + "source.docm");
Document destDoc = new Document();

// Clone the whole project.
destDoc.VbaProject = sourceDoc.VbaProject.Clone();
destDoc.Save("output.docm");

Document sourceDoc = new Document(MyDir + "source.docm");
Document destDoc = new Document();

destDoc.VbaProject = new VbaProject();

// Clone a single module.
VbaModule copyModule = sourceDoc.VbaProject.Modules["Module1"].Clone();
destDoc.VbaProject.Modules.Add(copyModule);

destDoc.Save("output.docm");

Hi Tahir,

Excuse me for my late response. For now, I have settled for now with the situation that macros are only retained when they are in the first source document. So I have not implemented this yet.

Regards, Ed

@EdAspose

We suggest you please check the code examples in the following article about cloning VBA project and module.
Working with VBA Macros

Moreover, please use the latest version of Aspose.Words for .NET 20.1.

The issues you have found earlier (filed as WORDSNET-19556) have been fixed in this Aspose.Words for .NET 20.2 update and this Aspose.Words for Java 20.2 update.