Jak zautomatyzować Excel z języka C++, bez korzystania z usługi MFC i #import

Tłumaczenia artykułów Tłumaczenia artykułów
Numer ID artykułu: 216686 - Zobacz jakich produktów dotyczą zawarte w tym artykule porady.
Rozwiń wszystko | Zwiń wszystko

Streszczenie

Nie ma kilka zalet, na piśmie swoje automatyzacji kod w języku C++ proste. Przede wszystkim można wykonać dokładnie. Następnie kod będzie mniejsze, szybsze i łatwiejsze do debugowania. I wreszcie, nie będzie zależna od żadnych bibliotek. Nawet jeśli dedykowane przy użyciu usługi MFC firmy klasy otoki lub Visual C++ macierzysta obsługa modelu COM (#import), mogą nadal mieć gra zawiera wnętrzności IDispatch i automatyzację COM do pracy wokół wspólnej usterki i ograniczenia z tych środowisk.

Więcej informacji

Wykonaj poniższe kroki, aby utworzyć prosty Visual C++ 6.0 aplikacji konsoli, który automatyzuje programu Microsoft Office Excel przy użyciu tylko C++:
  1. Uruchom Visual C++ 6.0 i utworzyć nową konsolę Win32 Wniosek o nazwie wybierz XlCpp aplikacji "Hello, World!" podstawowy, a następnie kliknij przycisk Zakończ.
  2. Otwórz wygenerowane XlCpp.cpp i Dodaj następujący kod przed funkcję 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. Wewnątrz funkcji main() zastąpić wiersz printf() Poniższy kod.
       // 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. Skompilować i uruchomić.
Funkcja AutoWrap() upraszcza większość niskiego poziomu Szczegóły zajmujące się bezpośrednio za pomocą interfejsu IDispatch. Swobodnie używać go we własnych implementacje. Jedno zastrzeżenie: jest to, że jeżeli przekazać wiele parametrów muszą należy przekazać w kolejności odwrotnej. Na przykład:
    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]);
				

Materiały referencyjne

Aby uzyskać więcej informacji dotyczących automatyzacji pakietu Office przy użyciu języka Visual C++ kliknij następujące numery artykułów w celu wyświetlenia tych artykułów z bazy wiedzy Microsoft Knowledge Base:
196776Automatyzacji pakietu Office przy użyciu języka Visual C++
216388 B2CSE.exe konwertuje automatyzację języka Visual Basic kodu Visual C++
(c) 1999 Microsoft Corporation Wszelkie prawa zastrzeżone. Składki przez Joe Crump, firma Microsoft Corporation.

Właściwości

Numer ID artykułu: 216686 - Ostatnia weryfikacja: 6 października 2011 - Weryfikacja: 3.0
Informacje zawarte w tym artykule dotyczą:
  • Microsoft Office Excel 2007
  • 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++ 5.0 Professional Edition
Słowa kluczowe: 
kbautomation kbhowto kbmt KB216686 KbMtpl
Przetłumaczone maszynowo
WAŻNE: Ten artykuł nie został przetłumaczony przez człowieka, tylko przez oprogramowanie do tłumaczenia maszynowego firmy Microsoft. Firma Microsoft oferuje zarówno artykuły tłumaczone przez ludzi, jak i artykuły tłumaczone maszynowo, dzięki czemu każdy użytkownik może uzyskać dostęp do całej zawartości bazy wiedzy Knowledge Base we własnym języku. Prosimy jednak pamiętać, że artykuły przetłumaczone maszynowo nie zawsze są doskonałe. Mogą zawierać błędy słownictwa, składni i gramatyki, przypominające błędy robione przez osoby, dla których język użytkownika nie jest językiem ojczystym. Firma Microsoft nie odpowiada za wszelkie nieścisłości, błędy lub szkody spowodowane nieprawidłowym tłumaczeniem zawartości oraz za wykorzystanie tej zawartości przez klientów. Oprogramowanie do tłumaczenia maszynowego jest często aktualizowane przez firmę Microsoft.
Anglojęzyczna wersja tego artykułu to:216686

Przekaż opinię

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com