MinGWはGNU ツールチェーンのWindows移植版でWindows APIのためのヘッダファイルがありGCC で Windowsアプリケーションの開発することができます。
wxWidgetsはWindowsを初めMac OS X、Linuxなど多くのOSで動かすことが出来るウィジェット・ツールキットです。多くのプログラミング言語で使用でき、いろんなライブラリもあります。
wxWidgets には wxAutomationObject という OLE オートメーションを操作するオブジェクトがあり、試しに wxWidgets を使ってExcelを操作してみました。
参考にしたところ。
- Excel オブジェクト モデルのリファレンス (Visual Studio Tools for Office)
- Koders - Source Code Search Engine
- EternalWindows オートメーション / コレクションオブジェクト
// g++ exc.cpp `wx-config --libs` `wx-config --cxxflags` -o exc #include "wx/msw/ole/automtn.h" #include "wx/wx.h" class MyApp : public wxApp { public: virtual bool OnInit(); }; // 新しいアプリケーションオブジェクトを生成 IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { wxAutomationObject exl, sfo, workBooks, workbook, workSheets, sheet, cell; char buf[256]; // フルパスのファイル名を取得 bool ret = sfo.CreateInstance( wxT("Scripting.FileSystemObject")); wxVariant res = sfo.CallMethod( wxT("GetAbsolutePathName"), wxT("sample2.xls")); wxString fullPathName = res.GetString(); // フルパスのファイル名を表示してみる。 strcpy( buf, (const char*)fullPathName.mb_str(wxConvUTF8) ); printf("FullPathName: %s\n", buf); // => FullPathName: C:\COM\Excel\sample2.xls ret = exl.CreateInstance(_T("Excel.Application")); // バージョンを取得してみる。 wxVariant vsVersion = exl.GetProperty(wxT("Version")); wxString ver = vsVersion.GetString(); strcpy( buf, (const char*)ver.mb_str(wxConvUTF8) ); printf("Version: %s\n",buf); // =>Version: 9.0 // Workbooks オブジェクトを取得 ret = exl.GetObject(workBooks, wxT("Workbooks")); // Workbooks オブジェクトをオープン wxVariant openArgs[1]; openArgs[0] = wxVariant( fullPathName, wxT("Filename")); workBooks.CallMethod(wxT("Open"), 1, openArgs); exl.GetObject(workbook, wxT("ActiveWorkbook")); // exl.GetObject( workSheet, wxT("ActiveSheet")); //一番手前のシートを取得。 // Worksheets オブジェクト全体を取得 ret = workbook.GetObject( workSheets, wxT("Worksheets")); // 2 番目の sheet オブジェクトを取得 wxVariant avSheetsItem[1]; avSheetsItem[0] = wxVariant(2); // 2 番目 ret = workSheets.GetObject( sheet , wxT("Item"), 1, avSheetsItem); // 1 行、2列目の cell オブジェクトを取得 wxVariant avCellItem[2]; avCellItem[0] = wxVariant(1); // 1 行目 avCellItem[1] = wxVariant(2); // 2列目 ret = sheet.GetObject( cell, wxT("Cells"), 2, avCellItem); // セルへ書き込み ret = cell.PutProperty(wxT("Value"), wxVariant(wxT("wxWidgets 2.8.11"))); printf("cell.PutProperty : %d\n", ret); // セルの値を読み込む wxVariant data = cell.GetProperty(wxT("Value")); wxString celltype = data.GetType(); wxString cellstr = data.GetString(); strcpy( buf, (const char*)celltype.mb_str(wxConvUTF8) ); printf("celltype: %s\n", buf); // => celltype: string strcpy( buf, (const char*)cellstr.mb_str(wxConvUTF8) ); printf("cellString: %s\n", buf); // => cellString: wxWidgets 2.8.11 // workBooks.CallMethod(wxT("Save")); だと保存するかどうか聞かれる。 workbook.CallMethod(wxT("Save")); workBooks.CallMethod(wxT("Close")); exl.CallMethod(wxT("Quit")); // GUI のとき TRUE にすると終了しない。 // return TRUE; return FALSE; }
分ってしまえばかなり簡単に Excel が操作できます。
コンパイルコマンドの引数 `wx-config --libs` `wx-config --cxxflags` は wx-config が環境を調べてコンパイルオプションを生成するためのものです。
// g++ exc.cpp `wx-config --libs` `wx-config --cxxflags` -o exc
MSYS シェルのなかから wx-config --libs を実行してもエラーになります。
cmd.exe からだとOK。
D:\lang\COM\Excel>wx-config --libs -mthreads -LD:\msys\1.0\home\user\wxMSW-2.8.11\lib\gcc_dll -lwxmsw28u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwxregexu -lwinspool -lwinmm -lshell32 -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32
cmd.exe 環境では `wx-config --libs` と言う記述は出来ませんので BASH シェルを呼び出してその中から実行しました。
D:\lang\COM\Excel>type ex.bat g++ exceltest.cpp `wx-config --libs` `wx-config --cxxflags` -o exceltest D:\lang\COM\Excel>bash ex.bat
MSYS シェルから出来ないのは何故?