MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Запись данных в открытый Excel файл с помощью COM OLE C++"
Answer 939486
Для подключения к запущенному экземпляру Excel необходимо использовать вызов GetActiveObject вместо CoCreateInstance. Далее, для получения доступа к открытому документу нужно заменить вызов метода Add на вызов свойства Item с индексом 1. Получаем такой код:
#include <stdlib.h> #include <stdio.h> #include <windows.h> #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) { MessageBoxA(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)) { printf("IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr); getchar(); _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)) { printf("IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr); getchar(); _exit(0); return hr; } // End variable-argument section... va_end(marker); delete[] pArgs; return hr; } int main(int argc, char **argv) { // Initialize COM for this thread... CoInitialize(NULL); // Get CLSID for our server... CLSID clsid; HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid); if (FAILED(hr)) { ::MessageBoxA(NULL, "CLSIDFromProgID() failed", "Error", 0x10010); return -1; } IUnknown* pUnk; hr = GetActiveObject(clsid, NULL, &pUnk); if (FAILED(hr)) { ::MessageBoxA(NULL, "GetActiveObject failed!", "Error", 0x10010); return -2; } IDispatch *pXlApp; hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pXlApp); if (FAILED(hr)) { ::MessageBoxA(NULL, "QueryInterface failed!", "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, (LPOLESTR)L"Visible", 1, x); } // Get Workbooks collection IDispatch *pXlBooks; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, (LPOLESTR)L"Workbooks", 0); pXlBooks = result.pdispVal; } //Open workbook IDispatch *pXlBook; { VARIANT result; VariantInit(&result); VARIANT index; VariantInit(&index); index.vt = VT_INT; index.intVal = 1; AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, (LPOLESTR)L"Item",1, index); pXlBook = result.pdispVal; VariantClear(&index); } // 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, (LPOLESTR)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, (LPOLESTR)L"Range", 1, parm); VariantClear(&parm); pXlRange = result.pdispVal; } // Set range with our safearray... AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, (LPOLESTR)L"Value", 1, arr); // Save workbook VARIANT var_result; VariantInit(&var_result); AutoWrap(DISPATCH_METHOD, &var_result, pXlBook, (LPOLESTR)L"Save", 0); VariantClear(&var_result); // Release references... pUnk->Release(); pXlRange->Release(); pXlSheet->Release(); pXlBook->Release(); pXlBooks->Release(); pXlApp->Release(); VariantClear(&arr); printf("All done! Press any key to exit\n"); getchar(); // Uninitialize COM for this thread... CoUninitialize(); return 0; }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.