Skip to main content

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.

...

Attachments:

KB22663.zip

Old KB# 4176