Visual C++ と MFC を使用して Microsoft Word を自動化して差し込み印刷を実行する方法
概要
この記事では、Microsoft Visual C++および Microsoft Foundation Classes (MFC) の Automation を使用して Microsoft Word ドキュメントを作成および操作する方法について説明します。
詳細情報
この記事では、Microsoft Visual Basic を使用した同じプロセスについて説明する Microsoft サポート技術情報の記事と並行しています。
オートメーション サンプルのビルド
Microsoft Developer Studio を使用して、"AutoProject" という名前の新しい "MFC AppWizard (exe)" プロジェクトを開始します。
MFC AppWizard の手順 1 で、アプリケーションの種類として [ダイアログ ベース] を選択し、[完了] をクリックします。
[新しいプロジェクト情報] ダイアログ ボックスが表示され、作成するクラスに次のものが含まれていることを示します。
Application: CAutoProjectApp in AutoProject.h and AutoProject.cpp Dialog: CAutoProjectDlg in AutoProject.h and AutoProjectDlg.cpp
[OK] をクリックして、プロジェクトを作成します。
Visual Studio のデザイン/編集領域で、[IDD_AUTOPROJECT_DIALOG] ダイアログ ボックスが開きます。 次の 2 つの手順の手順に従って変更します。
Label コントロール (IDC_STATIC) と [キャンセル] ボタン (IDCANCEL) を削除します。
[OK] ボタンの名前を "IDRUN" に変更し、キャプションを [実行] に変更します。AutoProject.rc ダイアログ ボックスのデザイン フォームを閉じます。
[表示] メニューの [ClassWizard] をクリックします (または Ctrl + W キーを押します)。
[メッセージ マップ] タブを選択します。[オブジェクト ID] ボックスの一覧で [IDRUN] を選択し、[メッセージ] ボックスの一覧で [BN_CLICKED] を選択します。 [関数の追加] をクリックし、関数名 "OnRun" をそのまま使用します。 [OK] をクリックして ClassWizard を閉じます。
注:** この手順では、AutoProjectDLG.h という名前のヘッダー ファイルに、関数メンバー "OnRun();" の宣言を追加します。 この手順では、CAutoProjectDlg::OnRun() という名前の空のスケルトン メッセージ ハンドラー関数も AutoProjectDLG.cpp という名前のファイルに追加します。
[表示] メニューの [ClassWizard] をクリックします (または Ctrl + W キーを押します)。
[オートメーション] タブを選択します。[クラスの追加] をクリックし、[タイプ ライブラリから] を選択します。自動化するアプリケーションのオブジェクト ライブラリを選択します (この例では、Excel 97 を自動化する場合は、Microsoft Excel 8.0 オブジェクト ライブラリを選択します。既定の場所は C:\Program Files\Microsoft Office\Office\Excel8.olb です)。
Microsoft Excel 2000 を自動化する場合は、既定の場所が C:\Program Files\Microsoft Office\Office\Excel9.olb である Microsoft Excel 9.0 オブジェクト ライブラリを選択します。
Microsoft Excel 2002 と Microsoft Office Excel 2003 を自動化する場合、オブジェクト ライブラリはファイル Excel.exeに埋め込まれます。 Office 2002 のExcel.exeの既定の場所は C:\program Files\Microsoft Office\Office10\Excel.exeです。 Office 2003 のExcel.exeの既定の場所は C:\program Files\Microsoft Office\Office11\Excel.exeです。 適切なオブジェクト ライブラリを選択したら、[開く] をクリックします。 [クラスの確認] ボックスの一覧ですべてのクラスを選択し、[OK] をクリックします。
メモ [クラスの確認] ダイアログ ボックスの一覧ボックスには、Microsoft Excel タイプ ライブラリ内のすべての IDispatch インターフェイス (クラスと実質的に同じ) が含まれています。 ダイアログ ボックスの下半分には、Excel8.cpp という名前の実装ファイルに、ColeDispatchDriver() から派生した生成されたクラス ラッパーが含まれ、適切な宣言ヘッダー ファイルが Excel8.h という名前になっていることがわかります。 (Excel 2002 および Excel 2003 の場合、ファイルの名前は Excel.cpp と Excel.h です)。
メモ 自動化する Word のバージョンに適したタイプ ライブラリを選択します。 正しいタイプ ライブラリを見つける方法については、以下のリファレンス セクションを参照してください。
[OK] をクリックして[MFC ClassWizard] ダイアログ ボックスを閉じます。
COM サービス ライブラリを読み込んで有効にする CAutoProjectApp::InitInstance() 関数に次のコードを追加します。
BOOL CAutoProjectApp::InitInstance() { if(!AfxOleInit()) // Your addition starts here { AfxMessageBox("Could not initialize COM dll"); return FALSE; } // End of your addition AfxEnableControlContainer(); . . . }
AutoProject.cpp プログラム ファイルの先頭にある#include ステートメントに次の行を追加します。
#include <afxdisp.h>
stdafx.h の include ステートメントの後に、上記で作成されたヘッダー ファイル (msword8.h、msword9.h、または msword.h) の include ステートメントを AutoProjectDlg.cpp に追加します。 Word 97 の例を次に示します。
#include "stdafx.h" #include "msword8.h"
次に示すように、Automation コードを CAutoProjectDlg::OnRun メソッドに追加します。
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); } }
上記のコードを、手順 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); }
プログラムをコンパイルして実行します。 [ 実行 ] ボタンをクリックすると、Microsoft Word が開始し、サンプルレターが表示されます。 Word 2000 と Word 2002 では、一部のメソッドが変更されていることに注意してください。 これらの変更の詳細については、「リファレンス」セクションを参照してください。
関連情報
Microsoft Word 2000 と Microsoft Word 2002 を自動化するための注意事項
Microsoft Word 2000 と Microsoft Word 2002 の一部のメソッドとプロパティが変更されました。
Office Automation の詳細については、Microsoft Office Development サポート サイト (Microsoft サポート) を参照してください。