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
Avec Microsoft Developer Studio, démarrez un nouveau projet « MFC AppWizard (exe) » nommé « AutoProject ».
À 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.
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.
Supprimez le contrôle Label (IDC_STATIC) et le bouton Annuler (IDCANCEL).
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.
Cliquez sur ClassWizard dans le menu Affichage (ou appuyez sur Ctrl+W).
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.
Cliquez sur ClassWizard dans le menu Affichage (ou appuyez sur Ctrl+W).
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.
Cliquez sur OK pour fermer la boîte de dialogue MFC ClassWizard.
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(); . . . }
Ajoutez la ligne suivante aux instructions #include en haut du fichier programme AutoProject.cpp :
#include <afxdisp.h>
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"
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); } }
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); }
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