【Talend】マクロ(vba)付きExcelと連携する

公開日:2017.06.23
更新日:2018.04.16
【Talend】マクロ(vba)付きExcelと連携する

Youtuberになりました!チャンネル登録をお願いします!(登録してもらえると超喜びます!!)

バイクお役立ち情報を発信してます! hidetasoさんはバイク好きっ!ちゃんねる
しっとり系のピアノ演奏を発信してます!独学雑魚ピアニストのピアノ楽しんで頑張るチャンネル

はじめに

今回は、Talendでxlsmファイル(Excelのマクロ(vba)付きファイル)と連携する方法についてです。

Talendには、通常のExcelドキュメントから値を取得するためのコンポーネントは存在しますが、残念ながらExcel vbaはサポートされません…

ですが、それでも既存資産にマクロ付きExcelがあり、そのマクロの仕様が複雑すぎて新たに作り直すのは無理…なんとしてもこのExcelと連携する必要があるんだ!
という場面に出くわしましたので、今回まとめておきます。

Excel vbaと連携するTalendコンポーネントはない

前述の通り、Excelに書かれたマクロ(vba)を実行するコンポーネントはありません。

が、大丈夫です。
かなり泥臭くはありますが、Talendにはコンソールを起動するコンポーネントがあるので、それを使った方法で戦います。

ちなみに、この記事を書くにあたって、komlogさんの記事が大変参考になりました。ありがとうございます。

実装する

コマンドラインからでも、Excelの中のvba(で書かれた関数)は直接起動できないようです。
ので、vba起動用のvbsを作成し、それを経由して間接的にvbaを実行する戦略でいきます。

vbaキック用vbsを作る

以下をコピペして、exec_macro.vbsと名付けて保存しておきます。

[vb]
Set objArgs = Wscript.Arguments
runXLmacro objArgs(0), objArgs(1), objArgs(2)

Function runXLmacro(BookName, MacroName, Parameters)
Dim XL
Set XL = CreateObject("Excel.Application")
XL.Visible = True
XL.Workbooks.Open BookName
XL.Run MacroName, Parameters
XL.ActiveWorkbook.Close False
XL.Quit
Set XL = Nothing
End Function

[/vb]

内容は、コマンドラインから引数を3個受け取り、Excelファイルを実行する、というものです。
パラメータに関しては後述します。

必要に応じて実行する関数のラッパーを作っておく

実行したいマクロ付きExcelが、複数の関数を実行する必要があったりする場合は、外から呼び出すためのラッパーを1つ作っておいた方が良いです。

今回は、不要とは思えど一応ラップしておきました。

[vb]
‘これがラッパー
Sub OutputCsvWrapper(file_path)
OutputCsv file_path, 2
End Sub


‘これがラップされる側
‘概要:シートよりCSV形式テキストファイルを書き出す
Sub OutputCsv(file_path, sheet_id)

‘初期化
Dim LAST_LINE As Long
Dim FIRST_COL As Integer: FIRST_COL = 1
Dim LAST_COL As Integer: LAST_COL = 4
Dim row As Integer: row = 1
Dim col As Long
Dim out_file_num As Integer

‘ Sheetのアクティブ化
Sheets(sheet_id).Activate

‘ 収容最終行の判定
LAST_LINE = 32

‘ FreeFile値の取得
out_file_num = FreeFile

‘ 指定ファイルをOPEN(出力モード)
Open file_path For Output As #out_file_num

‘ファイル出力
‘ 最終行まで繰り返す
Do Until row > LAST_LINE
For col = FIRST_COL To LAST_COL
Write #out_file_num, Cells(row, col).Value;
Next col

Write #out_file_num, ""

‘ 行を加算
row = row + 1
Loop

‘ 指定ファイルを閉じる
Close #out_file_num

End Sub

[/vb]

ちなみに、今回ジョブに組み入れたいExcelは…
めちゃめちゃ簡単なサンプルなんですが、「CSV出力」ボタンを押すとcsvを吐き出すよ、というものです…

ファイル名はuser_tenpo_manager.xlsmとしてあります。

Talendのジョブを組んでいく

さて。
今回のメインとなるコンポーネントは、tSystemです。

これが、コマンド実行してくれるコンポーネントです。

色々と設定項目はありますが、とりあえず今回のケースではCommandパラメータに実行したいコマンドを文字列でセットするだけでOKです。
ベタ下書きするのもアレなんで、contextにcmdTextとして外出ししておきます。

サクサクっとジョブを組み立てます。

シンプルですね。連携テストが出来ればいいかな、という勢いです。
「初期化」のtJavaでtSystemに実行してもらうコマンドを組み立て、
tSystemでマクロ実行、
このマクロはcsvを吐くものなので、動作確認として最後に出力ファイルを読み込んでログ出力する、というフローです。

実行コマンドの組み立て

さて、後はtSystemにキックしてもらうコマンドを組み立てればおしまいです。
先程作成した、exec_macro.vbsをキックするコマンドを書きます。

このvbsは、引数を3個とり、それぞれ実行したいExcelファイルパス、実行したい関数名、出力ファイルパスとなっています。

[text]
cmd /c exec_macro.vbs user_tenpo_manager.xlsm OutputCsvWrapper user_info.csv
[/text]

ですので、上記のようなコマンドを実行すればokです。
が、これではあまりに固定的すぎるので、それぞれのパラメータをcontextで外出ししておき、[初期化]tJavaで組み立てることにしました。

[初期化]tJavaの中身はこんな感じです。

[java]

context.cmdText = "cmd /c "
+ context.filePathWrapperVbs + " "
+ context.filePathTargetXlsx + " "
+ context.targetXlsxFunctionName + " "
+ context.filePathOutput;

System.out.println("コマンド=" + context.cmdText);
[/java]

外出ししたcontextを繋げてるだけですね…はい。

後は、tSystemのCommandパラメータに編集した文字列を与えれば完成です!

実行する

実行して、正しく動くかを確認します。
先程外出ししたcontextには下記のように所定のパスを書いて…実行!

Excelマクロが実行されたかどうかがとても分かりにくいですが、ちゃんと動いています。

Excel vbaがキックされcsvを吐き、そのcsvの中身がログ出力されています。

 

今回は以上です。

 

【文字数:3496文字】

IT系カテゴリの最新記事