Comment automatiser Microsoft Word pour effectuer un publipostage à l’aide de Visual C++ et MFC

Résumé

Cet article montre comment créer et manipuler un document Microsoft Word à l’aide d’Automation à partir de Microsoft Visual C++ et de Microsoft Foundation Classes (MFC).

Informations supplémentaires

Cet article est parallèle à un article de la Base de connaissances Microsoft qui décrit le même processus à l’aide de Microsoft Visual Basic.

Génération de l’exemple d’automatisation

  1. Avec Microsoft Developer Studio, démarrez un nouveau projet « MFC AppWizard (exe) » nommé « AutoProject ».

  2. À l’étape 1 de MFC AppWizard, choisissez « Dialog Based » pour le type d’application, puis cliquez sur Terminer.

    La boîte de dialogue Informations sur le nouveau projet s’affiche et indique que les classes à créer sont les suivantes :

    Application: CAutoProjectApp in AutoProject.h and AutoProject.cpp
    Dialog: CAutoProjectDlg in AutoProject.h and AutoProjectDlg.cpp
    

    Cliquez sur OK pour créer le projet.

  3. La boîte de dialogue « IDD_AUTOPROJECT_DIALOG » s’ouvre dans la zone de conception/modification de Visual Studio. Modifiez-le conformément aux instructions des deux étapes suivantes.

  4. Supprimez le contrôle Label (IDC_STATIC) et le bouton Annuler (IDCANCEL).

  5. Remplacez le nom du bouton OK par « IDRUN » et la légende par « Exécuter ». Fermez le formulaire de conception de boîte de dialogue AutoProject.rc.

  6. Cliquez sur ClassWizard dans le menu Affichage (ou appuyez sur Ctrl+W).

  7. Sélectionnez l’onglet Cartes des messages. Sélectionnez IDRUN dans la zone de liste ID d’objet, puis sélectionnez « BN_CLICKED » dans la zone de liste Messages. Cliquez sur Ajouter une fonction et acceptez le nom de la fonction « OnRun ». Cliquez sur OK pour fermer ClassWizard.

    REMARQUE:** Cette étape ajoute une déclaration pour le membre de fonction « OnRun(); » au fichier d’en-tête nommé AutoProjectDLG.h. Cette étape ajoute également une fonction de gestionnaire de messages squelette vide nommée CAutoProjectDlg::OnRun() au fichier nommé AutoProjectDLG.cpp.

  8. Cliquez sur ClassWizard dans le menu Affichage (ou appuyez sur Ctrl+W).

  9. Sélectionnez l’onglet Automation. Cliquez sur Ajouter une classe et choisissez « À partir d’une bibliothèque de types ». Accédez à la bibliothèque d’objets pour l’application que vous souhaitez automatiser (pour cet exemple, si vous automatiser Excel 97, choisissez la bibliothèque d’objets Microsoft Excel 8.0 ; l’emplacement par défaut est C:\Program Files\Microsoft Office\Office\Excel8.olb).

    Si vous automatisons Microsoft Excel 2000, choisissez Bibliothèque d’objets Microsoft Excel 9.0 pour laquelle l’emplacement par défaut est C:\Program Files\Microsoft Office\Office\Excel9.olb.

    Si vous automatisons Microsoft Excel 2002 et Microsoft Office Excel 2003, la bibliothèque d’objets est incorporée dans le fichier Excel.exe. L’emplacement par défaut pour Excel.exe dans Office 2002 est C:\program Files\Microsoft Office\Office10\Excel.exe. L’emplacement par défaut pour Excel.exe dans Office 2003 est C:\program Files\Microsoft Office\Office11\Excel.exe. Une fois que vous avez sélectionné la bibliothèque d’objets appropriée, cliquez sur Ouvrir. Sélectionnez toutes les classes de la liste Confirmer les classes, puis cliquez sur OK.

    NOTE La zone de liste de la boîte de dialogue Confirmer les classes contient toutes les interfaces IDispatch (qui sont pratiquement identiques aux classes) dans la bibliothèque de types Microsoft Excel. Dans la moitié inférieure de la boîte de dialogue, vous verrez qu’un fichier d’implémentation nommé Excel8.cpp contient des wrappers de classe générés dérivés de ColeDispatchDriver(), et que le fichier d’en-tête de déclaration approprié est nommé Excel8.h. (Pour Excel 2002 et Excel 2003, les fichiers sont nommés Excel.cpp et Excel.h.)

    Note Choisissez la bibliothèque de types appropriée pour la version de Word que vous automatiserez. Pour plus d’informations sur la recherche de la bibliothèque de types correcte, consultez la section références ci-dessous.

  10. Cliquez sur OK pour fermer la boîte de dialogue MFC ClassWizard.

  11. Ajoutez le code suivant à la fonction CAutoProjectApp::InitInstance(), qui charge et active la bibliothèque de services COM :

    BOOL CAutoProjectApp::InitInstance()
      {
         if(!AfxOleInit())  // Your addition starts here
         {
            AfxMessageBox("Could not initialize COM dll");
            return FALSE;
         }                 // End of your addition
    
         AfxEnableControlContainer();
      .
      .
      .
    
      }
    
  12. Ajoutez la ligne suivante aux instructions #include en haut du fichier programme AutoProject.cpp :

      #include <afxdisp.h>
    
  13. Ajoutez l’instruction Include pour le fichier d’en-tête créé ci-dessus (msword8.h, msword9.h ou msword.h) dans AutoProjectDlg.cpp après l’instruction include pour stdafx.h. Voici un exemple pour Word 97 :

       #include "stdafx.h"
       #include "msword8.h"
    
    
  14. Ajoutez du code Automation à la méthode CAutoProjectDlg::OnRun pour qu’elle apparaisse comme indiqué ci-dessous :

    void CAutoProjectDlg::OnRun()
    {
    _Application oWord;
    Documents oDocs;
    _Document oDoc;
    Selection oSelection;
    Paragraphs oParagraphs;
    Tables oTables;
    Table oTable;
    Range oRange;
    Columns oColumns;
    Column oColumn;
    Rows oRows;
    Row oRow;
    
    Cells oCells;
    Cell oCell; 
    Shading oShading;
    Hyperlinks oHyperlinks;
    MailMerge oMailMerge;
    MailMergeFields oMailMergeFields;
    COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR),
            vtTrue((short)TRUE),
    vtFalse((short)FALSE);
    CString StrToAdd;
    
    // Create an instance of Word
    if (!oWord.CreateDispatch("Word.Application")) {
    AfxMessageBox("Word failed to start!");
    } else {
    // Set the visible property
    oWord.SetVisible(TRUE);
    // Add a new document
    oDocs = oWord.GetDocuments();
    oDoc = oDocs.Add(vtOptional,vtOptional);
    
    CreateMailMergeDataFile(&oWord,&oDoc);
    // Add the address header
    
    StrToAdd = "State University\r\nElectrical Engineering " \ 
           "Department";
    oSelection = oWord.GetSelection();
    
    oParagraphs = oSelection.GetParagraphs();
    oParagraphs.SetAlignment(1);  // 1 = wdAlignParagraphCenter  
    oSelection.TypeText(StrToAdd);
    
    InsertLines(&oSelection,4);
    
    oParagraphs.SetAlignment(0);  // 0 = wdAlignParagraphLeft
    oMailMerge = oDoc.GetMailMerge();
    oMailMergeFields = oMailMerge.GetFields();
    oMailMergeFields.Add(oSelection.GetRange(),"FirstName");
    oSelection.TypeText(" ");
    oMailMergeFields.Add(oSelection.GetRange(),"LastName");
    oSelection.TypeParagraph();
    oMailMergeFields.Add(oSelection.GetRange(),"Address");
    oSelection.TypeParagraph();
    oMailMergeFields.Add(oSelection.GetRange(),"CityStateZip");
    
    InsertLines(&oSelection,4);
    // Set the paragraph alignment to Right justified
    oParagraphs = oSelection.GetParagraphs();
    
    oParagraphs.SetAlignment(2);  // 2 = wdAlignParagraphRight
    // Insert the current date
    oSelection.InsertDateTime(COleVariant("dddd, MMMM dd, yyyy"),\ 
     vtFalse,vtOptional);
    
    InsertLines(&oSelection,2);
    
    // Reset the justification to Justify
    
    oParagraphs = oSelection.GetParagraphs();
    oParagraphs.SetAlignment(3);  // 3 = wdAlignParagraphJustify
    
    oSelection.TypeText("Dear ");
    oMailMergeFields.Add(oSelection.GetRange(),"FirstName");
    oSelection.TypeText(",");
    
    InsertLines(&oSelection,2);
    
    // Add the body of the message
    StrToAdd = "Thank you for your recent request for next " \ 
           "semester's class schedule for the Electrical " \ 
           "Engineering Department.  Enclosed with this letter " \ 
           "is a booklet containing all the classes offered " \ 
           "next semester at State University.  Several new " \ 
           "classes will be offered in the Electrical " \ 
              "Engineering Department next semester.  These " \ 
           "classes are listed below.";
    oSelection.TypeText(StrToAdd);
    
    InsertLines(&oSelection,2);
    
    // Add a new table with 9 rows and 4 columns
    oRange = oSelection.GetRange();
    oTables = oDoc.GetTables();
    oTable = oTables.Add(oRange,9,4);
    
    // Set the width of each column
    oColumns = oTable.GetColumns();
    oColumn = oColumns.Item(1);
    oColumn.SetWidth(51.0,0);  // 0 = wdAdjustNone
    oColumn = oColumns.Item(2);
    oColumn.SetWidth(198.0,0);  // 0 = wdAdjustNone
    oColumn = oColumns.Item(3);
    oColumn.SetWidth(100.0,0);  // 0 = wdAdjustNone
    oColumn = oColumns.Item(4);
    oColumn.SetWidth(111.0,0);  // 0 = wdAdjustNone
    
    // Set the shading for row 1 to wdGray25
    oRows = oTable.GetRows();
    oRow = oRows.Item(1);
    oCells = oRow.GetCells();
    oShading = oCells.GetShading();
    oShading.SetBackgroundPatternColorIndex(16); // 16 = wdGray25
    
    // Turn on BOLD for the first row
    oRange = oRow.GetRange();
    oRange.SetBold(TRUE);
    
    // Set the alignment for cell (1,1) to center
    oCell = oTable.Cell(1,1);
    oRange = oCell.GetRange();
    oParagraphs = oRange.GetParagraphs();
    oParagraphs.SetAlignment(1);  // 1 = wdAlignParagraphCenter
    
    // Fill in the class schedule data
    FillRow(&oTable,1,"Class Number","Class Name",\ 
    "Class Time","Instructor");
    FillRow(&oTable,2, "EE220", "Introduction to Electronics II", \ 
    "1:00-2:00 M,W,F", "Dr. Jensen");
    FillRow(&oTable,3, "EE230", "Electromagnetic Field Theory I", \ 
    "10:00-11:30 T,T", "Dr. Crump");
    FillRow(&oTable,4, "EE300", "Feedback Control Systems", \ 
    "9:00-10:00 M,W,F", "Dr. Murdy");
    FillRow(&oTable,5, "EE325", "Advanced Digital Design", \ 
    "9:00-10:30 T,T", "Dr. Alley");
    FillRow(&oTable,6, "EE350", "Advanced Communication Systems", \ 
    "9:00-10:30 T,T", "Dr. Taylor");
    FillRow(&oTable,7, "EE400", "Advanced Microwave Theory", \ 
    "1:00-2:30 T,T", "Dr. Lee");
    FillRow(&oTable,8, "EE450", "Plasma Theory", \ 
    "1:00-2:00 M,W,F", "Dr. Davis");
    FillRow(&oTable,9, "EE500", "Principles of VLSI Design", \ 
    "3:00-4:00 M,W,F", "Dr. Ellison");
    
    // Go to the end of the document
    oSelection.GoTo(COleVariant((short)3), // 3 = wdGoToLine
    COleVariant((short)-1),vtOptional,vtOptional);  // -1 = wdGoToLast
    
    InsertLines(&oSelection,2);
    
    // Add closing text
    StrToAdd = "For additional information regarding the " \ 
                 "Department of Electrical Engineering, " \ 
                 "you can visit our website at ";
    oSelection.TypeText(StrToAdd);
    
    // Add a hyperlink to the homepage
    oHyperlinks = oSelection.GetHyperlinks();
    oHyperlinks.Add(oSelection.GetRange(),\ 
    COleVariant("http://www.ee.stateu.tld"),vtOptional);
    
    // Finish adding closing text
    StrToAdd = ".  Thank you for your interest in the classes " \ 
                 "offered in the Department of Electrical " \ 
                 "Engineering.  If you have any other questions, " \ 
                 "please feel free to give us a call at (999) " \ 
                 "555-1212.\r\n\r\n" \ 
                 "Sincerely,\r\n\r\n" \ 
                 "Kathryn M. Hinsch\r\n" \ 
                 "Department of Electrical Engineering\r\n";
    oSelection.TypeText(StrToAdd);
    
    // Perform mail merge
    oMailMerge.SetDestination(0); // 0 = wdSendToNewDocument
    oMailMerge.Execute(vtFalse);
    
    // Close the original form document
    oDoc.SetSaved(TRUE);
    oDoc.Close(vtFalse,vtOptional,vtOptional);
    
    }
    }
    
    
  15. Insérez le code suivant ci-dessus dans le code fourni à l’étape 3 :

    void InsertLines(Selection *pSelection, int NumLines)
    {
    int iCount;
    
    // Insert NumLines blank lines
    for (iCount = 1; iCount <= NumLines; iCount++)
    pSelection->TypeParagraph();
    }
    
    void FillRow(Table *pTable,int Row, CString Text1, 
     CString Text2, CString Text3, CString Text4)
    {
    Cell oCell;
    Range oRange;
    
    // Insert data into the specific cell
    oCell = pTable->Cell(Row,1);
    oRange = oCell.GetRange();
    oRange.InsertAfter(Text1);
    oCell = pTable->Cell(Row,2);
    oRange = oCell.GetRange();
    oRange.InsertAfter(Text2);
    oCell = pTable->Cell(Row,3);
    oRange = oCell.GetRange();
    oRange.InsertAfter(Text3);
    oCell = pTable->Cell(Row,4);
    oRange = oCell.GetRange();
    oRange.InsertAfter(Text4);
    
    }
    
    void CreateMailMergeDataFile(_Application *pApp,_Document *pDoc)
    {
      _Document oDataDoc;
      MailMerge oMailMerge;
      Documents oDocs;
      Tables oTables;
      Table oTable;
      Rows oRows;
      int iCount;
      COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR),
    vtFalse((short)FALSE);
    
    // Create a data source at C:\DataDoc.doc containing the field data
      oMailMerge = pDoc->GetMailMerge();
      oMailMerge.CreateDataSource(COleVariant("C:\\DataDoc.doc"), \ 
            vtOptional,vtOptional, \ 
            COleVariant("FirstName, LastName, Address,CityStateZip"),\ 
            vtOptional, vtOptional,vtOptional,vtOptional,vtOptional);
      // Open the file to insert data
      oDocs = pApp->GetDocuments();
      oDataDoc = oDocs.Open(COleVariant("C:\\DataDoc.doc"), \ 
           vtOptional,vtOptional,vtOptional,vtOptional,\ 
           vtOptional,vtOptional,vtOptional,vtOptional,\ 
           vtOptional);
      oTables = oDataDoc.GetTables();
      oTable = oTables.Item(1);
      oRows = oTable.GetRows();
      for (iCount=1; iCount<=2; iCount++)  
        oRows.Add(vtOptional);
    
    // Fill in the data
      FillRow(&oTable, 2, "Steve", "DeBroux", \ 
            "4567 Main Street", "Buffalo, NY  98052");
      FillRow(&oTable, 3, "Jan", "Miksovsky", \ 
            "1234 5th Street", "Charlotte, NC  98765");
      FillRow(&oTable, 4, "Brian", "Valentine", \ 
            "12348 78th Street  Apt. 214", "Lubbock, TX  25874");
      // Save and close the file
      oDataDoc.Save();
      oDataDoc.Close(vtFalse,vtOptional,vtOptional);
    }
    
    
  16. Compilez et exécutez votre programme. Cliquez sur le bouton Exécuter et Microsoft Word doit démarrer et afficher un exemple de lettre. Notez que certaines méthodes ont changé avec Word 2000 et Word 2002. Pour plus d’informations sur ces modifications, consultez la section « Références ».

References

Notes relatives à l’automatisation de Microsoft Word 2000 et Microsoft Word 2002

Certaines méthodes et propriétés ont changé pour Microsoft Word 2000 et Microsoft Word 2002.

Pour plus d’informations sur Office Automation, visitez le site de support microsoft Office Development à l’adresse : Support Microsoft