テーブル定義書から,Javaのエンティティクラスを自動生成する VBA マクロ
ExcelのDBテーブル定義書(.xlsファイル)を読み込んで,
Javaのエンティティクラスのソースコードを出力するマクロ。
モデル層で,永続化クラスを手でコーディングしなくて済む。
ソースコード
VBAのソースコードは下記の通り。
コード中のURLが解説を兼ねている。
' 全シートからJavaエンティティクラスを作ります Sub makeAllEntities() ' 全ワークシートに対して ' http://okwave.jp/qa1230032.html For Each ws In Worksheets ws.Activate makeEntity Next ws MsgBox "完了" End Sub ' アクティブなシートからJavaエンティティクラスを作ります Sub makeEntity() ' 定数 br = vbNewLine ' 改行。vbCrLfだと行頭に余計な二重引用符が付く tb = vbTab tb2 = vbTab & vbTab ' テーブル記載開始位置 x_offset = 2 ' 列 y_offset = 8 ' 行 class_description = Cells(2, 3).Value ' クラスの日本語名 class_name = Cells(4, 3).Value ' エンティティ名 package_name = Cells(5, 3).Value ' パッケージ名 ' 出力ファイルパス output_path = ThisWorkbook.Path & "\" & class_name & ".java" ' カレントディレクトリについて ' http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_140.html ' 書き込み ' ファイルポインタを作成 fp = FreeFile ' http://chaichan.web.infoseek.co.jp/vbtips/VBMemo2007011801.htm Open output_path For Output As #fp Print #fp, "package " & package_name & ";" ' import文はあきらめる Print #fp, "" Print #fp, "/**" & br _ & "* " & class_description & "を表すエンティティ。" & br _ & "*/" Print #fp, "public class " & class_name & " {" ' 属性読み込みループ x = x_offset y = y_offset str_vars = "" str_func = "" Do While True ' カラムの並び順は,左から ' 日本語名称,英字名称,型 jp_name = Cells(y, x).Value var_name = Cells(y, x + 1).Value type_name = Cells(y, x + 2).Value ' 終了判定 If Len(var_name) < 1 Then Exit Do End If var_name_big = SmallUnderbar2Pascal(var_name) ' member変数 str_vars = str_vars _ & tb & "/**" & br _ & tb & "* " & jp_name & "。" & br _ & tb & "*/" & br _ & tb & "private " & type_name & " " & var_name & ";" & br & br ' getter str_func = str_func _ & tb & "public " & type_name & " get" & var_name_big & "() {" & br _ & tb2 & "return " & var_name & ";" & br _ & tb & "}" & br & br ' setter str_func = str_func _ & tb & "public void set" & var_name_big & "( " & type_name & " " & var_name & " ) {" & br _ & tb2 & "this." & var_name & " = " & var_name & ";" & br _ & tb & "}" & br & br y = y + 1 Loop str_vars = br & tb & "// ------ メンバ変数 ここから ------" & br & br _ & str_vars _ & tb & "// ------ メンバ変数 ここまで ------" & br & br str_func = br & tb & "// ------ getter + setter ここから ------" & br & br _ & str_func _ & tb & "// ------ getter + setter ここまで ------" & br & br Print #fp, str_vars Print #fp, str_func Print #fp, "}" Close #fp 'MsgBox "完了" End Sub ' 全小文字アンダーバー区切りの文字列を,大文字始まり区切りに変換 Function SmallUnderbar2Pascal(str) ' アンダーバーで分割 Dim arr ' splitの戻り値はバリアント型で宣言されていなければならない ' http://officetanaka.net/excel/vba/tips/tips62.htm arr = Split(str, "_") For i = 0 To UBound(arr) word = arr(i) ' 1文字目は大文字に word_head = StrConv(Mid(word, 1, 1), vbUpperCase) ' StrConv http://eprostation.jpn.org/vba/vamoji.html ' Mid http://www.kanaya440.com/contents/script/vbs/function/string/mid.html ' 先頭文字のインデックスが1である点に注意 ' SubStr は使わない http://homepage1.nifty.com/coffee-break/pc/pc6/nb_0203.html word_tail = Mid(word, 2, Len(word) - 1) arr(i) = word_head & word_tail Next SmallUnderbar2Pascal = Join(arr, "") End Function ' テスト用のコード Sub TestSmallUnderbar2Pascal() MsgBox SmallUnderbar2Pascal("abc") ' Abc MsgBox SmallUnderbar2Pascal("abc_def_ghi") ' AbcDefGhi MsgBox SmallUnderbar2Pascal("x_y") ' XY End Sub
コード概説:
- VBScript / VBA での「部分文字列の抽出」は,Mid 関数で行なう。「VBA SubStr」等で検索すると,http://homepage1.nifty.com/coffee-break/pc/pc6/nb_0203.html のような愉快なページを見ることになる。
- Splitの戻り値となる配列を格納する変数は,バリアント型で宣言されていなければならない。
- VBAでのテキストファイル入出力は,FreeFile / Open / シャープ記号 によりファイルハンドルを扱う。ファイル存在時/非存在時の判定分岐は不要。
- 全ワークシートへの処理は,WorksheetsオブジェクトをFor Eachする。
また,シート本体で「セルからワークシート名を参照する」という部分がある。
これは下記を参考にした。
- Excelの関数でシート名を求める http://www.cre8system.jp/blog/2006/10/excel.html
- CELL : セルの各種情報をべる http://www.ecken.co.jp/func/func_cell.htm
実行結果
サンプルシートでマクロを実行すると,下記のようなJavaDocコメント付きのファイルがxlsと同じディレクトリに出力される。
package jp.co.hoge.hige.hage; /** * ユーザ設定情報を表すエンティティ。 */ public class UserAccount { // ------ メンバ変数 ここから ------ /** * ユーザID。 */ private int user_id; /** * ログインID。 */ private String login_id; /** * パスワード。 */ private String password; /** * ユーザー名。 */ private String user_name; // ------ メンバ変数 ここまで ------ // ------ getter + setter ここから ------ public int getUserId() { return user_id; } public void setUserId( int user_id ) { this.user_id = user_id; } public String getLoginId() { return login_id; } public void setLoginId( String login_id ) { this.login_id = login_id; } public String getPassword() { return password; } public void setPassword( String password ) { this.password = password; } public String getUserName() { return user_name; } public void setUserName( String user_name ) { this.user_name = user_name; } // ------ getter + setter ここまで ------ }
類似ツール
なお,類似のツールはたくさん存在する。
例えば Hibernate Synchronizer のように,O/Rマッパーのおまけとして利用できるプラグインがある。
Hibernate メモ2 / 開発プロセスと開発ツール
http://muimi.com/j/hibernate/devprocess.html