Cara mengotomatisasi Excel dari C++ tanpa menggunakan MFC atau #import

Terjemahan Artikel Terjemahan Artikel
ID Artikel: 216686 - Melihat produk di mana artikel ini berlaku.
Perbesar semua | Perkecil semua

RINGKASAN

Ada beberapa keuntungan untuk menulis Anda otomatisasi kode dalam c ++ lurus. Pertama dan terutama, Anda dapat melakukan apa yang Anda inginkan. Selanjutnya, kode Anda akan lebih kecil, lebih cepat dan lebih mudah untuk debug. Dan akhirnya, Anda tidak akan tergantung pada perpustakaan manapun. Bahkan jika Anda didedikasikan untuk menggunakan MFC kelas pembungkus atau Visual C++ dukungan COM asli (#import), Anda mungkin masih harus menyelidiki nyali IDispatch dan COM otomatisasi untuk bekerja sekitar bug dan keterbatasan dengan kerangka ini umum.

INFORMASI LEBIH LANJUT

Ikuti langkah-langkah di bawah ini untuk membangun sederhana Visual C++ 6.0 aplikasi konsol yang mengotomatisasi Microsoft Office Excel menggunakan hanya C++:
  1. Mulai Visual C++ 6.0, dan membuat konsol Win32 baru Aplikasi bernama XlCpp. Pilih "Hello, World!" aplikasi dasar, dan klik Menyelesaikan.
  2. Buka XlCpp.cpp dihasilkan, dan tambahkan kode berikut sebelum fungsi 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. Di dalam fungsi main(), menggantikan jalur printf() dengan kode berikut.
       // 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. Mengkompilasi dan menjalankan.
Fungsi AutoWrap() menyederhanakan sebagian besar tingkat rendah rincian terlibat dengan menggunakan IDispatch secara langsung. Jangan ragu untuk menggunakannya dalam Anda sendiri implementasi. Satu surat protes adalah bahwa jika Anda melewati beberapa parameter, mereka perlu diberikan dalam urutan terbalik. Misalnya:
    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]);
				

REFERENSI

Untuk informasi lebih lanjut tentang mengotomatisasi Office dengan menggunakan Visual C++, klik nomor artikel di bawah ini untuk melihat artikel di dalam Basis Pengetahuan Microsoft:
196776Otomatisasi Office menggunakan Visual C++
216388 B2CSE.exe mengkonversi kode Visual Basic otomatisasi Visual C++
(c) Microsoft Corporation 1999, Semua Hak Dilindungi Undang-Undang. Kontribusi oleh Joe sekaligus, Microsoft Corporation.

Note This is a "FAST PUBLISH" article created directly from within the Microsoft support organization. The information contained herein is provided as-is in response to emerging issues. As a result of the speed in making it available, the materials may include typographical errors and may be revised at any time without notice. See Terms of Use for other considerations.

Properti

ID Artikel: 216686 - Kajian Terakhir: 19 September 2011 - Revisi: 2.0
Berlaku bagi:
  • 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
Kata kunci: 
kbautomation kbhowto kbmt KB216686 KbMtid
Penerjemahan Mesin
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:216686

Berikan Masukan

 

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