VB(orVBA)からJComへの翻訳の仕方
〜JComでサポートされないオブジェクト、メソッド、プロパティを使うにはどうしたらいい?〜
まず、やりたい処理をVBで記述してください。
VBで書けることでしたら、ほぼJComでも書くことができます。
そして、VBのプログラムがあれば、ほとんど機械的にJComの
プログラムに翻訳することができます。
翻訳する前に以下のものを準備してください。
VBAのヘルプ
Excel97の場合、(Office)\Office\VBAXL8.HLPがそうです。
これは、インストール時のオプションによっては、インストールされない場合があります。
その場合は、再インストールしてください。
オブジェクトブラウザ
VBを起動し、メニューで「表示/オブジェクトブラウザ」を選べば起動します。
列挙型の値を調べたいときなど、便利です。
OLE/COM オブジェクトビューア
オブジェクトブラウザがあれば必要ないでしょう。
VisualStudio6の場合、スタートメニューから、
「Microsoft Visual Studio 6.0 ツール/OLE Viewer」
を選びます。
主に、VC++気質(カタギ)の方はこちらでも代用できます。
実際に翻訳をしてみます。ここではサンプルとして、Excelで図形を扱ってみましょう。
やりたいことをVBのプログラムで記述します。
ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 30, 40, 200, 100).Select
まず、ActiveSheetが何者なのか、VBのヘルプで調べてみましょう。
これは、Application,Window,Workbookいずれかのプロパティであることがわかります。
JComのExcelApplicationクラスにはActiveSheetメソッドが用意されているので、それが使えます。
Workbookがあってのシートなので、あらかじめWorkbookを作っておきます。
import jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
/** JComでShapeを扱うサンプルプログラム */
class Shapes {
public static void main(String[] args) throws Exception {
ReleaseManager rm = new ReleaseManager();
try {
System.out.println("EXCELを起動中...");
ExcelApplication xlApp = new ExcelApplication(rm);
xlApp.Visible(true);
ExcelWorkbooks xlBooks = xlApp.Workbooks();
ExcelWorkbook xlBook = xlBooks.Add(); // 新しいブックを作成
ExcelWorkSheet xlSheet = xlApp.ActiveSheet();
...
次に、取得したWorkSheetオブジェクトからShapesプロパティを取得します。
JComのExcelWorkSheetクラスなどは、すべてIDispatchクラスから継承されています。
IDispatchクラスは低レベルインターフェースでこれを使えば、未対応のプロパティや
メソッドでも扱うことができます。プロパティの取得には、IDispatchのget()を使います。
Shapesプロパティを取得するには以下のようになります。
IDispatch xlShapes = (IDispatch)xlSheet.get("Shapes");
戻り値はオブジェクト型なので、IDispatchに変換して受けます。
次にいよいよテキストボックスを追加します。
VBのAddTextBoxはShapesオブジェクトのメソッドです。
JComのIDispathでメソッドを呼ぶ場合は、methodを使います。
引数の数だけ、Objectの配列を用意し、それをmethodで呼びます。
int msoTextOrientationHorizontal = 1;
Object[] args1 = new Object[] {
new Integer(msoTextOrientationHorizontal),
new Float(30),
new Float(40),
new Float(200),
new Float(100)
};
IDispatch xlShape = (IDispatch)xlShapes.method("AddTextbox", args1);
整数ならJavaのIntegerで、単精度実数ならJavaのFloatで送ります。
問題は、msoTextOrientationHorizontalです。
これは、VBAのヘルプからMsoTextOrientationクラスのLong値であることはわかるのですが、
実際にどんな値なのかはヘルプからはわかりません。
そこで、VBのオブジェクトブラウザが登場します。
先頭がMsoで始まっているので、MicrosoftのOfficeライブラリに属するものと想像できます。
図形は、Excelだけではなく、Wordでも使われますから、共通のOfficeのライブラリに属するのです。
MsoTextOrientaionの列挙型(Enum)を探し、msoTextOrientationHorizontalを探します。
これで値が1であることがわかります。
VBのLongは4バイトの整数なので、Javaで扱うときには、Integerに該当します。
さて、これで追加されました。最後に、そのオブジェクトを選択状態にするので、
ShapeオブジェクトのSelectメソッドを呼びます。
引数は省略可能なので、引数なし、つまりnullで呼び出します。
xlShape.method("Select", null); // デフォルトはtrue
もう1つサンプルをあげます。
上記の処理のあと、テキストボックスの文字を"あいうえお"に変えてみましょう。
VBのソースは以下の様になります。
Selection.Characters.Text = "あいうえお"
これを同じ要領で、JCom用に翻訳してみます。
xlShape = (IDispatch)xlApp.get("Selection");
IDispatch xlCharacters = (IDispatch)xlShape.get("Characters");
xlCharacters.put("Text", "あいうえお");
最後に全ソースを載せておきます。
VBA
ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 30, 40, 200, 100).Select
Selection.Characters.Text = "あいうえお"
ActiveSheet.Shapes.AddLine(40, 200, 250, 250).Select
Java
import jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
/** JComでShapeを扱うサンプルプログラム */
class Shapes {
public static void main(String[] args) throws Exception {
ReleaseManager rm = new ReleaseManager();
try {
System.out.println("EXCELを起動中...");
//ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, 30, 40,
200, 100).Select
ExcelApplication xlApp = new ExcelApplication(rm);
xlApp.Visible(true);
ExcelWorkbooks xlBooks = xlApp.Workbooks();
ExcelWorkbook xlBook = xlBooks.Add(); // 新しいブックを作成
IDispatch xlShapes = (IDispatch)xlApp.ActiveSheet().get("Shapes");
int msoTextOrientationHorizontal = 1;
Object[] args1 = new Object[] {
new Integer(msoTextOrientationHorizontal),
new Float(30),
new Float(40),
new Float(200),
new Float(100)
};
IDispatch xlShape = (IDispatch)xlShapes.method("AddTextbox", args1);
xlShape.method("Select", null); // デフォルトはtrue
//Selection.Characters.Text = "あいうえお"
xlShape = (IDispatch)xlApp.get("Selection");
IDispatch xlCharacters = (IDispatch)xlShape.get("Characters");
xlCharacters.put("Text", "あいうえお");
//ActiveSheet.Shapes.AddLine(40, 200, 250, 250).Select
xlShape = (IDispatch)xlShapes.method("AddLine",
new Object[] {
new Float(40),
new Float(200),
new Float(250),
new Float(250)
});
xlShape.method("Select", null);
System.out.println("[Enter]を押してください。終了します");
System.in.read();
xlBook.Close(false, null, false);
xlApp.Quit();
System.out.println("ご静聴、ありがとうございました。");
}
catch(Exception e) { e.printStackTrace(); }
finally { rm.release(); }
}
}