Você está offline; aguardando reconexão

Como automatizar o Excel a partir do C++ sem usar MFC ou # Import

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 216686
Sumário
Existem diversas vantagens para escrever sua automação código em C++ reta. Primeiro e foremost, você pode fazer exatamente o que você deseja. Em seguida, seu código será menor, mais rápido e mais fácil depurar. E finalmente, você não será dependente de quaisquer bibliotecas. Mesmo se você estiver dedicado ao uso de MFC é classes de wrapper ou nativo COM do Visual C++ suporte (# Import), você ainda pode ser necessário para me aprofundar em entranhas de IDispatch e automação COM para contornar erros comuns e limitações com essas estruturas.
Mais Informações
Siga as etapas abaixo para compilação um Visual C++ 6.0 simples aplicativo de console que automatiza o Microsoft Office Excel usando apenas C++:
  1. Inicie o Visual C++ 6.0 e crie um novo aplicativo de Console Win32 chamado XlCpp. Escolha um aplicativo "Hello, World!" base e clique em Concluir .
  2. Abra o XlCpp.cpp gerado e adicione o código a seguir antes da função main().
    #include <ole2.h> // OLE2 Definitions// AutoWrap() - Automation helper function...HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {    // Begin variable-argument list...    va_list marker;    va_start(marker, cArgs);    if(!pDisp) {        MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);        _exit(0);    }    // Variables used...    DISPPARAMS dp = { NULL, NULL, 0, 0 };    DISPID dispidNamed = DISPID_PROPERTYPUT;    DISPID dispID;    HRESULT hr;    char buf[200];    char szName[200];        // Convert down to ANSI    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);        // Get DISPID for name passed...    hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);    if(FAILED(hr)) {        sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);        MessageBox(NULL, buf, "AutoWrap()", 0x10010);        _exit(0);        return hr;    }        // Allocate memory for arguments...    VARIANT *pArgs = new VARIANT[cArgs+1];    // Extract arguments...    for(int i=0; i<cArgs; i++) {        pArgs[i] = va_arg(marker, VARIANT);    }        // Build DISPPARAMS    dp.cArgs = cArgs;    dp.rgvarg = pArgs;        // Handle special-case for property-puts!    if(autoType & DISPATCH_PROPERTYPUT) {        dp.cNamedArgs = 1;        dp.rgdispidNamedArgs = &dispidNamed;    }        // Make the call!    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);    if(FAILED(hr)) {        sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);        MessageBox(NULL, buf, "AutoWrap()", 0x10010);        _exit(0);        return hr;    }    // End variable-argument section...    va_end(marker);        delete [] pArgs;        return hr;}						
  3. Dentro da função main(), substitua a linha printf() com o seguinte código.
       // Initialize COM for this thread...   CoInitialize(NULL);   // Get CLSID for our server...   CLSID clsid;   HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);   if(FAILED(hr)) {      ::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010);      return -1;   }   // Start server and get IDispatch...   IDispatch *pXlApp;   hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);   if(FAILED(hr)) {      ::MessageBox(NULL, "Excel not registered properly", "Error", 0x10010);      return -2;   }   // Make it visible (i.e. app.visible = 1)   {      VARIANT x;      x.vt = VT_I4;      x.lVal = 1;      AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);   }   // Get Workbooks collection   IDispatch *pXlBooks;   {      VARIANT result;      VariantInit(&result);      AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);      pXlBooks = result.pdispVal;   }   // Call Workbooks.Add() to get a new workbook...   IDispatch *pXlBook;   {      VARIANT result;      VariantInit(&result);      AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Add", 0);      pXlBook = result.pdispVal;   }   // Create a 15x15 safearray of variants...   VARIANT arr;   arr.vt = VT_ARRAY | VT_VARIANT;   {      SAFEARRAYBOUND sab[2];      sab[0].lLbound = 1; sab[0].cElements = 15;      sab[1].lLbound = 1; sab[1].cElements = 15;      arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);   }   // Fill safearray with some values...   for(int i=1; i<=15; i++) {      for(int j=1; j<=15; j++) {         // Create entry value for (i,j)         VARIANT tmp;         tmp.vt = VT_I4;         tmp.lVal = i*j;         // Add to safearray...         long indices[] = {i,j};         SafeArrayPutElement(arr.parray, indices, (void *)&tmp);      }   }   // Get ActiveSheet object   IDispatch *pXlSheet;   {      VARIANT result;      VariantInit(&result);      AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);      pXlSheet = result.pdispVal;   }   // Get Range object for the Range A1:O15...   IDispatch *pXlRange;   {      VARIANT parm;      parm.vt = VT_BSTR;      parm.bstrVal = ::SysAllocString(L"A1:O15");      VARIANT result;      VariantInit(&result);      AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);      VariantClear(&parm);      pXlRange = result.pdispVal;   }   // Set range with our safearray...   AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);   // Wait for user...   ::MessageBox(NULL, "All done.", "Notice", 0x10000);   // Set .Saved property of workbook to TRUE so we aren't prompted   // to save when we tell Excel to quit...   {      VARIANT x;      x.vt = VT_I4;      x.lVal = 1;      AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L"Saved", 1, x);   }   // Tell Excel to quit (i.e. App.Quit)   AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);   // Release references...   pXlRange->Release();   pXlSheet->Release();   pXlBook->Release();   pXlBooks->Release();   pXlApp->Release();   VariantClear(&arr);   // Uninitialize COM for this thread...   CoUninitialize();						
  4. Compilar e executar.
A função AutoWrap() simplifica a maioria dos detalhes de baixo nível envolvidos com usando IDispatch diretamente. Fique à vontade para usá-lo em suas próprias implementações. Uma limitação é que, se você passar vários parâmetros, eles precisam ser passados em ordem inversa. Por exemplo:
    VARIANT parm[3];    parm[0].vt = VT_I4; parm[0].lVal = 1;    parm[1].vt = VT_I4; parm[1].lVal = 2;    parm[2].vt = VT_I4; parm[2].lVal = 3;    AutoWrap(DISPATCH_METHOD, NULL, pDisp, L"call", 3, parm[2], parm[1], parm[0]);				
Referências
Para obter mais informações sobre como automatizar Office usando o Visual C++, clique nos números abaixo para ler os artigos na Base de dados de Conhecimento da Microsoft:
196776Automação do Office usando o Visual C++
216388B2CSE.exe converte código de automação do Visual Basic para Visual C++
(c) 1999 Microsoft Corporation, todos os direitos reservados. Contribuições de Joe Crump, Microsoft Corporation.

_com_ptr_t CComPtr XL2003 XL2007

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 216686 - Última Revisão: 05/11/2007 16:38:34 - Revisão: 5.2

Microsoft Office Excel 2007, Microsoft Office Excel 2003, Microsoft Excel 2002 Standard Edition, Microsoft Excel 2000 Standard Edition, Microsoft Excel 97 Standard Edition, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 6.0 Enterprise Edition, Microsoft Visual C++ 5.0 Professional Edition, Microsoft Visual C++ 6.0 Professional Edition, Microsoft Visual C++, 32-bit Learning Edition 6.0

  • kbmt kbautomation kbhowto KB216686 KbMtpt
Comentários
r="var m=document.createElement('meta');m.name='ms.dqp0';m.content='true';document.getElementsByTagName('head')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?">