非プログラマーのためのインフォマティクス入門。(仮)

非プログラマーがインフォマティクスについて勉強したことを記録します。主にKNIMEというソフトを使用しています。

非プログラマーのためのインフォマティクス入門。(仮)

【KNIME】ノード紹介:Try, Catch Errors 〜折角流した処理がエラーで止まるのを回避する〜

みなさん、いかがお過ごしですか?

はてなブログには、どのくらいのページビューがあったのかを見ることができる機能があります。なんだか最近、ちょっとずつアクセスが増えているようです。

嬉しいので、もっと色々と更新したいのですが、今年度から担当になった新しい業務を覚えるのが大変で、なかなか記事を書けずにいます。*1

ちょっとずつですが書き続けますので、気長にお付き合いいただければ幸いです。

 

さて、今回はKNIMEのお話です。

f:id:sumtat:20180621232917p:plain

ちょっと使い方に慣れて色々なことをフロー化していくと、「よーし、今日はこのフローを流して帰ろう!明日には終わってるだろから、朝になったら結果を見よう!」みたいなことがあると思います。

で、朝になってみたら

「うわー、途中でError吐いて、とまっとるやんけ」

みたいな、残念なことになってる…。

あるあるですよね!

なるべく堅牢なフローにするにはエラー対策は結構重要だと思います。そこで、今回はエラー回避に役立つTryとCatch Errorノードを紹介したいと思います。*2

 今回の例題としては、

【複数のエクセルファイルを読んでまとめるが、その中にパスワード付きファイルがあって読み込めなかった】

というケースを取り扱ってみます。

f:id:sumtat:20180620231819p:plain

testというフォルダの中にfile1~file3のエクセルファイルがあり、file2にはパスワードをかけました。

「file2.xlsx」にはパスワードがかかっていることを知らない前提で、これらのファイルを読み込もうとするとこんな感じになるかなと思います↓

f:id:sumtat:20180620232348p:plain

  1.  List Filesでtestフォルダの中にあるファイルのPathを取ってきます
  2. Chunk Loop Startで、取ってきたFile Pathを1つずつ次のノードへ渡します
  3. Table Row to Valiableで、流れてきたデータを変数として次のノードへ渡します
  4. File Pathが変数になっているので、Excel Readerの設定で、対象ファイル名を変数として指定します
  5. (2こあるString Manipulationはちょっと無視して)Loop Endにたどり着くので、全ての行に対して繰り返し処理が終わるまで実行します。

ここで、特に手順2, 3が意味わからない感じの方は、下記を参考にしていただければ御理解頂けると思います。

キャプチャにもあるように、Execute Failedとなって止まっちゃってますね。

これは設定がおかしかったわけではなくて、パスワード付きファイルを読めなかったことに起因します。

このような、(設定はおかしくないけど)エラーになる場合、別のルートに流してくれるのがTryノードです

 

Tryノードを使ってエラーを回避するフロー例はこんな感じかなと思います↓

f:id:sumtat:20180620233923p:plain

TryとCatch Errorsをペアにして使います。Try~Catch Errorsの間がエラーで止まっちゃった場合、Catch Errorsの下側入力▶︎から入った情報が採用されるという仕組みです。

今回の記事の内容はこれが全てなのですが、いくつかString Manipulationが入ってたり、Column Filterを入れてたりするので、おまけ的な感じで紹介します(本質ではないです)。

 

まず、よりイメージしやすくするようにエクセルファイルの内容を貼り付けます↓

f:id:sumtat:20180620234733p:plain
f:id:sumtat:20180620234754p:plain

file1, file3はこんな感じです。file2は読めないので無視。で、処理の終わったあとのイメージがこんな感じ↓

f:id:sumtat:20180620234949p:plain

読み込むエクセルファイルにはなかったmemo, sourceの2列が増えてますね。これを作ってるのが、さっき無視した2つのString Manipulationです。

f:id:sumtat:20180620235252p:plain
f:id:sumtat:20180620235302p:plain
上段の2つ
f:id:sumtat:20180620235336p:plain
f:id:sumtat:20180620235347p:plain
下段の2つ

上段・下段とも、片方のString Manipulationノードを使ってmemoというカラムにOKまたはErrorという文字列を書き込むようにしています。

他方のString Manipulationノードでは、どのファイルの内容か?がわかるように、sourceという列に読み込んだファイル名を入れるようにしています。上段では変数のLocation、下段では流れてるデータとしてのLocationを使ってます。

で、下段のcolumn filterで使わないカラムを除いてます。

f:id:sumtat:20180621000315p:plain

Catch Errorsで、正常側・エラー対応側のどちらかのデータを受け取ったあと、Loop Endで繰り返し処理の終了です。

Loop Endの設定で、Allow changing table specificationsにチェックを入れておいてください。

f:id:sumtat:20180621000650p:plain

これにチェックを入れないと、Loop Endで受け取るデータは、常に同じカラムで構成されるものでないとエラーになります。今回はfile2を読めないので、

  1. 下段からくるデータにx, yというカラムがない(作っとけばいいんだけど)
  2. 上段からくるデータはx, y, memo, sourceの4つが揃ってる
  3. 上下の内容が違うじゃん。違ってもいいって宣言してないじゃん
  4. エラーでーす

という感じになって、折角エラー回避したのに最後でエラーみたいな極寒地獄が待っていますので、それぞれの状況に合わせた設定をするように心がけてください。

 

いかがでしたか?例えばwebから情報を取ってこようと思った時に、timeout errorだったりする場合などもあると思います。そんな時にも使える方法だと思います。

エラーになったやつを再度処理するフローに繋げるとか、色々と使い道が出てくるとおもいますので、試してみてください。

お金儲けのためとかじゃなく、ただの趣味(コミュニケーション相手は欲しい)でやってるので、コメントとかあれば気軽にお願いします。

 

気温差が激しい季節です。体調管理には気をつけましょう!

では、また次回。

*1:とはいうものの、今回のように更新していると、そんな暇があったら仕事を身につけろ・勉強しろ!などと叱咤激励を受けることもありそうですがね。別に仕事中にブログ書いてるわけじゃないんで許してくださいね。

*2:単純な例題が何かないかなーと考えても、なかなか出てこなくて記事を書くのに時間がかかりました。エラーを吐くケースを想像しようとしても中々出てこなかったりするので、実際の運用の際には、どこにエラーの可能性が潜んでいるかをよーく考えないといけないですね。