[英]How to get Excel cell value in C++
如果有人知道如何從Excel :: Window指針轉到打開的Excel單元格中的實際值,請告訴我。 這是任務的條件:-Excel當前正在一個窗口中運行,並且一張工作簿在一張紙上-一些單元格具有數據(為簡單起見,假設只有一個單元格[1,1]具有數據,即“ a”)如何確定只有一個單元格具有數據,並且單元格為[1,1]並且數據為“ a”。 從這里開始是一個代碼片段:
int main( int argc, CHAR* argv[])
{
CoInitialize( NULL );
HWND excelWindow = FindWindow(L"XLMAIN", NULL);
EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1);
return 0;
}
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM)
{
WCHAR szClassName[64];
if(GetClassNameW(hwnd, szClassName, 64))
{
if(_wcsicmp(szClassName, L"EXCEL7") == 0)
{
Excel::Window* pWindow = NULL;
HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&pWindow);
if(hr == S_OK)
{
// Here we need to answer the question using pWindow
pWindow->Release();
}
return false;
}
}
return true;
}
這是最終使用的代碼:
#include <windows.h>
#include <oleacc.h>
#import "C:\Program Files (x86)\Common Files\microsoft shared\OFFICE14\MSO.DLL" no_implementation rename("RGB", "ExclRGB") rename("DocumentProperties", "ExclDocumentProperties") rename("SearchPath", "ExclSearchPath")
#import "C:\Program Files (x86)\Common Files\microsoft shared\VBA\VBA6\VBE6EXT.OLB" no_implementation
#import "C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE" rename("DialogBox", "ExclDialogBox") rename("RGB", "ExclRGB") rename("CopyFile", "ExclCopyFile") rename("ReplaceText", "ExclReplaceText")
#include <string>
using std::string;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM)
{
WCHAR szClassName[64];
if(GetClassNameW(hwnd, szClassName, 64))
{
if(_wcsicmp(szClassName, L"EXCEL7") == 0)
{
//Get AccessibleObject
Excel::Window* pWindow = NULL;
IDispatch* pXlSheet = NULL;
HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&pWindow);
if(hr == S_OK)
{
try {
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pWindow, L"ActiveSheet", 0);
pXlSheet = result.pdispVal;
_variant_t sheetName;
VariantInit(&sheetName);
if ((pXlSheet != NULL) && (pXlSheet != (IDispatch*)0xCCCCCCCC))
AutoWrap(DISPATCH_PROPERTYGET, &sheetName, pXlSheet, L"Name", 0);
// get cell which you need
string location = "C5";
location += ":" + location; // cell is a range with the same start/end cells
OLECHAR *sOleText=new OLECHAR[location.length()+1];
mbstowcs(sOleText,location.c_str(),location.length()+1);
IDispatch *pXlRange; // Get Range from Sheet
VARIANT parm;
parm.vt = VT_BSTR;
parm.bstrVal = ::SysAllocString(sOleText);
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
VariantClear(&parm);
pXlRange = result.pdispVal;
Excel::RangePtr cell = pXlRange;
Excel::CharactersPtr ptr = cell->Characters;
_bstr_t text = ptr->Text; // here is needed text
} catch (...) { }
}
return false; // Stops enumerating through children
}
}
return true;
}
void main( int argc, CHAR* argv[])
{
CoInitialize(NULL);
HWND excelWindow = FindWindow(L"XLMAIN", NULL);
EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1);
CoUninitialize();
}
AutoWrap()函數取自http://support.microsoft.com/kb/216686/en-us?fr=1 ,而初始示例取自http://www.northatlantawebdesign.com/index.php/ 2009/07/15 / access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility /感謝所有提供幫助的人。
丹尼爾,
我相信您正在使用Excel COM進行訪問。 我從未使用C ++做到這一點,但我想它應該與C#沒什么大不同。 您最艱巨的任務應該是導入必要的庫。 但我相信您已經做到了。
您應該使用這樣的東西:
int full_cells = 0;
Excel::_Worksheet worksheet = pWindow->ActiveSheet;
for(int j = 1; j < worksheet.Columns.Count; j++)
{
for (int i = 1; i < worksheet.Rows.Count; i++)
{
if(worksheet.Cells[i][j].Value != "")
{
full_cells++;
cout << worksheet.Cells[i][j].Value;
}
}
}
請注意,我尚未測試此代碼。 我只是向您展示它的外觀。 您應該在這里閱讀文檔: http : //msdn.microsoft.com/en-us/library/ms262200.aspx並適當地使用它。
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.