繰り返し処理の途中からリトライしたい

Amazon等のECサイトから価格情報を取得しExcelに転記する処理を400個ほどの商品で繰り返したいのですが、途中でエラーとなった場合、そこでワークフローを終了せず、エラーとなった商品(またはその次の商品)から処理を続行することは可能でしょうか。解決方法ご存知の方いらっしゃいましたら、ご教授よろしくお願いいたします。

ワークフローの作り方にも依存しますが・・・。
最初に価格情報(あるいはその件数)を全件取得してしまって、価格取得-Excel転記を1件ずつ
ループを使って処理する構造にできるならば、[繰り返しをコンティニュー] アクティビティを使用して制御を簡素化することができると思います。
[繰り返しをコンティニュー] は、後続処理の実行を行わずにループの先頭から処理を実行してくれるので、1件ずつ処理・途中にエラーがあっても継続させるような処理には使いやすいと思います。

(想定したワークフローのイメージ)

1 Like

質問の主旨が、「どんなエラーがでるかわからないけどエラーが出たら再実行したい」でしたら、
処理内容を[トライキャッチ]アクティビティで囲うことで処理の続行ができます。

2 Likes

こんにちは

この手の話は例外処理設計に関わる部分かと思います。参考として、以下のドキュメント12項(特に12.3項あたり)を一度確認されると良いのではないかと思います。

yukinoさん
繰り返しをコンティニューというアクティビティがあることを知らなかったので使えそう!と思い試しましたが、当方したいことはトライキャッチに繰り返しをコンティニューを入れたいイメージです…繰り返し内の処理すべてにエラーの場合も続行Trueを設定するしかないですかね…
ご回答ありがとうございました。

繰り返し内にリトライループ(無限にしないこと)を作り、その中にTryCatchで処理を書く。
例外が発生したらリトライループを抜けない。
リトライ有無をBool変数とし、リトライリミットを別変数にして回数制限するか、ループ変数(例えば i)にしてループ判定を10回、正常時99設定とかにする。
(リミット超えたらロボット停止処理となる(はず)のでその辺も考慮してください)

1 Like

トライキャッチでは、トライに正常処理を記入し、キャッチに正常処理実行中にエラーが発生した場合の処理を記入します。
そのため、 @yukino さんの2つ目のワークフローの

Tryの中に

ECサイトから価格情報を取得しExcelに転記する処理

Catchの中に

途中でエラーとなった場合の処理 (何も書かなければ、次の商品の処理が続きます)

で実現できると思われます。

この部分が @yukino さんが組んだ2つ目のフローで完成できます。

一度お試しください。

2 Likes

Legacy32さん
リトライループとはどういったものでしょうか。初心者なもので…

@kana612
繰り返し(後判定)
でいいと思います。
上の例で言えば、条件を Bool変数判定(b処理完了=Falseとか)にするか、i<10(Forループもどき)とかにします。
後者の場合、使用変数が1つで済むので私としては好みです。ループ抜けた後、判定で i<99ならロボット停止と書けますし。

質問にエラーで次の商品とあるので停止はしなくていいですね。
しかし、スキップした場合は何らかの方法でわかるようにしたほうがいいと思います。
また、10や 99のマジックナンバーは変数に定数として書いてもいいし、コメントで書いても後でわかればかまいません。
(コーディング基準があればそれに合わせてください)

KatoRさん
トライキャッチではエラーになった場合繰り返しを抜けてしまうと思っていました。
仰る通りできれば理想ですが、トライキャッチアクティビティは、CatchかFinallyのどちらかには処理を設定する必要があるようです…

TryCatchの詳細は以下などを参照していただくとして、

Try
 処理A
 処理B
 ・・・
 i=99
Catch
 Exception(←これは指定が必要)
  処理なしでも可

(今回の場合、Finallyは何も書かなくていいでしょう)

上記の場合、処理A~i=99までの間のどこかでエラーが発生したら、即時Catch Exceptionへ処理が移ります。で、Exception内の処理を終えたら、Tryブロックを抜けるだけです。エラーでループを抜ける場合はここに breakなどを記述しないと抜けてくれません。
(i のカウントアップはTryブロックの外に書くほうがいいと思います)

ちなみに Finallyは例えば Tryの中でファイルオープン、クローズする場合、エラーでクローズ処理に到達できない時のためなどに、Finallyにクローズを書きます。(Finallyはエラーの有無に関わらず実行される)

@KatoR さん
CatchesにException設定抜けていただけでした。試してみます。ありがとうございます。

1 Like

Exceptionについては様々な種類がありますが、全てのエラーを無視したいのであれば、
System.Exceptionを指定しておけば大丈夫です。
ただし、全てのエラーを処理してしまうため、想定外のエラーにも気づけない可能性もあります。そのため、起こりうるエラーが分かっているのであれば、特定のExceptionのみを指定し、その他想定外のエラーについては発生時にExceptionを追加する方がフローとしての品質はより良いものができると思います。

以下は参考までに。
エラーの種類によって動作を分類したいのであれば、Exceptionに複数の種類を設定し、
それぞれに対してフローを作成すると良いです。
例えば、ECサイトから商品名が取得できず、Nullになることがあった場合、Null参照のエラーなどが考えられます。
この場合、NullReferenceExceptionを設定すれば、商品名が取得できなかったときの処理ができます。

ご丁寧な説明ありがとうございます。
今回の件からは少し逸れますが、System.Exceptionを設定しているのに例外発生時Catchesに入ってくれない原因って何か考えられることありますでしょうか…?

System.Exception発生時の処理に何も無ければ、例外発生したかは見た目では分かりません。
System.Exceptionに入ったか確認したい場合は、添付した画像のようにメッセージボックスアクティビティを使用しメッセージボックスとして出力するか、メッセージをログアクティビティを使用して出力タブにメッセージを出力する方法があります。
前者の方法の場合、メッセージボックスが表示されるため、シナリオが停止しますのでご注意ください。

フロー

出力タブ(左下)
Try-Catch2

メッセージボックス入れてますが表示されません。
エラーが発生していること、Catchesに入っていないことはデバッグ実行により確認済です。

エラー発生時のスクリーンショットを投稿いただけますか?
可能であれば、Try-Catchアクティビティもお願いいたします。

こんにちは

可能性のひとつとして
Global Exception Handlerが設定されていて、ErrorAction.Ignoreが設定されている
ということはありませんでしょうか?
プロジェクトパネルで左まわりの矢印みたいなアイコンのファイルがあると怪しいかも。

1 Like

@Yoichi さん
グローバルハンドラーにErrorAction.Abort設定しています。
トライキャッチよりもグローバルハンドラーが優先されるということでしょうか。