はじめに
この投稿は、RPAツール「UiPath」で Datatable からデータテーブルを比較する方法について、個人的にまとめたものです。
データテーブルの操作 シリーズ
DataTable の操作方法について記載した記事が、他にもあります。参考まで。
2つの DataTable を比較する
たまに、2つの DataTable を比較したいときがあります。たとえば
- Excel の Sheet1 と Sheet2 にある表が「内容が全く同じか?」を確認する
- Excel の Sheet1 と Sheet2 にある表で「内容が同じ行」を取得・確認する
- Excel の Sheet1 と Sheet2 にある表で「内容が違う行」を取得・確認する
というような場合です。
この場合、アクティビティを並べて「力技」で処理することも出来ますが、以下のようなLINQ 式を使用すると、簡単に比較できます。
以下で説明します。
2つの DataTable が「完全一致」するか
2つのデータテーブルで、中身が「完全一致」するか?は、以下のように判定します。
判定は、.AsEnumerable.SequenceEqual(比較するDataTable, DataRowComparer.Default)
で行い、全行の配列を比較をしています。比較方法をカスタマイズしたいときに「DataRowComparer.Default」を変更しますが、UiPathでは基本的に使わないので考慮不要です。
VBのコードにすると、以下のようになります。
'// 中身が一致するか判定
Dim isSameContents As Boolean = _
dt_1.AsEnumerable.SequenceEqual(dt_2.AsEnumerable, DataRowComparer.Default)
Console.WriteLine(If(isSameContents, "中身が一致一致", "中身が一致しない"))
2つの DataTable で「重複する行」を取得
2つのデータテーブルで「同じ内容の行」を取得するには、以下のように行います。
DataTable1 と DataTable2 の両方に含まれる要素を「積集合(Intersect)
」という方法で取得します。
VBのコードにすると、以下のようになります。
'// 同じ行を取得
Dim enm_datarow As IEnumerable(Of System.Data.DataRow) = _
dt1.AsEnumerable().Intersect(dt2.AsEnumerable(), DataRowComparer.Default)
'// 行数が 0 で無ければ DataTable に変換(0なら.Cloneで定義のみコピー/中身は無し)
Dim dt3 As DataTable = _
If(enm_datarow.Count <> 0, enm_datarow.CopyToDataTable(), dt1.Clone)
DataTable 型にしたければ「.CopyToTable()」を付けます。ただし、CopyToTable は、対象データ行がない場合はエラーになるので、上記のように「件数の有無」で分岐させると安心です。
2つの DataTable で「ユニークな行」を取得
2つのデータテーブルで「それぞれにしか無い行」を取得するには、以下のように行います。
DataTable1 から DataTable2 の行を取り除いた行を「差集合(Except)
」という方法で取得します。
VBのコードにすると、以下のようになります。
'// ユニークな行を取得
Dim enm_datarow As IEnumerable(Of System.Data.DataRow) = _
dt1.AsEnumerable().Except(dt2.AsEnumerable(), DataRowComparer.Default)
'// 行数が 0 で無ければ DataTable に変換(0なら.Cloneで定義のみコピー/中身は無し)
Dim dt3 As DataTable = _
If(enm_datarow.Count <> 0, enm_datarow.CopyToDataTable(), dt1.Clone)
終わりに
いかがでしたでしょうか。なにかの役に立てば幸いです。
この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。