HOWTO: Use Microsoft Foundation Classes (MFC) to Automate Word and Create a Mail Merge for Mailing Labels (278260)



The information in this article applies to:

  • Microsoft Word 2000
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • The Microsoft Foundation Classes (MFC)

This article was previously published under Q278260

SUMMARY

This article describes how to use Microsoft Foundation Classes (MFC) to automate Microsoft Word to create and execute a mail merge for mailing labels.

MORE INFORMATION

The sample code in this article uses a tab-delimited text file (C:\Data.txt) as the data source. The text file has five fields: Contact_Name, Address, City, Postal_Code, and Country. You can use any text editor to create the text file data source. You can also use any other data source, such as a Microsoft Access database, instead of the tab-delimited text file.

When you create the data source, remember to separate the fields (columns) with tab characters and separate the records (rows) with carriage returns. For example:

Contact_Name       Address                City       Postal_Code   Country
Maria Anders       Obere Str. 57          Berlin     12209         Germany
Thomas Hardy       120 Hanover Sq.        London     WA1 1DP       UK
Hanna Moos         Forsterstr. 57         Mannheim   68306         Germany
Laurence Lebihan   12, rue des Bouchers   Marseille  13008         France  
					

Step-by-Step Sample

  1. Create a new dialog-based MFC AppWizard EXE project, and name it AutoWord.
  2. On the View menu, click ClassWizard (or press CTRL+W). On the Automation tab, click Add Class, and then click From a Type Library. Browse to the Word type library (MSWord8.olb for Word 97 or MSWord9.olb for Word 2000).NOTE: The type library is located in the same folder as Winword.exe, which is installed by default at C:\Program Files\Microsoft Office\Office.

  3. Add all of the classes in the Word type library that ClassWizard presents.
  4. Add a button named IDC_RUN to the IDD_AUTOWORD_DIALOG dialog resource.
  5. Right-click the new button and click Events. Click Add Handler to add a handler for the BN_CLICKED event to the message map. Click OK to accept the OnRun member function name.
  6. In AutoWord.cpp, append MSWord8.h (or MSWord9.h) to the list of includes:
    #include "MSWord8.h" //Use MSWord9.h for Word 2000.
    					
  7. In AutoWordDlg.cpp, replace the OnRun handler
    void CAutoWordDlg::OnRun() 
    {
         // TODO: Add your control notification handler code here
    }
    					
    with the following code:
    _Application oApp;
    _Document oDoc;
    Documents oDocs;
    MailMergeFields oMMFields;
    COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR),
                vTrue((short)TRUE),
    			vFalse((short)FALSE);
    
    void AddFieldAtSelection(CString sMergeField)
    {
        Selection oSel = oApp.GetSelection();
        Range oSelRange = oSel.GetRange();
        MailMergeField oMMField = oMMFields.Add(oSelRange, sMergeField);
    }
    
    void CAutoWordDlg::OnRun() 
    {
        
        //Start Word.
        if(!oApp.CreateDispatch("Word.Application",NULL))
        {
            AfxMessageBox("Unable to start Word.");
            return;
        }
    
        //Create a new mail merge document.
        oDocs = oApp.GetDocuments();
        oDoc = oDocs.Add(vOpt, vOpt);  //for Word 97
        //oDoc = oDocs.Add(vOpt, vOpt, vOpt, vOpt);  //for Word 2000
        MailMerge oMerge = oDoc.GetMailMerge();
    
        //Insert Fields into the document.
        oMMFields = oMerge.GetFields();
        
        Selection oSel;
        AddFieldAtSelection("Contact_Name");
        oSel = oApp.GetSelection();
        oSel.TypeParagraph();
        AddFieldAtSelection("Address");
        oSel = oApp.GetSelection();
        oSel.TypeParagraph();
        AddFieldAtSelection("City");
        oSel = oApp.GetSelection();
        oSel.TypeText(" ");
        AddFieldAtSelection("Postal_Code");
        oSel = oApp.GetSelection();
        oSel.TypeText(" -- ");
        AddFieldAtSelection("Country");
        oSel.ReleaseDispatch();
    
        //Add an AutoText entry for the label layout.
        Template oNormal = oApp.GetNormalTemplate();
        AutoTextEntries oATEs = oNormal.GetAutoTextEntries();
        Range oRange = oDoc.GetContent();
        AutoTextEntry oATE = oATEs.Add("MyLabelLayout", oRange);
        oATEs.ReleaseDispatch();
        oNormal.ReleaseDispatch();
    
        //Clear the document because the AutoText entry has been added and the document
        //text and fields are no longer needed.
        oRange.Delete(vOpt, vOpt);
        oRange.ReleaseDispatch();
    
        //Set up the mail merge type as mailing labels and specify the data source.
        oMerge.SetMainDocumentType(1L); //1=wdMailingLabels
        oMerge.OpenDataSource("C:\\Data.txt", vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt);
    
        //Create the new document for the merge using the AutoText entry previously added.
        MailingLabel oMLabel = oApp.GetMailingLabel();
        _Document oFinal = oMLabel.CreateNewDocument(COleVariant("5160"), COleVariant(""), COleVariant("MyLabelLayout"), vOpt, COleVariant(4L));
        oFinal.ReleaseDispatch();
        oMLabel.ReleaseDispatch();
    
        //Execute the mail merge.
        oMerge.SetDestination(0);   //wdSendToNewDocument=0
        oMerge.Execute(vOpt);
        oMMFields.ReleaseDispatch();
        oMerge.ReleaseDispatch();
    
        //Delete the AutoText entry.
        oATE.Delete();
        oATE.ReleaseDispatch();
    
        //Close the original mail merge document and make Word visible.
        oDoc.Close(vFalse, vOpt, vOpt);
        oDoc.ReleaseDispatch();
        oApp.SetVisible(TRUE);
        oDocs.ReleaseDispatch();
        oApp.ReleaseDispatch();
    }
    					
    NOTE: If you did not save the tab-delimited text file as C:\Data.txt, modify the OpenDataSource method to specify the correct path to the file. Also note that if you wrapped the classes in the Word 2000 type library instead of the Word 97 type library, you must add two additional optional arguments to the call to the Add method, as illustrated in the code comment.

  8. In AutoWord.cpp, add the following line to the beginning of the CAutoWordApp::InitInstance() method:
        AfxOleInit();
    					
  9. Build the project.
  10. Press F5 to run the project.
  11. Click the IDC_RUN button.
A new document is presented in Word. The document consists of formatted mailing labels created with data that is extracted from the tab-delimited text file (C:\Data.txt).

REFERENCES

For additional information, click the article numbers below to view the articles in the Microsoft Knowledge Base:

178749 HOWTO: Create Automation Project Using MFC and a Type Library

258512 HOWTO: Automate Word from Visual Basic to Create a Mail Merge for Mailing Labels

220911 HOWTO: Automate Word 97 to Do Mail Merge with Visual C++ and MFC



(c) Microsoft Corporation 2000, All Rights Reserved. Contributions by Lori B. Turner, Microsoft Corporation.


Modification Type:MinorLast Reviewed:7/13/2004
Keywords:kbAutomation kbhowto KB278260