スポンサーリンク

テーブル定義書から,Javaのエンティティクラスを自動生成する VBA マクロ

ExcelのDBテーブル定義書(.xlsファイル)を読み込んで,
Javaのエンティティクラスのソースコードを出力するマクロ。


モデル層で,永続化クラスを手でコーディングしなくて済む。

ダウンロードできます

簡単なサンプルを下記からダウンロードできる。

http://www.name-of-this-site.org/coding/vba/tables_template.xls

ソースコード

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

コード概説:

  • Splitの戻り値となる配列を格納する変数は,バリアント型で宣言されていなければならない。
  • VBAでのテキストファイル入出力は,FreeFile / Open / シャープ記号 によりファイルハンドルを扱う。ファイル存在時/非存在時の判定分岐は不要。
  • 全ワークシートへの処理は,WorksheetsオブジェクトをFor Eachする。

また,シート本体で「セルからワークシート名を参照する」という部分がある。

これは下記を参考にした。

実行結果

サンプルシートでマクロを実行すると,下記のような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