はじめに
この投稿は、RPAツール「UiPath」で Datatable から「重複行の取得」をする方法について、個人的にまとめたものです。
UiPathブログ発信チャレンジ の 11日目の記事です。
データテーブルの操作 シリーズ
DataTable の操作方法について記載した記事が、他にもあります。参考まで。
重複のパターン
今回の記事で言う「重複」とは「同一 DataTable 内で、内容が重複している行」を指します。2つのデータテーブルでの比較 の話なら、以下の記事を参考にしてください。
重複のパターンは、大きく分けて「2つ」です。
- A)行単位で重複している(全ての列で内容が同じ)
- B)列の一部で重複している(一部の列で内容が同じ)
重複の検出方法
上記のような重複行を「取得」する方法は、以下の「2つ」があります。
- 1)行ループしながら、重複行を抽出
- 2)Linqの「Where」で、重複行を抽出
以下で順に説明します。
1)行ループしながら、重複を抽出
原始的な方法ですが、以下のように行ループしながら、同じ内容の行を抽出します。
ポイントは、データ行のループを回しながら、自分自身のデータテーブルに「同じデータがあるか?」を問い合わせて、「1件」なら重複なし、「2件以上」なら重複あり としているところです。
この方法の場合、行の数が多いほど、繰り返しアクティビティの処理コストがかかる
ため、遅くなります。
速度が気になる場合は、以下のように「InvokeCode」アクティビティ内でループ処理をすると良いです。
'// 引数
'// - in_dt:元のデータテーブル
'// - out_dt:重複がある行 だけのデータテーブル
'// 定義だけのDatatableを用意(.Clone:定義あり/中身のデータ無し)
out_dt = in_dt.Clone
For Each row As DataRow In in_dt.Rows
'// 「重複なし」なら該当件数1、「重複あり」なら該当件数2以上
If in_dt.Select(String.Format("[ProductID] = '{0}' AND [ShopID] = '{1}'",
row("ProductID").ToString,
row("ShopID").ToString)
).Count > 1 Then
'// 重複あり:データテーブルに行追加(配列で行追加)
'// (Rowで行追加すると「この行は既に別のテーブルに属しています」エラーになる)
out_dt.Rows.Add(row.ItemArray)
End If
Next
2)Linqの「Where」で、重複を抽出
Linqで条件を指定して、重複している行だけを抽出します。
重複行がない場合を考慮して、「ary_row」に一旦データを格納し、データがあった場合は「.CopyToDataTable」でデータテーブルに変換し、データがなかった場合は、元のデータテーブルを「.Clone」して空のデータテーブルをセットします。
以下のように「InvokeCode」アクティビティ内で処理する事もできます。
'// 引数
'// - in_dt:元のデータテーブル
'// - out_dt:重複がある行 だけのデータテーブル
Dim ary_row As DataRow()
ary_row = (From row In in_dt.AsEnumerable()
Where (
From row_ In in_dt.AsEnumerable()
Where row("ProductID").ToString = row_("ProductID").ToString AndAlso
row("ShopID").ToString = row_("ShopID").ToString
Select row("ProductID")
).Count > 1
).ToArray
out_dt = If(ary_row.Count > 0 ,ary_row.CopyToDataTable, in_dt.Clone)
終わりに
以上、DataTableの重複行の取得方法について、でした。なにかの役に立てば幸いです。
この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。