トップ回答者
VC++/CLIからエクセル

質問
-
お世話になってます、ハードボイルド探偵です。
現在VC++2008ExpressのC++/CLIからエクセルを使おうとして、頓挫中です。コードの方は以下のようなものを
実現したいと考えています。
①テキストからデータを読んで、エクセルファイルに書き出し
②エクセルで編集
③編集したデータをテキストに反映
②の部分はエクセルでやればいいので、問題は①と③なのですが、事の最初からつまずいてしまい、VCからエクセルファイル
を作成することも出来ません。
ネットで調べて以下のようなことをやってみたのですが、ダメでした
①ソリューションの共通プロパティのCOMの部分に、Microsoft.Office.Interop.Excelを追加
②構成プロパティの共通言語ランタイムサポートを「安全な MSIL 共通言語ランタイム サポート (/clr:safe)」に変更
③using namespace Microsoft::Office::Interop::Excel;と書いてみた
これは下記のサイトのマネです。
http://www.codeproject.com/KB/office/automate_excel.aspx
ここのサイトの内容だと、上に3つでエクセルを使えるようになるはずなのですが、ダメでした。
最悪CSV経由でと考えていますが、出来ればエクセルで処理を済ませたいと考えています。あと、C++/CLIからエクセル
を使う方法の資料を色々探してみたのですが、さっぱり見つかりません。できればそういうサイトとか本とかを紹介
して頂ければと思います。
こちらの環境は以下の通りです。
OS WinXP SP3
言語 VisualC++2008 Expressエディション(CLIで使ってます)
エクセル Excel2000
以上です。よろしくお願いします。
回答
-
> http://www.codeproject.com/KB/office/automate_excel.aspx
リンク先は VS2003 の上 マネージドC++ なので、今となっては情報が古いのかもしれません。
実はわたくし C++/CLI はよくわかってないのですが、たぶんこうだろうと勘でやってみたら、以下の手順で動きました。
ちなみに環境は Windows XP SP3/VS 2010 beta2/Excel 2003 ですが、VS2008 でも同様の手順で動くと思います。
1. まず「新しいプロジェクト」→「Visual C++」→「CLR」→「Windows フォームアプリケーション」で新規プロジェクトを適当な名前で作成。2. Microsoft Excel 11.0 Object Library を参照に追加
3. CLR Support は /clr:pure のままでよい。
4. Form1.h の名前空間に Excel を追加using namespace Excel;
5. Main の Application が Excel::Application とバッティングするので名前空間を指定
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{ // コントロールが作成される前に、Windows XP ビジュアル効果を有効にします System::Windows::Forms::Application::EnableVisualStyles(); System::Windows::Forms::Application::SetCompatibleTextRenderingDefault(false); // メイン ウィンドウを作成して、実行します System::Windows::Forms::Application::Run(gcnew Form1()); return 0; }
6. Button クリックイベントに以下のコードを追加
private: System::Void button1_Click (System::Object^ sender, System::EventArgs^ e) { Excel::Application^ xlApp = gcnew Excel::ApplicationClass(); Workbook^ wb = xlApp->Workbooks->Add(Type::Missing); static_cast<Worksheet^>(xlApp->ActiveWorkbook->Sheets->Item[3])->Delete(); static_cast<Worksheet^>(xlApp->ActiveWorkbook->Sheets->Item[2])->Delete(); Worksheet^ ws = static_cast<Worksheet^>(xlApp->ActiveSheet); ws->Name = "Charts"; ws->Cells[1,1] = "Hello World!"; xlApp->Visible = true; }
これで Excel が起動し、コードのとおり動作いたしました。お試しください。
すべての返信
-
C++/CLIだけでアプリを組むのは茨の道とこのフォーラムでも何方かが言われていました。
これまでWeb上や雑誌等の記事を読んだ感じだとC++/CLIは.net言語とネイティブC++を繋ぐ位置にあって、
ネイティブC++のプログラムから.net言語のライブラリを読んだり、はたまたC#等の.net言語から
C++で作成したライブラリを呼んだりしたい時にC++/CLIで間を取り持つ事で活用できると言う話だったと
思います。その為か、御本人が言われているようにC++/CLIだけでプログラミングをする場合の情報が非常に少ない
状態だと思います。
どうしてもC++/CLIで組まなければいけないのか?と言う所を再考されてみるのも良いのではと思います。
言語自体に縛りがあるわけではないのでれば、C#等を使った方が良いのではないかと言うのが正直な感想です。
C++/CLI言語自体を勉強したくてその手段としてのチャレンジなら要らぬおせっかいと言う事になりますけれど。
追伸:
C++言語とC++/CLI言語は言語としては別の言語になりますのでC++言語の勉強を目的としてるのであれば、
方向性が違うと言う事になると思います。この辺は御本人がどうお考えなのかが分からないので何とも言えませんけれど。
解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。- 編集済み PATIO 2009年12月21日 6:43 追伸を追加
-
# ただ「ダメでした」の一言で片付けてしまうのではなくて、どのようにダメだったかの詳細があると質問としてユーザー フレンドリーなのではないかと思います。
対象の Excel 2000 は PIA がありませんので、リンク先のような Excel 2003 や 2007 と同じやり方ではできないように思います。
TLBIMP.EXE を利用して自前で PIA を作るとかするのではないでしょうか。
C# and Excel interop - Stack Overflow
http://stackoverflow.com/questions/1111935/c-and-excel-interop
あるいは、アンマネージド コードで COM 呼び出ししてやるとか。 -
> http://www.codeproject.com/KB/office/automate_excel.aspx
リンク先は VS2003 の上 マネージドC++ なので、今となっては情報が古いのかもしれません。
実はわたくし C++/CLI はよくわかってないのですが、たぶんこうだろうと勘でやってみたら、以下の手順で動きました。
ちなみに環境は Windows XP SP3/VS 2010 beta2/Excel 2003 ですが、VS2008 でも同様の手順で動くと思います。
1. まず「新しいプロジェクト」→「Visual C++」→「CLR」→「Windows フォームアプリケーション」で新規プロジェクトを適当な名前で作成。2. Microsoft Excel 11.0 Object Library を参照に追加
3. CLR Support は /clr:pure のままでよい。
4. Form1.h の名前空間に Excel を追加using namespace Excel;
5. Main の Application が Excel::Application とバッティングするので名前空間を指定
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{ // コントロールが作成される前に、Windows XP ビジュアル効果を有効にします System::Windows::Forms::Application::EnableVisualStyles(); System::Windows::Forms::Application::SetCompatibleTextRenderingDefault(false); // メイン ウィンドウを作成して、実行します System::Windows::Forms::Application::Run(gcnew Form1()); return 0; }
6. Button クリックイベントに以下のコードを追加
private: System::Void button1_Click (System::Object^ sender, System::EventArgs^ e) { Excel::Application^ xlApp = gcnew Excel::ApplicationClass(); Workbook^ wb = xlApp->Workbooks->Add(Type::Missing); static_cast<Worksheet^>(xlApp->ActiveWorkbook->Sheets->Item[3])->Delete(); static_cast<Worksheet^>(xlApp->ActiveWorkbook->Sheets->Item[2])->Delete(); Worksheet^ ws = static_cast<Worksheet^>(xlApp->ActiveSheet); ws->Name = "Charts"; ws->Cells[1,1] = "Hello World!"; xlApp->Visible = true; }
これで Excel が起動し、コードのとおり動作いたしました。お試しください。 -
ダメの内容はフォームだけのアプリでコンパイルが通らないということでした。以下のようにコンパイラに怒られました。
1>------ ビルド開始: プロジェクト: excel_test, 構成: Debug Win32 ------
1>'d:\temp2\SoftProject\VC++2008\excel_test\excel_test\Interop\Office.dll' をターゲット ディレクトリにコピーしています...
1>'d:\temp2\SoftProject\VC++2008\excel_test\excel_test\Interop\VBIDE.dll' をターゲット ディレクトリにコピーしています...
1>'d:\temp2\SoftProject\VC++2008\excel_test\excel_test\Interop\Interop.Excel.1.3.dll' をターゲット ディレクトリにコピーしています...
1>コンパイルしています...
1>stdafx.cpp
1>コンパイルしています...
1>excel_test.cpp
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\Form1.h(16) : error C3083: 'Office': '::' の左側のシンボルには、型を指定しなければなりません
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\Form1.h(16) : error C3083: 'Interop': '::' の左側のシンボルには、型を指定しなければなりません
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\Form1.h(16) : error C2039: 'Excel' : 'Microsoft' のメンバではありません。
1>.\excel_test.cpp(12) : error C2872: 'Application' : あいまいなシンボルです。
1> 'd:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll の可能性があります : Excel::Application'
1> または 'c:\windows\microsoft.net\framework\v2.0.50727\system.windows.forms.dll : System::Windows::Forms::Application'
1>.\excel_test.cpp(12) : error C2039: 'EnableVisualStyles' : 'Excel::Application' のメンバではありません。
1> d:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll : 'Excel::Application' の宣言を確認してください。
1>.\excel_test.cpp(12) : error C3861: 'EnableVisualStyles': 識別子が見つかりませんでした
1>.\excel_test.cpp(13) : error C2872: 'Application' : あいまいなシンボルです。
1> 'd:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll の可能性があります : Excel::Application'
1> または 'c:\windows\microsoft.net\framework\v2.0.50727\system.windows.forms.dll : System::Windows::Forms::Application'
1>.\excel_test.cpp(13) : error C2039: 'SetCompatibleTextRenderingDefault' : 'Excel::Application' のメンバではありません。
1> d:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll : 'Excel::Application' の宣言を確認してください。
1>.\excel_test.cpp(13) : error C3861: 'SetCompatibleTextRenderingDefault': 識別子が見つかりませんでした
1>.\excel_test.cpp(16) : error C2872: 'Application' : あいまいなシンボルです。
1> 'd:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll の可能性があります : Excel::Application'
1> または 'c:\windows\microsoft.net\framework\v2.0.50727\system.windows.forms.dll : System::Windows::Forms::Application'
1>.\excel_test.cpp(16) : error C2660: 'Excel::_Application::Run' : 関数に 1 個の引数を指定できません。
1>AssemblyInfo.cpp
1>コードを生成中...
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\interop\office.dll のメタデータ情報をキャッシュ中です...
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\interop\interop.excel.1.3.dll のメタデータ情報をキャッシュ中です...
1>d:\temp2\softproject\vc++2008\excel_test\excel_test\interop\vbide.dll のメタデータ情報をキャッシュ中です...
1>ビルドログは "file://d:\temp2\SoftProject\VC++2008\excel_test\excel_test\Debug\BuildLog.htm" に保存されました。
1>excel_test - エラー 11、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
このエラーの内容についてはさっぱりわかりません。
ちなみにPIAの自作というのは私の手に余ります。今後の課題にさせてください。 -
仰るとおりかと思いますが、C++には男のロマンがありますので、なるべくならC++で通したいと思っています。
今はまだC++/CLIだけですが、出来れば生の方も書けるようになりたいです。が、途中でヘタレたときは
VisulaBasicかC#にします。
中でも書いていますが、C++/CLIとC++は別の言語です。
C++/CLIを勉強したからC++と同じと言うわけでは無いのでそのことは頭に置いておいた方が良いと思います。
C++の勉強がしたいのであれば、C++/CLIを使うのではなくて
WTL等を使ってC++で組んだ方が純粋にC++でプログラミングできると思います。
って、もう見ていないんだろうなぁ。
解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。