- - PR -
C++でEXCELファイルを読む方法
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-01-09 13:41
ご返答ありがとうございます。
> MFCなのか、Win32 SDKなのか、C++/CLI(Windows Formアプリケーション)なのか > どれなのでしょうか? そうですね、肝心なことが抜けてました。 現在、ある計算ライブラリを作成しておりまして、その中でエクセルファイルから データを取得する必要が出てまいりました。 ちなみに、このライブラリは、MFCを使わない、Win32コンソールアプリケーション >DLLもしくはスタティックライブラリです。 MFCを使ってはいけないという制限はないので、もし簡単になるのであれば、MFCを 使ってもかまいません。 以上、よろしくお願いいたします。 | ||||
|
投稿日時: 2007-01-09 14:21
じゃんぬさんから適切なアドバイスがありますが、
RangePtrの値を_WorksheetPtrの変数から取得するときに pSheet->Range["A1"]; のように取得するのと同様、A1の部分を任意の名前にするだけです。 Excel::RangePtr pRange = pSheet->Range["あ"]; みたいに。 | ||||
|
投稿日時: 2007-01-09 14:41
Blueさん、じゃんぬねっとさん、
ご回答ありがとうございます。 これで解決できそうです。 ところで、ついでにもう一つ教えて下さい。 先にふれましたように開発しているものはオブジェクトライブラリ もしくはDLL形式で提供することになるのですが、こういったケースでは、 COMの初期化(CoUninitialize)終了(CoUninitialize)処理 というのは、これを利用するアプリケーション側でやってもらうもの なのでしょうか?それともライブラリの初期化/終了関数の中でやるもの なのでしょうか? | ||||
|
投稿日時: 2007-01-09 16:53
自分の面倒は自分でみたほうがいいんじゃない?
ラッパークラスにしてコンストラクタとデストラクタを使うとか。 | ||||
|
投稿日時: 2007-01-09 19:01
言葉足らずでした。
今回作ったものは汎用のライブラリ/DLLとして提供するのですが、 これを利用するアプリはすでにCOMを使っているかどうかが分かり ません。 もしアプリがすでにCOMの初期化処理を行っていると、ライブラリ側 でやる必要はないですし、COMを使っていないアプリであれば、ライ ブラリ側で初期化しないといけません。 一般的なお作法として、このようなCOMの機能を使用するライブラリ を提供する場合は、誰がどのようにCOMの初期化・終了をしてやれば よいのでしょうか。 ライブラリの利用手引きに、ライブラリの関数を呼び出す前に、COM の初期化を行ってくださいと書けばすむ話なのでしょうか。 | ||||
|
投稿日時: 2007-01-09 19:15
矢継ぎ早の質問ですいません。
おかげさまで、教えていただいたサンプルを参考にEXCELのデータを読めるようになりました。 ここで1つ困ったことがあります。 現在は以下のようにタイプライブラリを利用?しているのですが、EXCELのバージョンや インストール先が決まっていない場合はどのようにすればよいのでしょうか? ご教示のほどよろしくお願いいたします。 #import "C:\Program Files\Common Files\Microsoft Shared\Office11\MSO.DLL" no_namespace rename("DocumentProperties", "DocumentPropertiesXL") rename("RGB", "MSO_RBGXL") #import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\Vbe6ext.olb" no_namespace #import "C:\Program Files\Microsoft Office\Office11\EXCEL.EXE" rename("ReplaceText", "ReplaceTextXL") rename("CopyFile", "CopyFileXL") rename("DialogBox", "DialogBoxXL") rename("RGB", "RBGXL") rename("DocumentProperties", "DocumentPropertiesXL") exclude("IFont") exclude("IPicture") no_dual_interfaces | ||||
|
投稿日時: 2007-01-10 00:51
かなり、根気が要る作業になります。 まず、#importを使う方法はまず使えません。 CLSIDFromProgID、CoCreateInstanceあたりを使って一つ一つプロパティからメソッドを割り当てていく方法になります。 それが面倒であれば、VB6とか遅延バインディングを使えるプログラム言語を使って ActiveX DLLを作るとか。(わたしならそうするかも。(COMの初期化処理なんていらないし)) というか、一番最初のリンク先のスレッドに同様な質問&回答がありますけど。 | ||||
|
投稿日時: 2007-01-10 09:48
おはようございます。
まずExcelのインストール先が決まっていない点ですが、 実行時に関しては「COMの位置透過性」から問題にはなりません。 (COMの実行モジュールのパスはレジストリに登録されているはずですから) EXCELのバージョンが決まっていない点に関しては、 すでに#import指令に"no_dual_interfaces"を付けていらっしゃるようなので、 カスタムインターフェイス経由ではなく、IDispatchインターフェイスを使用するようになっています。 つまり一応「遅延バインディング」となっております。 問題はEXCELのバージョンによって、 1.ディスパッチIDと呼ばれるIDが変更されている可能性があることと 2.メソッド・プロパティの引数が変更されている可能性があることです。 2.の引数変更に関しては、一般的な対処の方法は難しいですが、 1.の、ディスパッチIDに関しては、IDispatch::GetIDsOfNamesを実行時に呼んでやれば 動的に取得することができます。 つまり何が言いたいかといいますと、 自動生成された「excel.tli」というソースファイルで _com_dispatch_method関数呼び出しの第2引数を定数ではなく、 IDispatch::GetIDsOfNamesで取得したものを使用するほうがよいということです。 #私ならMFCのCOleDispatchDriverを使うと思います。 「TypeLibからのMFCクラス」でCOleDispatchDriver派生クラスが自動生成されます。 あとは、ディスパッチIDを動的に取得するように、ちょこちょこっと修正をします。 [ メッセージ編集済み 編集者: Tdnr_Sym 編集日時 2007-01-10 09:52 ] |