概要
UiPathの「For Each Row / 繰り返し(各行)」アクティビティの中で、特定行だけ削除する方法です。
問題
UiPathでExcelファイルを処理すると、DataTable型には必ずお世話になると思います。
そして、DataTable型の変数を、「For Each Row / 繰り返し(各行)」で順次に処理していくのも、かなり多いワークフローのパターンになると思います。
「For Each Row / 繰り返し(各行)」の中で、row(行に該当する変数)を読むだけなら何も問題ありません。
ところが、処理している行を削除したいとき、方法を知らないと躓くことが多いようです。
たとえばこのような設定。rowの2番目の要素をInt32型に変換して、値が「1」ならその行を削除する簡単なロジックです。一見、動きそうに見えますが、
こうなります。
原因は、「For Each Row / 繰り返し(各行)」を実行中に、そのDataTableに変更が加わったために、現在処理している行が特定できなくなった、といった感じです。(厳密にはちょっと違うのですが、話を進める上で不要なので割愛します)
そして、確かに自分で行を削除しているので、DataTableに変更が加わっているのも当然なのです。これでは困りますね。
対策
「For Each Row / 繰り返し(各行)」ではなく、「For Each / 繰り返し(コレクションの各要素)」を使います。
ポイントは2つです。
- 「For Each / 繰り返し(コレクションの各要素)」の、TypeArgumentを、 System.Data.DataRowにする。
- 対象のコレクションにDataTable型変数をそのまま設定せず、**DataTable型変数.Select()**で一時的な配列に変換する。
細かい解説は省きますが、これで「データ行を削除」が例外(エラー)にならずに動作します。
(原理的には「繰り返し中に、テーブルを直接弄ると叱られるので、いったん内容をコピーした配列を用意して、それを順番に処理することで、元のテーブルの変更を無視できる」ぐらいに思ってください)