2011-12-23 34 views
2

開いたExcelセルでExcel :: Windowポインタから実際の値に移動する方法を知っている人は、教えてください。 ここにタスク条件があります: - Excelは現在、1枚のブックに1枚のブックがある単一のウィンドウで実行されています - 一部のセルにはデータがあります(セル[1,1] ) 質問は、1つのセルにデータがあり、セルが[1,1]でデータが "a"であることを調べる方法です。ここで開始する は、コードスニペットです:C++でExcelセルの値を取得する方法

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; 
} 

答えて

4

が最終的に使用するコードです:

#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://www.northatlantawebdesign.com/index.php/2009/07/15/access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility/ おかげでから最初のサンプルが、http://support.microsoft.com/kb/216686/en-us?fr=1から撮影されています。

+0

pXlSheetと0xCCCCCCCCを比較する理由) pXlSheetを初期化しました。 –

0

ダニール、

私はあなたがそれにアクセスするために、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とそれを適切に使用してください。

希望します。ここで

+0

こんにちは、テオ。コードスニペットありがとう。残念なことに、これは主なアイデアだけを示しています。私は最初から明確です。このスニペットを自分のコードに挿入しようとすると、互換性のないタイプのような、多くのコードエラーが発生します。 C#のようにこのコードをどのように扱うかはあまり明らかではありません。また、ドキュメンテーションは参考書として役立ちますが、私が必要とするのは指導です。したがって、問題はまだ開かれています。 –

関連する問題