じっぱひとからげ

十把一絡げになんでもかんでもつづる。

UiPath入門(6)〜CSVを読み込んでLINEのメッセージに出力する

blog.jippahitokarage.com

UiPath入門(2)では、zaimにログインするところまでをRecordingで取り込む作業を紹介した。今回はその続きを紹介する。この自動化の取り組みは、わが家のzaimの家計簿データを対象として、「未分類」に仕分けられたものの一覧をLINEのメッセージに通知するというものだ。

<実装の内容>
(1)zaimにログインする(前回はここまで)

(2)家計簿データをダウンロードする

(2)家計簿から「未分類」を抽出する

(3)LINEに未分類の一覧を通知する

全体のフローチャート

フローは以下の通り。それぞれのSequenceについて内容を見ていくことにする。

f:id:jippahitokarage:20170819082553p:plain

CSVのダウンロード

zaimへのログインについては、こちら(UiPath入門(2)〜Recordingで作業内容を取り込んで再生する - じっぱひとからげ)参照。

f:id:jippahitokarage:20170819084653p:plain

CSVをダウンロードする際、そのままのファイル名で保存しても良いが、後続の読み込みを簡易化するため、名前をつけて保存することにする。ここではdatestrという名前のString型の変数を指定してファイル名としている。

f:id:jippahitokarage:20170819084701p:plain

「Type Into」Activityには datastr[k(enter)] と指定しているのは、datestrというString型の変数に格納された文字列をキーボードで入力したあとでENTERキーを押すことを指示している。datastrはあらかじめ now.Date.Year.ToString+now.Date.Month.ToString+now.Date.Day.ToString という文字列で初期化してある。

f:id:jippahitokarage:20170819084706p:plain

nowは現在の日付・時刻を持つオブジェクトで2017年現在だとnow.Date.Year.ToStringは"2017"を返す。つまり、datestrには今日日付の場合"20170819"が格納されている。日付や時刻に関する操作は頻繁に登場するのでぜひ覚えておきたい。

少し話はそれるが、もっとシンプルにnow.toString("yyyyMMdd")と出力するフォーマットで指定することもできる。例えばMessage Boxにこのように定義して出力すると、同じ結果が得られる。
f:id:jippahitokarage:20170819090140p:plain

f:id:jippahitokarage:20170819090243p:plain

さらに、AddDaysを使うことで日付を前後させることもできる。

f:id:jippahitokarage:20170819090551p:plain

f:id:jippahitokarage:20170819090555p:plain

もちろん、引数に負の数を入れれば前日、前々日の日付も取得できる。

さて、これでyyyyMMdd.csvというファイルがダウンロードできた。

CSVを読み込む

CSVの読み込みは非常にシンプルで、「Read CSV」Activityにファイルパス、文字コード、読み込む変数、デリミタを指定するだけで良い。

CSVを読み込むためのDataTable型の変数を宣言しておく。ここではdtZaimDataという名前のDataTable型の変数を用意した。
f:id:jippahitokarage:20170819091001p:plain

「Read CSV」Activityを用意する。
f:id:jippahitokarage:20170819090951p:plain

Propertiesで読み込むファイルの場所File Pathと、読み込むときの文字コードEncordingと、どの変数に読み込むのかOutputを指定する。読み込む対象はCSVなのでデリミタDelimitatorはCommaのままで良い。CSVの先頭行が列名を示しているのであれば、IncludeColumnNamesにチェックを入れておく。
f:id:jippahitokarage:20170819091003p:plain

もちろん、指定するファイルはこれまでの工程でzaimからダウンロードしたCSVで、ファイル名はdatestr+".csv"だ。zaimではダウンロード時に文字コードを選択できるが、デフォルトではShift-JISになっているようなので、ここではShift-JISを指定している。

CSVをフィルタして出力する

zaimのCSVの列名は以下のようになっている。基本的にはこれまでの振り分けルールなどから食料品を買ったのか外食なのかなどを判定してくれるが、zaimが判定しきれなかったものは「未分類」とされる。そこで、わが家の家計簿の判定が「未分類」となったものだけ抽出したい。

実際のCSVはこちら。家計が丸出しなので列名以外は伏せておく。
f:id:jippahitokarage:20170819092503p:plain

やりたいことは、"ジャンル"列が"未分類"のデータだけを抽出するということ。こちらが実際のフローチャートだ。普段からプログラミングに慣れている人なら、見ただけで内容は把握できると思う。

f:id:jippahitokarage:20170819093402p:plain

「For each」Activityを利用して、DataTable変数に可能されたデータを1行ずつ取り出し、「If」Activityで"ジャンル"列が"未分類"かどうかを判定し、Trueの場合はmessageというString型の変数に格納してiをインクリメントし、Falseの場合は何もしない。これを繰り返すことにより、messageには"ジャンル"列が"未分類"の行だけ取り出されることになる。

もしかすると、DataTableに対してSQLを投げるActivityがあるのかもしれない。現時点で私が調べきれていないだけなので、もっとスマートな方法がある可能性があることは承知いただきたい。

代入は「Assing」Activityを利用する。左辺に右辺を代入する。messageについては、このような式を書いている。

message = message+row("日付").ToString+",”+row("ジャンル").ToString+",収入"+row("収入").ToString+",支出"+row("支出").ToString+","+row("商品").ToString+","+row("メモ").ToString+Environment.newline

列名の指定はInt型で列番号を指定することもできるし、CSVの読み込みのときに1行目が列名であるとしている場合は、列名を文字列で指定することもできる。また、ここは少しハマったところではあるが、改行コードはEnvironment.newlineで表現される。"\n"と入力してもただの文字列としか判断されないので注意。

また「Log message」Activityは標準出力に任意の文字列を出力できるので、読み込んだCSVの内容を確認するのに利用している。

LINEにメッセージを送信

LINEはWindows用のデスクトップアプリケーションをインストールしておく。ログインについてはzaimのようなWebアプリケーション同様、ユーザIDとパスワードを入力することで自動化できる。

ここで"未分類"を抽出したString型のmessageをメッセージ欄に入力して送信する。

f:id:jippahitokarage:20170819101425p:plain

スマホの画面で見るとこんな感じ。messageの行末には改行コードが入っているので、LINE上は1つずつが別の発言として送信される。

f:id:jippahitokarage:20170819101907p:plain

これで、わが家の家計簿の"未分類"一覧をLINEに通知する仕掛けができた。今回のケースのようにブラウザ上のWebアプリとWindowsアプリケーションであるLINEを横断するような自動化の仕掛けが簡単に実装できることこそRPAの真価が発揮される場面なのだと思う。

UiPath入門シリーズはこちら

blog.jippahitokarage.com