Visual C++ と MFC を使用して Microsoft Word を自動化して差し込み印刷を実行する方法

概要

この記事では、Microsoft Visual C++および Microsoft Foundation Classes (MFC) の Automation を使用して Microsoft Word ドキュメントを作成および操作する方法について説明します。

詳細情報

この記事では、Microsoft Visual Basic を使用した同じプロセスについて説明する Microsoft サポート技術情報の記事と並行しています。

オートメーション サンプルのビルド

  1. Microsoft Developer Studio を使用して、"AutoProject" という名前の新しい "MFC AppWizard (exe)" プロジェクトを開始します。

  2. MFC AppWizard の手順 1 で、アプリケーションの種類として [ダイアログ ベース] を選択し、[完了] をクリックします。

    [新しいプロジェクト情報] ダイアログ ボックスが表示され、作成するクラスに次のものが含まれていることを示します。

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

    [OK] をクリックして、プロジェクトを作成します。

  3. Visual Studio のデザイン/編集領域で、[IDD_AUTOPROJECT_DIALOG] ダイアログ ボックスが開きます。 次の 2 つの手順の手順に従って変更します。

  4. Label コントロール (IDC_STATIC) と [キャンセル] ボタン (IDCANCEL) を削除します。

  5. [OK] ボタンの名前を "IDRUN" に変更し、キャプションを [実行] に変更します。AutoProject.rc ダイアログ ボックスのデザイン フォームを閉じます。

  6. [表示] メニューの [ClassWizard] をクリックします (または Ctrl + W キーを押します)。

  7. [メッセージ マップ] タブを選択します。[オブジェクト ID] ボックスの一覧で [IDRUN] を選択し、[メッセージ] ボックスの一覧で [BN_CLICKED] を選択します。 [関数の追加] をクリックし、関数名 "OnRun" をそのまま使用します。 [OK] をクリックして ClassWizard を閉じます。

    :** この手順では、AutoProjectDLG.h という名前のヘッダー ファイルに、関数メンバー "OnRun();" の宣言を追加します。 この手順では、CAutoProjectDlg::OnRun() という名前の空のスケルトン メッセージ ハンドラー関数も AutoProjectDLG.cpp という名前のファイルに追加します。

  8. [表示] メニューの [ClassWizard] をクリックします (または Ctrl + W キーを押します)。

  9. [オートメーション] タブを選択します。[クラスの追加] をクリックし、[タイプ ライブラリから] を選択します。自動化するアプリケーションのオブジェクト ライブラリを選択します (この例では、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 のバージョンに適したタイプ ライブラリを選択します。 正しいタイプ ライブラリを見つける方法については、以下のリファレンス セクションを参照してください。

  10. [OK] をクリックして[MFC ClassWizard] ダイアログ ボックスを閉じます。

  11. 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();
      .
      .
      .
    
      }
    
  12. AutoProject.cpp プログラム ファイルの先頭にある#include ステートメントに次の行を追加します。

      #include <afxdisp.h>
    
  13. stdafx.h の include ステートメントの後に、上記で作成されたヘッダー ファイル (msword8.h、msword9.h、または msword.h) の include ステートメントを AutoProjectDlg.cpp に追加します。 Word 97 の例を次に示します。

       #include "stdafx.h"
       #include "msword8.h"
    
    
  14. 次に示すように、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);
    
    }
    }
    
    
  15. 上記のコードを、手順 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. プログラムをコンパイルして実行します。 [ 実行 ] ボタンをクリックすると、Microsoft Word が開始し、サンプルレターが表示されます。 Word 2000 と Word 2002 では、一部のメソッドが変更されていることに注意してください。 これらの変更の詳細については、「リファレンス」セクションを参照してください。

関連情報

Microsoft Word 2000 と Microsoft Word 2002 を自動化するための注意事項

Microsoft Word 2000 と Microsoft Word 2002 の一部のメソッドとプロパティが変更されました。

Office Automation の詳細については、Microsoft Office Development サポート サイト (Microsoft サポート) を参照してください。