Como automatizar o Microsoft Word para efetuar uma postalização com o Visual C++ e o MFC

Resumo

Este artigo demonstra como criar e manipular um documento do Microsoft Word através da Automatização a partir do Microsoft Visual C++ e do Microsoft Foundation Classes (MFC).

Mais Informações

Este artigo paralelamente um artigo da Base de Dados de Conhecimento Microsoft que descreve o mesmo processo através do Microsoft Visual Basic.

Criar o exemplo de automatização

  1. Com o Microsoft Developer Studio, inicia um novo projeto "AppWizard MFC (exe)" denominado "Projeto Automático".

  2. No passo 1 do AppWizard MFC, selecionar "Caixa de Diálogo Baseada" para o tipo de aplicação e, em seguida, clique em Concluir.

    A caixa de diálogo Nova Informação do Projeto é exibida e indica que as Turmas a criar incluem:

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

    Clique em OK para criar o projeto.

  3. A caixa de diálogo "IDD_AUTOPROJECT_DIALOG" é aberta na área de edição/estrutura do Visual Studio. Modifique-o de acordo com as instruções nos dois passos seguintes.

  4. Remova o controlo Etiqueta (IDC_STATIC) e o botão Cancelar (IDCANCEL).

  5. Altere o nome do botão OK para "IDRUN" e a legenda para "Executar". Feche o formulário de estrutura da caixa de diálogo Projeto Automático.rc.

  6. Clique em ClassWizard no menu Ver (ou prima Ctrl+W).

  7. Selecione o separador Mapas de Mensagens. Selecione IDRUN na caixa de listagem IDs de Objeto e selecione "BN_CLICKED" na caixa de listagem Mensagens. Clique em Adicionar Função e aceite o nome da função "AoAtivar". Clique em OK para fechar o classWizard.

    NOTA:** Este passo adiciona uma declaração para o membro da função "OnRun();" ao ficheiro de cabeçalho denominado AutoProjectDLG.h. Este passo também adiciona uma função de alça de esqueleto vazia chamada CAutoProjectDlg::OnRun() ao ficheiro denominado AutoProjectDLG.cpp.

  8. Clique em ClassWizard no menu Ver (ou prima Ctrl+W).

  9. Selecione o separador Automatização. Clique em Adicionar Turma e selecione "A partir de uma biblioteca de tipos". Navegue para selecionar a biblioteca de objetos da aplicação que pretende automatizar (para este exemplo, se estiver a automatizar o Excel 97, selecione a Biblioteca de Objetos do Microsoft Excel 8.0; a localização predefinida é C:\Program Files\Microsoft Office\Office\Excel8.olb).

    Se estiver a automatizar o Microsoft Excel 2000, selecione Biblioteca de Objetos do Microsoft Excel 9.0 para a qual a localização predefinida é C:\Program Files\Microsoft Office\Office\Excel9.olb.

    Se estiver a automatizar o Microsoft Excel 2002 e o Microsoft Office Excel 2003, a biblioteca de objetos será incorporada na biblioteca de Excel.exe. A localização predefinida Excel.exe no Office 2002 é C:\program Files\Microsoft Office\Office10\Excel.exe. A localização predefinida Excel.exe no Office 2003 é C:\program Files\Microsoft Office\Office11\Excel.exe. Depois de selecionar a biblioteca de objetos adequada, clique em Abrir. Selecione todas as turmas na lista Confirmar Turmas e, em seguida, clique em OK.

    NOTA A caixa de listagem na caixa de diálogo Confirmar Turmas contém todas as interfaces de IDispatch (que são praticamente idênticas às classes) na biblioteca de tipos do Microsoft Excel. Na parte inferior da caixa de diálogo, verá que um ficheiro de Implementação denominado Excel8.cpp contém embrulhos de classe gerados derivados de ColeDispatchDriver() e o ficheiro de cabeçalho da declaração apropriado é denominado Excel8.h. (Para o Excel 2002 e o Excel 2003, os ficheiros chamam-se Excel.cpp e Excel.h.)

    Nota Selecionar a biblioteca de tipos correta para a versão do Word que está a automatizar. Consulte a secção de referências abaixo para obter informações sobre como encontrar a biblioteca de tipos corretos.

  10. Clique em OK para fechar a caixa de diálogo MFC ClassWizard.

  11. Adicione o seguinte código à função CAutoProjectApp::InitInstance(), que carrega e ativa a biblioteca de serviços COM:

    BOOL CAutoProjectApp::InitInstance()
      {
         if(!AfxOleInit())  // Your addition starts here
         {
            AfxMessageBox("Could not initialize COM dll");
            return FALSE;
         }                 // End of your addition
    
         AfxEnableControlContainer();
      .
      .
      .
    
      }
    
  12. Adicione a seguinte linha às instruções #include mais na parte superior do ficheiro do programa AutoProject.cpp:

      #include <afxdisp.h>
    
  13. Adicione a inspeção incluir para o ficheiro de cabeçalho que foi criado acima (msword8.h, msword9.h ou msword.h) em AutoProjectDlg.cpp após a inspeção incluir para stdafx.h. Um exemplo para o Word 97 seria:

       #include "stdafx.h"
       #include "msword8.h"
    
    
  14. Adicionar código de automatização ao método CAutoProjectDlg::OnRun para que seja apresentado como apresentado abaixo:

    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. Insira o seguinte código acima no código indicado no passo 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. Compile e execute o programa. Clique no botão Executar e o Microsoft Word deverá iniciar e apresentar uma carta de exemplo. Tenha em atenção que alguns métodos mudaram com o Word 2000 e o Word 2002. Para obter mais informações sobre estas alterações, consulte a secção "Referências".

Referências

Notas para automatizar o Microsoft Word 2000 e o Microsoft Word 2002

Alguns métodos e propriedades foram alterados para o Microsoft Word 2000 e o Microsoft Word 2002.

Para obter mais informações sobre a Automatização do Office, visite o site de suporte do Desenvolvimento do Microsoft Office em: Suporte da Microsoft