2008-10-02 10 views
2

J'ai une application Windows C++ existante qui lie à ATL. Je dois ouvrir un fichier Excel existant et accéder à certaines propriétés. Une des choses que je dois faire est de déterminer si l'utilisateur consulte actuellement le fichier Excel.Comment ouvrir le fichier existant en utilisant COM/ATL (pas MFC)

Nous pouvons supposer que l'utilisateur a installé Excel, même si vous ne savez pas quelle version.

Quel est le code C++/COM à attacher à un fichier Excel existant? Comment puis-je déterminer si le fichier est actuellement ouvert par une instance d'Excel? Supposons que je connais le nom de fichier. J'ai fait un googled autour pendant 15 minutes mais n'ai pas découvert comment faire ceci sans MFC.

Répondre

3

Beau défi. Et parce qu'un défi ne peut pas être refusé je me suis assis devant Visual Studio et voici une solution possible.

#include <windows.h> 
#include <iostream> 

using namespace std; 

#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\MSO.DLL" \ 
    rename("RGB", "MSORGB") \ 
    rename("DocumentProperties", "MSDocumentProperties") 

using namespace Office; 

#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB" 

using namespace VBIDE; 

#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE" \ 
    rename("DialogBox", "ExcelDialogBox") \ 
    rename("RGB", "ExcelRGB") \ 
    rename("CopyFile", "ExcelCopyFile") \ 
    rename("ReplaceText", "ExcelReplaceText") 

void DumpCOMError(_com_error& e) { 
    wcout << L"Error:" << endl; 
    wcout << L" Code = " << hex << e.Error() << endl; 
    wcout << L" Code meaning = " << e.ErrorMessage() << endl; 
    _bstr_t bstrSource(e.Source()); 
    _bstr_t bstrDescription(e.Description()); 
    wcout << L" Source = " << bstrSource << endl; 
    wcout << L" Description = " << bstrDescription << endl; 
} 

HRESULT IsXlsFileOpen(LPWSTR FileName, BOOL& file_open) { 
    Excel::_ApplicationPtr pApplication; 
    HRESULT hr = E_FAIL; 
    if (FAILED(hr = pApplication.CreateInstance(L"Excel.Application"))) { 
     file_open = FALSE; 
     return hr; 
    } 

    _variant_t varOption(static_cast<long>(DISP_E_PARAMNOTFOUND), VT_ERROR); 
    Excel::_WorkbookPtr pBook; 

    try { 
     pBook = pApplication->Workbooks->Open(
         FileName, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption, 
         varOption); 

     file_open = pBook->ReadOnly == VARIANT_TRUE; 
     pBook->Close(VARIANT_FALSE); 

     hr = S_OK; 
    } catch (_com_error& e) { 
     file_open = FALSE; 
     DumpCOMError(e); 
     hr = e.Error(); 
    } 

    pApplication->Quit(); 
    return hr; 
} 

int main(int argc, wchar_t* argv[]) 
{ 
    CoInitialize(NULL); 
    { 
     BOOL fileOpen; 
     HRESULT hr = IsXlsFileOpen(L"f:\\temp\\treta.xls", fileOpen); 
     if (SUCCEEDED(hr)) { 
      cout << "File is " << (fileOpen ? "open" : "not open") << "." << endl; 
     } 
     cout << "IsXlsFileOpen returned: 0x" << hex << hr << endl; 
    } 
    CoUninitialize(); 

    return 0; 
} 

Certains crédits sont méritées pour:

http://www.vbaexpress.com/kb/getarticle.php?kb_id=625

http://www.codeproject.com/KB/wtl/WTLExcel.aspx

http://www.codeguru.com/forum/printthread.php?s=26acdf89a1a6b79b7aa6a52e11b8d832&threadid=61997

Questions connexes