none
VC++/CLIからエクセル RRS feed

  • 質問

  • お世話になってます、ハードボイルド探偵です。

    現在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

    以上です。よろしくお願いします。
    2009年12月21日 5:07

回答

  • 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 が起動し、コードのとおり動作いたしました。お試しください。
    2009年12月21日 16:44

すべての返信

  • 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 追伸を追加
    2009年12月21日 6:39
  • # ただ「ダメでした」の一言で片付けてしまうのではなくて、どのようにダメだったかの詳細があると質問としてユーザー フレンドリーなのではないかと思います。

    対象の 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 呼び出ししてやるとか。
    2009年12月21日 9:45
  • 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 が起動し、コードのとおり動作いたしました。お試しください。
    2009年12月21日 16:44
  • 仰るとおりかと思いますが、C++には男のロマンがありますので、なるべくならC++で通したいと思っています。

    今はまだC++/CLIだけですが、出来れば生の方も書けるようになりたいです。が、途中でヘタレたときは
    VisulaBasicかC#にします。

    2009年12月22日 7:35
  • ダメの内容はフォームだけのアプリでコンパイルが通らないということでした。以下のようにコンパイラに怒られました。

    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の自作というのは私の手に余ります。今後の課題にさせてください。
    2009年12月22日 7:39
  • わざわざのコーディングありがとうございます。ひらぽんさんのコードで問題を解決することが出来ました。

    私が書こうと思ってるコードの①の部分はまさにこんな感じです。ありがたくパクらせて頂きます。

    ありがとうございました。
    2009年12月22日 7:50
  • 仰るとおりかと思いますが、C++には男のロマンがありますので、なるべくならC++で通したいと思っています。

    今はまだC++/CLIだけですが、出来れば生の方も書けるようになりたいです。が、途中でヘタレたときは
    VisulaBasicかC#にします。

    既に終わってしまっているようですが、
    中でも書いていますが、C++/CLIとC++は別の言語です。
    C++/CLIを勉強したからC++と同じと言うわけでは無いのでそのことは頭に置いておいた方が良いと思います。

    C++の勉強がしたいのであれば、C++/CLIを使うのではなくて
    WTL等を使ってC++で組んだ方が純粋にC++でプログラミングできると思います。

    って、もう見ていないんだろうなぁ。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年12月22日 8:50
  • ですね。生もやっぱり男のロマンがあるんでしょうか。
    ハードボイルド探偵さんの基準では生 > C++/CLI > C#なのかな。
    個人的には、C++とC#が書けて初めてC++/CLIがわかると思っています。
    貼り付けられているエラーを見る限りnamespaceが何なのかも理解していなさそうですし…いろいろと順序が間違ってると思います。
    2009年12月22日 15:04