LOCAL FillBuildingBlockInWord(pTxtXPath : Text;pTxtBuildingBlockPath : Text) //Loop through the content controls in the printed Word Report layout FOREACH netWordContentControl IN netWordContentControls DO BEGIN //If the XPaths match, find the Word Block and replace the content control with it IF netWordContentControl.XMLMapping.XPath = pTxtXPath THEN BEGIN lNetContentControlRange := netWordContentControl.Range; //The range of the report Word Layout content control //Open the building block Word document we saved earlier lNetBBWordApp := lNetBBWordAppClass.ApplicationClass; lNetBBWordApp.Visible := FALSE; lNetBBWordDoc := netWordHelper.CallOpen(lNetBBWordApp, pTxtBuildingBlockPath, FALSE, FALSE); lNetBBContentRange := lNetBBWordDoc.Content; //Get the contents of the building block document //Try to add the building block content to the word document; if successful, delete the content contol (while leaving the data) IF TryAddContent(lNetContentControlRange, lNetBBContentRange) THEN netWordContentControl.Delete(FALSE); //Close the building block document netWordHelper.CallClose(lNetBBWordDoc, FALSE); CLEAR(lNetBBWordApp); END; END; //ForEach
LOCAL [TryFunction] TryAddContent(VAR pRefNetWordRange : DotNet "Microsoft.Office.Interop.Word.Range" RUNONCLIENT;VAR pRefNetBuildingBlockRange : DotNet "Microsoft.Office.Interop.Word.Range" RUNONCLIENT) pRefNetWordRange.InsertXML(pRefNetBuildingBlockRange.XML(FALSE), lNetObject);
Answers
Using the Microsoft.Office.Interop.Word libraries, I was able to loop through the content controls of the Word Report Layout at time of printing and look for a specific XPath in the CustomLayout xml (stored in the Custom Report Layout table).
Using that XPath, I was then able to replace the content control with the content of the WordDocument.Content range of the previously stored Word blob.
At this point it does require the report to use the actual table with the stored blob, given that the XPath search string is hard-coded, but that does not present practical issues at this point.
Getting the XPath
In order to get the correct XPath, please refer to this C# code snippet. It is usable as dll, but also not hard to code into NAV itself.
We can now add pre-stored Word blobs to our Word report layout in runtime.
We will need to test more, but this is the business part of the code.
TryAddContent function:
Peter Conijn
-The Learning Network-
I want to know from where to run your code and variables of what types in your function?
I need is to add additional pages to a word document created from a report using the saveaspdf function with the content from another word documents stored in NAV as attachment to the Sales Quote. As I understand, it is possible with your method?
Regard,
Vyacheslav
Thank you for reaching out. Yes, it's certainly possible using this, but you don't need to loop through content controls like I do, nor do you need the whole bit about XPath.
I would remind you, however, that this solution was based on C/AL and uses .NET interop, which, going forward, will be tougher in AL.
The functionality can be called in codeunit 9651, in the MergeWordLayout function, just after the line:
Almost all of the .NET variables all come from the Microsoft.Office.Interop.Word assembly.
WordHelper is a Dynamics NAV assembly:
It always helps me to search for similar code in C# and translate that back to C/AL. StackOverflow specifically often gives you a lot of information.
Peter Conijn
-The Learning Network-