How to generate letters in Word with custom fields
elwin68
Member Posts: 153
Hello,
For a client custom tables are made in NAV2009 SP1 (classic client).
Now a solution must be made to create letters in Word including custom fields.
The client must be able to generate the templates in Word himself. It would be nice letters can be generated and printed through a batch.
The following options are possible:
- Interaction template
Custom fields can't be used.
It can be programmed to use custom fields but only a maximum number of fields can be used.
- Style sheets
It can not be called through code behind a button.
It can not be used through a batch.
Does anyone have a flexibel solution?
Thanks in advance.
For a client custom tables are made in NAV2009 SP1 (classic client).
Now a solution must be made to create letters in Word including custom fields.
The client must be able to generate the templates in Word himself. It would be nice letters can be generated and printed through a batch.
The following options are possible:
- Interaction template
Custom fields can't be used.
It can be programmed to use custom fields but only a maximum number of fields can be used.
- Style sheets
It can not be called through code behind a button.
It can not be used through a batch.
Does anyone have a flexibel solution?
Thanks in advance.
0
Answers
-
Add a function to call the stylesheet functionality through code.
See attachment for this function (add it in codeunit 403)
It can be called like this:
//gAppLaunchMgt Codeunit Application Launch Management
//gPKRecRef RecordRef
gPKRecRef.GETTABLE( BaseRecordInStyleSheet);
gAppLaunchMgt.LaunchAppManual( gPKRecRef,
StyleSheetToUse, // somewhere the user has chosen this one, or set in setup record
ExportFormat::PDF, // or " ", DOC, HTML, TXT
PathToStoreFile,
{VAR} FileNameCreated);
This works in a 5.0SP1 environment on SQL with 3.70 functionality
Function looks like this:PROCEDURE LaunchAppManual@1000000000(PKRecRef@1000000000 : RecordRef;StylesheetTemplateCode@1000000010 : Code[20];SaveAs@1000000017 : 'None,DOCX,PDF,HTML,TXT';PathName@1000000023 : Text[250];VAR vTxtFileName@1000000021 : Text[250]) : Boolean; VAR DataXML@1000000008 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{88D969C0-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v4.0'.DOMDocument40"; ApplicationXML@1000000006 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{88D969C0-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v4.0'.DOMDocument40"; DataXMLNode@1000000003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v4.0'.IXMLDOMNode"; WordApp@1000000002 : Automation "{00020905-0000-0000-C000-000000000046} 8.4:{000209FF-0000-0000-C000-000000000046}:'Microsoft Word 12.0 Object Library'.Application"; WordAppDoc@1000000001 : Automation "{00020905-0000-0000-C000-000000000046} 8.4:{0002096C-0000-0000-C000-000000000046}:'Microsoft Word 12.0 Object Library'.Documents"; StyleSheetLink@1000000014 : Record 685; PKKeyRef@1000000004 : KeyRef; PKCurKeyRef@1000000016 : KeyRef; PKFieldRef@1000000007 : FieldRef; TextWordNotFound@1000000011 : TextConst 'ENU=Word not found.;NLD=MS-Word niet gevonden.'; UrlStr@1000000009 : ARRAY [2] OF Text[1024]; FileName@1000000015 : Text[1024]; FileNameDoc@1000000018 : Text[1024]; FieldCount@1000000005 : Integer; wdExportFormatPDF@1000000012 : Integer; wdFormatText@1000000013 : Integer; wdFormatHTML@1000000020 : Integer; wdFormatXMLDocument@1000000022 : Integer; OpenAfterExport@1000000019 : Boolean; BEGIN //STYLESHEET-01.ns CREATE(ApplicationXML); CREATE(DataXML); PKCurKeyRef := PKRecRef.KEYINDEX(PKRecRef.CURRENTKEYINDEX); FOR FieldCount := 1 TO PKCurKeyRef.FIELDCOUNT DO BEGIN PKFieldRef := PKCurKeyRef.FIELDINDEX(FieldCount); UrlStr[1] += 'Field' + FORMAT(PKFieldRef.NUMBER); IF FieldCount < PKCurKeyRef.FIELDCOUNT THEN UrlStr[1] += ',' END; UrlStr[1] := '%26view=SORTING(' + UrlStr[1] + ')'; PKKeyRef := PKRecRef.KEYINDEX(1); FOR FieldCount := 1 TO PKKeyRef.FIELDCOUNT DO BEGIN PKFieldRef := PKKeyRef.FIELDINDEX(FieldCount); UrlStr[2] += 'Field' + FORMAT(PKFieldRef.NUMBER) + '=0(' + FORMAT(PKFieldRef.VALUE) + ')'; IF FieldCount < PKCurKeyRef.FIELDCOUNT THEN UrlStr[2] += ','; IF FieldCount > 1 THEN FileName += ' '; FileName += FORMAT(PKFieldRef.VALUE); END; UrlStr[2] := '%26position=' + UrlStr[2] + '%26servertype=MSSQL'; IF PathName<>'' THEN BEGIN IF PathName[STRLEN( PathName)] <> '\' THEN PathName += '\'; FileName := PathName+FileName; END; DataXMLNode := DataXML.createNode(1, 'Object', ''); DataXML.appendChild(DataXMLNode); AddAttribute(DataXMLNode, 'url', UrlStr[1] + UrlStr[2]); StyleSheetLink.SETFILTER("Template Code",StylesheetTemplateCode); StyleSheetLink.FINDSET; LaunchApp(DataXML,StyleSheetLink."Style Sheet ID",ApplicationXML); IF NOT CREATE(WordApp,TRUE) THEN ERROR(TextWordNotFound); FileNameDoc := FileName + '.doc'; // TEMP IF EXISTS(FileNameDoc) THEN ERASE(FileNameDoc); ApplicationXML.save(FileNameDoc); WordApp.Visible := FALSE; WordApp.Documents.Open(FileNameDoc); CASE SaveAs OF SaveAs::PDF: BEGIN FileNameDoc := FileName + '.pdf'; IF EXISTS(FileNameDoc) THEN ERASE(FileNameDoc); wdExportFormatPDF := 17; OpenAfterExport := FALSE; WordApp.ActiveDocument.ExportAsFixedFormat( FileNameDoc,wdExportFormatPDF,OpenAfterExport); END; SaveAs::TXT: BEGIN FileNameDoc := FileName + '.txt'; // TEMP IF EXISTS(FileNameDoc) THEN ERASE(FileNameDoc); wdFormatText := 2; WordApp.ActiveDocument.SaveAs( FileNameDoc, wdFormatText); END; SaveAs::HTML: BEGIN FileNameDoc := FileName + '.html'; IF EXISTS(FileNameDoc) THEN ERASE(FileNameDoc); wdFormatHTML := 10;// wdFormatFilteredHTML = 10 WordApp.ActiveDocument.SaveAs( FileNameDoc, wdFormatHTML); END; SaveAs::DOCX: BEGIN FileNameDoc := FileName + '.docx'; IF EXISTS(FileNameDoc) THEN ERASE(FileNameDoc); wdFormatXMLDocument := 12; WordApp.ActiveDocument.SaveAs( FileNameDoc, wdFormatXMLDocument); END; ELSE WordApp.Visible(TRUE); END; vTxtFileName := FileNameDoc; WordApp.Documents.Close; WordApp.Quit; //STYLESHEET-01.ne END;0 -
Thanks for your solution.
I will look if it is possible in NAV2009SP1.0 -
How does it work?
Who's going to process the url attribute you create? There's no code to do this in my version.
Checked NAVW16.00.01 (2009 SP1 R2) and NAVW15.00 (NAV 5.0 SP1).0 -
I dno, maybe Word might do the trick. It is a word template.0
-
vaprog wrote:How does it work?
Who's going to process the url attribute you create? There's no code to do this in my version.
Checked NAVW16.00.01 (2009 SP1 R2) and NAVW15.00 (NAV 5.0 SP1).
Yes, you are correct. It creates a node in an empty XML Document. Maybe Remco isn't working with NAV anymore for this
0 -
Ok, I have updated it a bit to make it work. Thank you Remco for the example

1.
To test and start it.PROCEDURE RxTestLaunchAppManual@1000000014(); VAR LrCustomer@1000000000 : Record 18; LrrefRecord@1000000001 : RecordRef; LoptSaveAs@1000000002 : 'None,DOCX,PDF,HTML,TXT'; LtFilePathName@1000000003 : Text[250]; BEGIN LtFilePathName := ''; LrCustomer.RESET; LrCustomer.FINDFIRST; LrrefRecord.GETTABLE(LrCustomer); RxLaunchAppManual(LrrefRecord, 'Klantkaart voor brief Microsoft Word', LoptSaveAs::DOCX, 'd:\', LtFilePathName, FALSE, 21); END;
2.
The new code.PROCEDURE RxLaunchAppManual@11083986(PrrefRecord@1000000000 : RecordRef;PtStylesheetTemplate@1000000010 : Text[250];PoptSaveAs@1000000017 : 'None,DOCX,PDF,HTML,TXT';PtFilePath@1000000023 : Text[250];VAR vPtFilePathName@1000000021 : Text[250];PbCloseApplication@1000000022 : Boolean;PiFormID@1000000011 : Integer) : Boolean; VAR LaXMLDocument@1000000008 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A05-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.DOMDocument60"; LaXMLDocumentApplication@1000000006 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A05-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.DOMDocument60"; LaXMLNode@1000000003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode"; LaXMLNodeControl1@1000000027 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode"; LaXMLNodeControl2@1000000028 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode"; LaXMLNodeRow@1000000029 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode"; LaWdApp@1000000002 : Automation "{00020905-0000-0000-C000-000000000046} 8.4:{000209FF-0000-0000-C000-000000000046}:Unknown Automation Server.Application"; LaWdDocument@1000000001 : Automation "{00020905-0000-0000-C000-000000000046} 8.4:{0002096C-0000-0000-C000-000000000046}:Unknown Automation Server.Documents"; LkrefPrimKey@1000000004 : KeyRef; LkrefCurrentKey@1000000016 : KeyRef; LfrefField@1000000007 : FieldRef; UrlStr@1000000009 : ARRAY [2] OF Text[1024]; LtFilePathName@1000000015 : Text[512]; LtFilePathNameDoc@1000000018 : Text[512]; LiFieldCount@1000000005 : Integer; LrStyleSheet@1000000014 : Record 2000000066; LguidRxLastProgram@1000000024 : GUID; LiConstwdExportFormatPDF@1000000020 : Integer; LiConstwdFormatText@1000000019 : Integer; LiConstwdFormatHTML@1000000013 : Integer; LiConstwdFormatXMLDocument@1000000012 : Integer; LbConstOpenAfterExport@1000000025 : Boolean; GtcNoWord@1000000026 : TextConst 'ENU=MsWord not found.;NLD=MsWord niet gevonden.'; BEGIN //MOD_RX //http://www.mibuso.com/forum/viewtopic.php?f=23&t=43516&sid=5d6db25f72ba4922227b8dce658e4ca4 LkrefCurrentKey := PrrefRecord.KEYINDEX(PrrefRecord.CURRENTKEYINDEX); FOR LiFieldCount := 1 TO LkrefCurrentKey.FIELDCOUNT DO BEGIN LfrefField := LkrefCurrentKey.FIELDINDEX(LiFieldCount); UrlStr[1] += 'Field' + FORMAT(LfrefField.NUMBER); IF LiFieldCount < LkrefCurrentKey.FIELDCOUNT THEN UrlStr[1] += ',' END; UrlStr[1] := '%26view=SORTING(' + UrlStr[1] + ')'; LkrefPrimKey := PrrefRecord.KEYINDEX(1); FOR LiFieldCount := 1 TO LkrefPrimKey.FIELDCOUNT DO BEGIN LfrefField := LkrefPrimKey.FIELDINDEX(LiFieldCount); UrlStr[2] += 'Field' + FORMAT(LfrefField.NUMBER) + '=0(' + FORMAT(LfrefField.VALUE) + ')'; IF LiFieldCount < LkrefCurrentKey.FIELDCOUNT THEN UrlStr[2] += ','; IF LiFieldCount > 1 THEN LtFilePathName += ' '; LtFilePathName += FORMAT(LfrefField.VALUE); END; UrlStr[2] := '%26position=' + UrlStr[2] + '%26servertype=MSSQL'; IF PtFilePath<>'' THEN BEGIN IF PtFilePath[STRLEN( PtFilePath)] <> '\' THEN BEGIN PtFilePath += '\'; END; LtFilePathName := PtFilePath+LtFilePathName; END; CREATE(LaXMLDocumentApplication); CREATE(LaXMLDocument); LaXMLDocument.async := FALSE; LaXMLDocument.loadXML( '<?xml version="1.0" encoding="UTF-8" standalone="no"?><Object>' + '</Object>'); LaXMLNode := LaXMLDocument.documentElement; AddAttribute(LaXMLNode, 'url', UrlStr[1] + UrlStr[2]); AddAttribute(LaXMLNode, 'type', 'Form'); AddAttribute(LaXMLNode, 'id', FORMAT(PiFormID)); AddElement(LaXMLNode,'Control','',LaXMLNodeControl1); AddAttribute(LaXMLNodeControl1,'type','TabControl'); AddElement(LaXMLNodeControl1,'Control','',LaXMLNodeControl2); AddAttribute(LaXMLNodeControl2,'type','TabPage'); AddElement(LaXMLNodeControl2,'Row','',LaXMLNodeRow); AddElement(LaXMLNodeRow,'Control','',LaXMLNodeControl1); AddAttribute(LaXMLNodeControl1,'type','Label'); AddElement(LaXMLNodeRow,'Control','',LaXMLNodeControl2); AddAttribute(LaXMLNodeControl2,'type','TextBox'); AddAttribute(LaXMLNodeControl2,'value','30000'); //LaXMLDocument.save('d:\manualobject.xml'); LrStyleSheet.RESET; LrStyleSheet.SETFILTER(Name,PtStylesheetTemplate); IF (NOT LrStyleSheet.FINDFIRST) THEN BEGIN EXIT; END; CLEAR(LguidRxLastProgram); //No ReportX LaunchApp(LaXMLDocument,LrStyleSheet."Style Sheet ID",LaXMLDocumentApplication, LguidRxLastProgram); IF NOT CREATE(LaWdApp,FALSE, TRUE) THEN BEGIN ERROR(GtcNoWord); END; LtFilePathNameDoc := LtFilePathName + '.doc'; // TEMP IF EXISTS(LtFilePathNameDoc) THEN ERASE(LtFilePathNameDoc); LaXMLDocumentApplication.save(LtFilePathNameDoc); LaWdApp.Visible := TRUE; LaWdApp.Documents.Open(LtFilePathNameDoc); CASE PoptSaveAs OF PoptSaveAs::PDF: BEGIN LtFilePathNameDoc := LtFilePathName + '.pdf'; IF EXISTS(LtFilePathNameDoc) THEN ERASE(LtFilePathNameDoc); LiConstwdExportFormatPDF := 17; LbConstOpenAfterExport := FALSE; LaWdApp.ActiveDocument.ExportAsFixedFormat(LtFilePathNameDoc,LiConstwdExportFormatPDF,LbConstOpenAfterExport); END; PoptSaveAs::TXT: BEGIN LtFilePathNameDoc := LtFilePathName + '.txt'; // TEMP IF EXISTS(LtFilePathNameDoc) THEN ERASE(LtFilePathNameDoc); LiConstwdFormatText := 2; LaWdApp.ActiveDocument.SaveAs(LtFilePathNameDoc, LiConstwdFormatText); END; PoptSaveAs::HTML: BEGIN LtFilePathNameDoc := LtFilePathName + '.html'; IF EXISTS(LtFilePathNameDoc) THEN ERASE(LtFilePathNameDoc); LiConstwdFormatHTML := 10;// LiConstwdFormatFilteredHTML = 10 LaWdApp.ActiveDocument.SaveAs(LtFilePathNameDoc, LiConstwdFormatHTML); END; PoptSaveAs::DOCX: BEGIN LtFilePathNameDoc := LtFilePathName + '.docx'; IF EXISTS(LtFilePathNameDoc) THEN ERASE(LtFilePathNameDoc); LiConstwdFormatXMLDocument := 12; LaWdApp.ActiveDocument.SaveAs(LtFilePathNameDoc, LiConstwdFormatXMLDocument); END; ELSE LaWdApp.Visible(TRUE); END; vPtFilePathName := LtFilePathNameDoc; LaWdApp.Documents.Close; IF (PbCloseApplication) THEN BEGIN LaWdApp.Quit; END; CLEAR(LaXMLDocumentApplication); CLEAR(LaXMLDocument); END;
3.
I have made MS-Word visible.0 -
Forgive me for being lazy, but I've just realized that the posted code does not compile under NAV2009 because the AddElement function has been changed.
Has anybody fixed this?Brian Rocatis
Senior NAV Developer
Elbek & Vejrup0
Categories
- All Categories
- 75 General
- 75 Announcements
- 66.7K Microsoft Dynamics NAV
- 18.8K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 611 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 253 Dynamics CRM
- 103 Dynamics GP
- 6 Dynamics SL
- 1.5K Other
- 991 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 28 Design Patterns (General & Best Practices)
- Architectural Patterns
- 9 Design Patterns
- 4 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1K General Chat
- 1.6K Website
- 77 Testing
- 1.2K Download section
- 23 How Tos section
- 249 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions
