QA@IT

Jcomを使用したExcelマクロ実行について

6156 PV

kmと申します。

Webアプリで、複数のExcelをWebサーバ側で結合して、最終的に画面からダウンロードするような仕組みを作ろうとしています。
あれこれ調べてみましたが、複数のExcelの結合自体をjavaから実行することが困難そうなので(POIも使えない環境です)、Excelマクロを使って、結合することにしました。
こちらの記事を参考にさせていただいて、どうにかjavaからExcelマクロを実行できるようにしました。
(jcomの作者様がアドバイスされているだけあって、当該方式ですでに実装はし、ある程度確認ができています。)

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=43458&forum=12

ただし、java側から引数(Excelのパス)を渡したものの、Excelマクロでどのように受け取ればよいのかよくわからず、javaからexcelのシートおよびセルを指定する形で引数を渡す、何ともチープな作りとなってしまっています。。。
本当は以下のように、argにそれぞれ引数を設定して、"Run"するときにExcel側に引数が渡ると思うのですが。

        Object[] arg = new Object[3];
        arg[0] = "testmacro";   // マクロ名
        arg[1] = "aaa";         // 引数1
        arg[2] = "bbb";         // 引数2
        Object ret = excel.method("Run", arg);

素人考えで、Excelのマクロ側で引数が受け取れるように、プロシージャのSub マクロ名("ここに引数を指定")してみましたが、今度はjava側でマクロを認識せず、動きませんでした。
(引数指定のExcelマクロは、Excelのマクロ表示上からも消えることから、javaから参照できないということなんでしょうかね)

どのようにExcelマクロを記述すれば引数を受け取れるか、ご存知でしたらアドバイスいただけると助かります。

  • Javaが使えるのに、なぜPOIが使えないのでしょう?それから、そのExcelファイルは古い形式(.xls)ですか?それとも新しい形式(.xlsx)ですか? -
  • その肝心のExcelマクロ側で引数に何をしていしたのか書いてください。Variantあたりで受け取るしかないような気もするけど。 -
  • stripeさん>
    メーカー独自のフレームワークで、apache POIなど、ライブラリを追加するのが難しい環境です。Jcomは奇跡的に入っていました。
    ちなみに、Excelは2003(xls)、IE6(SP2)です。
    -
  • flied_onionさん>
    当初String型で引数を宣言していました。ご記載いただいた通り、variant型にしてみたら、受け取れました。ありがとうございます。
    あとは、戻り値を返してエラー判定を行いたいので、以下のretにどう返すか検討しています。
    Object ret = excel.method("Run", arg);
    -

回答

flied_onionさん>

上記のコメントにも記載いたしましたが、variant型でマクロ側も引数を受け取れました。
ありがとうございました。
5つ引数を渡す必要があるので、全てvariant型で引数を定義してみたいと思います。

あとは、Excel側からjava側へも戻り値を返すようにしたいので、ひと思案しております。
Object ret = excel.method("Run", arg);

私が記載した上記ソース上のretに戻り値を渡せれば、エラー判定が可能と考えています。
ただし、Excelマクロのsubプロシージャだと戻り値が返せないので、functionを定義し、javaから呼べれば実現しそうな気がしています。
とにかくお試ししてみないとですね。

編集 履歴 (0)

提示の例ですが個人用マクロブックのマクロを実行しようとしている格好でしょうか?
そうすると実行ユーザーが誰なのかも問題になるとおもいます。

全然検証はできていませんが
以下の様にしてブックに書いたマクロを呼び出してみた場合はどうなりますか?

  ExcelWorkbooks xlBooks=excel.Workbooks(); 
  ExcelWorkbook xlbook=xlBooks.Open(マクロ付ブック); 
  Object[] arg=new Object[1]; 
  arg[0]="test"; 
  xlbook.method("testmacro", arg); 
  xlbook.Close(false,null,false); 

マクロの方は

Public Sub testmacro(val as String)
  ' val で取り出す

または

Public Sub testmacro(val as Variant)
  ' val(ubound(val)) で取り出す

で取り出せるんじゃないかと思います。

ただMicrosoftは.NETにおいてサーバー側のExcelオートメーションを推奨していません。
Interopだったからかオートメーションそのものをだったかは記憶していませんがそのあたりは一応認識されておいたほうがいいかもしれません。
※ 禁止って意味ではなかったはず。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。