神尾みかさんのDS自由自在 第2回
「CSV形式のログデータをメールで送信する!」
少しずつDataSpiderのスクリプト作成に慣れてきた様子の東谷君。でもやはり神尾みかさんの手助けなくては完成させられないのが悩みどころ。
今日も早速、朝から悩みに突き当たっている様子です。
東谷君:
むむむむ・・・・。ぐぐぐぐぐ・・。ううう・・・。
みかさん:
お、さっそく今日も悩んでるわね!
東谷君:
分かりますか・・・。
みかさん:
そりゃそんな唸ってたら分かるわよ。
どうしたの?
東谷君:
スクリプトで悩んでいるところがありまして・・・。
みかさん:
どんなスクリプト?。
東谷君:
CSVファイルに出力されたログのデータを、メールの本文に入れて管理者に送付するスクリプトなんですよね。
CSVのデータ読み取りは[CSV読み取り]処理で、メール送信は[1通メール送信]処理でやろうと思ってるんですけど、読み取りから書き込みにどうデータを渡そうかと・・・・。
みかさん:
なるほどね。
そういう処理を作る方法は幾つかあるわね・・・・。
まず今日は、[CSV読み取り]処理と[1通メール送信]処理で実現する方法で考えてみましょうか。
東谷君:
はい!
可変データをプロパティ入力欄に渡すには?
みかさん:
まず元のCSVファイルのデータはどんなもの?
それをどのような形式でメールで送りたいの?
東谷君:
CSVファイルはこんな感じですね。
■CSVファイル
日付,時間,項目
20110803,000132,エラー
20110803,052325,正常起動
で、メールはこんな内容を送信したいです。
■メール本文
以下ログです。
====================================================
日付,時間,項目
20110803,000132,エラー
20110803,052325,正常起動
====================================================
みかさん:
なるほど。まず読み取りから考えてみましょうか。
このCSVファイルを[CSV読み取り]処理で読み取ったら、どういうデータが出力されるかしら。
東谷君:
[CSV読み取り]処理はテーブルモデル型のデータを出力するんで、こんな形でテーブルデータが出力されますね。
<?xml version="1.0" encoding="UTF-8"?>
<table>
<row>
<column>日付</column>
<column>時間</column>
<column>項目</column>
</row>
<row>
<column>20110803</column>
<column>000132</column>
<column>エラー</column>
</row>
<row>
<column>20110803</column>
<column>052325</column>
<column>正常起動</column>
</row>
</table>
東谷君:
うーん、悩んでいるのが、これは後続の処理の入力データとして使うための出力データですよね。
で、[1通メール送信]処理は入力データからデータを受け取らずに、プロパティの[本文]こデータを入力して送信する形式の処理ですよね。
このデータをどう[1通メール送信]処理の[本文]入力欄に実行時に渡せばいいのか、っていうとことで・・・・
みかさん:
ふふふ、もうほとんど答えは出ていると思うんだけど、ちょっと考えてみましょうか。
まず[1通メール送信]処理での[本文]プロパティは、そのままだと設定時に入力したデータをそのまま使用して送信する機能だよね。
でも、それを実行時に動的に変えることができるようにするためには・・・・。
東谷君:
あ、「スクリプト変数」を使えばいいのか!
みかさん:
そうそう、オペレーションの入力欄に可変データを渡す、というときにスクリプト変数を使うのよ。これはよく出てくると思うので覚えておいてね!
東谷君:
はい!
よし、文字列型のスクリプト変数「var」を作成して、[1通メール送信]処理の[本文]に埋め込む...と。
▲本文欄に変数${var}を埋め込む
繰り返し処理を使ってスクリプト変数にデータを追加する!
みかさん:
この「var」変数に、どうやって[CSV読み取り]処理で読み取ったデータを渡すか、ということなんだけど、東谷君何かアイディアはあるかしら?
東谷君:
う、そうですね・・・。
このvar変数は文字列型なので、CSVファイルから読み取ったテーブルデータの文字列をこのvar変数に追加していけばいいのかな。
ということは、[繰り返し]処理のどれかを使って変数代入を繰り返し行えば・・・・。
みかさん:
そう! この場合、テーブルデータで読み取った行数分繰り返したいわけだから・・・・。
東谷君:
[繰り返し(データ件数)]処理ですね!
そうすれば、読み取ったデータ件数繰り返し「var」変数にデータを追加していけば、データを出力できますね。
みかさん:
そうね、読み取ったデータは変数代入で区切り文字に「,」(カンマ)を入れればCSV形式のデータになるし、例えばタブ区切りや「|」区切りにする、ということもできるわね。
とりあえずここではカンマ区切りでやってみましょうか。
東谷君:
分かりました! こんな感じですね。
東谷君:
変数代入処理ではこんな感じでcolumnのデータとカンマを文字列連結して、元の「var」変数の後に追加していくと・・・・できた! よし実行だ!
みかさん:
ああああ
東谷君:
あれ、こんな内容でメールが送られちゃった・・・・。
以下ログです。
====================================================
日付,時間,項目20110803,000132,エラー20110803,052325,正常起動
====================================================
みかさん:
早まっちゃって・・・。
今のままだと、改行が入ってないので全部1行になってしまうのよ。
東谷君:
そうでした・・・。
くも子:
おちつけ!
東谷君:
くも子にまで・・・・
条件分岐をして改行を追加する
みかさん:
じゃあ、このデータに改行を入れる処理を考えてみましょうか。
東谷君:
そうですね・・・。
1行目のデータはそのまま代入、
2行目のデータからは、改行を挿入した後にデータを挿入すればできるかな。
みかさん:
そうね。そのためには?
東谷君:
1行目のデータはこう、2行目以降のデータはこう、っていうフローを作ればいいから・・・・[条件分岐]処理ですね!
みかさん:
さすが! そうね、1行目のデータかどうかの判断は幾つか方法があるんだけど、例えば”「var」変数が空文字になっているかどうか”で判断して条件を分岐すると、こんな感じになるわね。
東谷君:
こちらの2行目以降の変数代入で、こんな感じで改行を[複数行文字列定数]ロジックで加えてやることで、できるわけですね。
そして実行・・・・できた!
みかさん:
パチパチパチ。
東谷君:
本日はありがとうございま
くも子:
満足するのはまだ早いクモ!
みかさん:
おっとここで物言いが!
東谷君:
なんと!
みかさん:
もっと違う作り方もできるよ、っていうことをくも子は言いたいみたいよ!
条件分岐を使わずに作ってみる!
みかさん:
今は[条件分岐]処理でプロセスフローを分岐して実現したけど、[条件分岐]処理を使用しなくても、Mapperで[条件判定による出力の切り替え]ロジックを使えば同じようなことができるわね、
東谷君:
おお、なるほど!
って[条件判定による出力の切り替え]ロジックってどう使うんでしたっけ・・・・。
みかさん:
簡単に言うと、ある条件に対して成立時はこのデータ、不成立時はこのデータ、という風に出力するデータを切り替えることができるロジックね。
東谷君:
ふむふむ、じゃあ条件を「1行目かどうか」、成立時は空文字、不成立時は改行を出力すれば、同じようなことができますね。
みかさん:
そうそう、そして「1行目かどうか」は、[繰り返し(データ件数]処理のコンポーネント変数「count」が0かどうか、ということで判断できるので、そう設定するこんな感じね。
▲[条件判定による出力の切り替え]ロジックの[条件]タブ
▲[条件判定による出力の切り替え]ロジックの[不成立時]タブ
東谷君:
おお、なるほど。じゃあスクリプトはこうなるわけですね。
こっちの方がシンプルですね。
みかさん:
変数代入の処理はちょっと複雑になるけどね。
どちらがいいかは要件次第だと思うわ。
大切なのはいろいろなやり方を知っていて、その時のベストなやり方を自分で選べることね。
今回の処理も、この2つ以外にもやり方あるので、他のやり方でも作ってみるといいと思うよ。
東谷君:
了解です! 本日はありがとうございました!
というわけで本日も様々なスクリプト作成知識を教わった東谷君。
果たしてみかさんから独立できる日々は来るのか?
DataSpder修行はまだまだ続きます。
なお、今回作成したスクリプトは、以下スキルアップセンターのページよりダウンロードが可能です。
(※) [条件分岐]処理を使った場合のスクリプトになります。
スキルアップセンター > サンプルスクリプトのダウンロード > CSVに出力された複数行をメール本文に張り付ける