Problem:
COM WORD: Automate Word to Perform a Mail Merge with Access Data
( GetMailMerge, OpenDataSource,... )
The cobol sample pasted below and attached to this KB is a copy & 'COBOL' paste of an example available on Microsoft Web site
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dno2kta/html/offaut.asp
Automate Word to Perform a Mail Merge with Access Data
MFC example
//For optional arguments
COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR);
//Start Word
_Application oApp;
oApp.CreateDispatch("Word.Application");
if(!oApp)
{
AfxMessageBox("Cannot start Word.");
return;
}
//Get the Documents collection so that you can add
//a new Document for the mail merge "main document"
Documents oDocs = oApp.GetDocuments();
_Document oDoc = oDocs.Add(vOpt, vOpt);
//Note for Word 2000: The Add method has 4 arguments in Word 2000. If
//you wrapped the classes from the Word type library (msword9.olb),
//modify the Add method to provide 4 optional arguments:
// oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);
//Get the MailMerge property of the new document
MailMerge oMMerge = oDoc.GetMailMerge();
//Set the document type as Form Letters
oMMerge.SetMainDocumentType((long)0); //wdFormLetters = 0
//Set up the mail merge data source to the DSN "Northwind" and
//an SQL statement
CString sSQL;
sSQL ="SELECT CompanyName, Address, ContactName, City, Country," \\
"Region FROM Customers";
oMMerge.OpenDataSource("", vOpt, vOpt, vOpt, vOpt,
vOpt, vOpt, vOpt, vOpt, vOpt, vOpt,
COleVariant("DSN=Northwind"),
COleVariant(sSQL), vOpt);
//Add the field codes and text to the document
Selection oSel = oApp.GetSelection();
Range oRange;
MailMergeFields oMMFlds = oMMerge.GetFields();
MailMergeField oMMFld;
oRange = oSel.GetRange();
oMMFld = oMMFlds.Add(oRange, "CompanyName");
oSel.TypeParagraph();
oRange = oSel.GetRange();
oMMFld = oMMFlds.Add(oRange, "Address");
oSel.TypeParagraph();
oRange = oSel.GetRange();
oMMFld = oMMFlds.Add(oRange, "City");
oSel.TypeText(", ");
oRange = oSel.GetRange();
oMMFld = oMMFlds.Add(oRange, "Country");
oSel.TypeParagraph();
oSel.TypeParagraph();
oSel.TypeText("Dear ");
oRange = oSel.GetRange();
oMMFld = oMMFlds.Add(oRange, "ContactName");
oSel.TypeText(",");
oSel.TypeParagraph();
oSel.TypeParagraph();
oSel.TypeText("This letter is to inform you...");
oSel.TypeParagraph();
oSel.TypeParagraph();
oSel.TypeText("Sincerely, John Smith");
//Execute the mail merge and then close the
//main document without saving changes
oMMerge.SetDestination(0); //wdSendToNewDocument = 0
oMMerge.Execute(COleVariant((short)FALSE));
oDoc.Close(COleVariant((short)FALSE), vOpt, vOpt);
//Make Word visible
oApp.SetVisible(TRUE);
Resolution:
To create a mail merge with external data in Microsoft Word, you must create a User DSN for the OpenDataSource method of Word's MailMerge object. The sample code uses a DSN named "Northwind" that refers to Northwind.mdb. Before using the sample code, you must first create the DSN:
1) In Control Panel in Windows, double-click the ODBC Data Sources (32-bit) icon. The ODBC Data Source Administrator dialog box appears.
2) Click Add on the User DSN tab.
3) Select the Microsoft Access Driver, and click Finish.
4) When prompted for the new Data Source information, type Northwind for the name of the Data Source, and click Select to browse to Northwind.mdb.
5) Click OK to save the DSN information and then exit the ODBC Data Source Administrator.
___________________________________
FYI: Complete Object Model for Microsoft WORD
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/off2000/html/wotocObjectModelApplication.asp
___________________________________
Cobol Code pasted:
*> This is required for OLE applications
$set ooctrl( P)
program-id. wordyva.
special-names.
call-convention 74 is winapi.
class-control.
*> OLE automation classes
wordapp is class "$OLE$word.application"
olesup is class "olesup"
oleVariant is class "olevar"
.
working-storage section.
copy "mfole".
copy typelibWORD *> generated by MF Netx Type Library assistant
replacing ==GLOBAL== by ==WGlobal==
==Variable== by ==Wvariable==
==RANGE== by ==WRANGE==
==CHARACTERS== by ==WCHARACTERS==
==WORDS== by ==WWORDS==
==PARAGRAPH== by ==WPARAGRAPH==
==TABLE== by ==WTABLE==
==COLUMN== by ==WCOLUMN==
==SECTION== by ==WSECTION==
==INDEX== by ==WINDEX==
.
01 wordServer object reference value null.
01 theDocuments object reference value null.
01 theDocument object reference value null.
01 oMMerge object reference value null.
01 oSelection object reference value null.
01 oRange object reference value null.
01 oMMFlds object reference value null.
01 oMMFld object reference value null.
01 CWdMailMergeMainDocType WdMailMergeMainDocType.
01 VariantObject object reference value null.
01 VConnection object reference value null.
01 VSQLStatement object reference value null.
01 v VARIANT.
01 vOpt Object reference value null.
01 DataSourceFileName pic x(100) value spaces. *> p1
01 Connection pic x(150) value z'DSN=NorthWind'.
*> p12
01 VOConnection object reference value null. *> p12
01 SQLStatement pic x(100) value
z'SELECT CompanyName, Address, ContactName , City, Country,
- 'Region FROM Customers'. *> p13
01 VOSQLStatement object reference value null. *> p13
01 theStringLength PIC 9(9) COMP-5.
01 TheErrorCode PIC 9(9) COMP-5.
01 TheError redefines TheErrorCode PIC 9(9) COMP-5.
01 WRKstr pic x(100) value spaces.
01 theCharArray object reference.
01 theType VARTYPE.
01 TheDisplayObj object reference.
01 TheVariant VARIANT.
01 theDay pic 9(2).
01 theMonth pic 9(2).
01 theYear pic 9(4).
01 nBufferLength DWORD.
01 lpBuffer pic x(100).
01 RetAPI DWORD.
linkage section.
01 lnkValueI2 pic x(2) comp-5.
01 lnkValueSI2 pic s9(4) comp-5.
01 lnkValueI4 pic x(4) comp-5.
01 lnkValueR4 comp-1.
01 lnkValueR8 comp-2.
procedure division.
*> Create an instance of Word
invoke wordapp "new" returning wordServer
*> Make it visible
invoke wordServer "SetVisible" using by value 1
*> Get the Word documents collection object
invoke wordServer "getDocuments" returning theDocuments
*> Create a new document. The Template and NewTemplate
*> parameters for this method are optional
invoke theDocuments "add" returning TheDocument
invoke theDocument "GetMailMerge" returning oMMerge
*> 0 = wdFormLetters
move 0 to CWdMailMergeMainDocType
invoke oMMerge "SetMainDocumentType" using by value 0
move all low-value to DataSourceFileName
*>===========
move low-values to v
move VT-ERROR to VARIANT-vartype of v
move DISP-E-PARAMNOTFOUND to VARIANT-VT-SCODE of v
invoke olevariant "newWithData" using v returning vOpt
move vOpt to TheDisplayObj
perform displayvariant
*>===========
*> p12 Connection Optional Variant. A range within which the query specified by SQLStatement is to be performed.
* move z'"TABLE Customers"' to Connection
invoke oleVariant "new" returning VOConnection
move length of Connection to TheStringLength
perform until Connection(TheStringLength:1) not = " "
subtract 1 from TheStringLength
end-perform
invoke VOConnection "setString"
using by value TheStringLength
by reference Connection(1:TheStringLength)
returning theErrorCode
move VOConnection to TheDisplayObj
perform displayvariant
*>===========
*> p13 SQLStatement Optional Variant. Defines query options for retrieving data.
invoke oleVariant "new" returning VOSQLstatement
move length of SQLstatement to TheStringLength
perform until SQLstatement(TheStringLength:1) not = " "
subtract 1 from TheStringLength
if TheStringLength = 0 exit perform end-if
end-perform
invoke VOSQLstatement "setString"
using by value TheStringLength
by reference SQLstatement(1:TheStringLength)
returning theErrorCode
move VOSQLstatement to TheDisplayObj
perform displayvariant
*>===========
*>===========
invoke oMMerge "OpenDataSource"
using by reference DataSourceFileName *>p1
by reference vOpt *>p2
by reference vOpt *>p3
by reference vOpt *>p4
by reference vOpt *>p5
by reference vOpt *>p6
by reference vOpt *>p7
by reference vOpt *>p8
by reference vOpt *>p9
by reference vOpt *>p10
by reference vOpt *>p11
by reference VOConnection *>p12
by reference VOSQLstatement *>p13
by reference vOpt *>p14
returning theErrorCode
end-invoke
invoke wordserver "GetSelection" returning oSelection
invoke oMMerge "GetFields" returning oMMFlds
*__________________________________
invoke oSelection "GetRange" returning oRange
invoke oMMFlds "Add" using by reference oRange
by reference z"CompanyName"
invoke oSelection "TypeParagraph"
*__________________________________
invoke oSelection "GetRange" returning oRange
invoke oMMFlds "Add" using by reference oRange
by reference z"Address"
invoke oSelection "TypeParagraph"
*__________________________________
invoke oSelection "GetRange" returning oRange
invoke oMMFlds "Add" using by reference oRange
by reference z"City"
invoke oSelection "TypeParagraph"
*__________________________________
invoke oSelection "GetRange" returning oRange
invoke oMMFlds "Add" using by reference oRange
by reference z"Country"
invoke oSelection "TypeParagraph"
*__________________________________
invoke oSelection "GetRange" returning oRange
invoke oSelection "TypeText" using z'"Dear "'
invoke oSelection "GetRange" returning oRange
invoke oMMFlds "Add" using by reference oRange
by reference z"ContactName"
invoke oSelection "TypeText" using z'","'
invoke oSelection "TypeParagraph"
invoke oSelection "TypeParagraph"
invoke oSelection "TypeText"
using "This letter is to inform you ..."
invoke oSelection "TypeParagraph"
invoke oSelection "TypeParagraph"
invoke oSelection "TypeText"
using "Sincerely, Micro Focus SupportLine";
*__________________________________
* //Execute the mail merge and then close the
* //main document without saving changes
* oMMerge.SetDestination(0); //wdSendToNewDocument = 0
invoke oMMerge "SetDestination" using by value 0
*> oMMerge.Execute(COleVariant((short)FALSE));
invoke oMMerge "Execute" using by value 0
*> oDoc.Close(COleVariant((short)FALSE), vOpt, vOpt);
invoke TheDocument "Close" using by value 0
by reference vOpt
by reference vOpt
*__________________________________
*> We no longer need the Documents collection
invoke theDocuments "finalize" returning theDocuments
*> Tell Word to quit (it won't shut down otherwise)
invoke wordServer "quit"
*> We've now finished with the Word object
invoke wordServer "finalize" returning wordServer
exit program
stop run.
...