Option Strict On Public Class Form1 Private ds As DataSet Private tbl As DataTable Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load ds = New DataSet() tbl = ds.Tables.Add("tbl") ' 8 個の列を持つテーブル tbl.Columns.Add("F1", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F2", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F3", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F4", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F5", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F6", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F7", GetType(Integer)).AllowDBNull = False tbl.Columns.Add("F8", GetType(String)).AllowDBNull = True 'そのうち 7 つの列に一意制約を追加する Dim cols() As DataColumn = "F1 F2 F3 F4 F5 F6 F7".Split().Select(Function(f) tbl.Columns(f)).ToArray() tbl.Constraints.Add(New UniqueConstraint("UniqueKey1", cols, False)) '検証用のダミーデータ tbl.Rows.Add(1, 1, 1, 1, 1, 1, 1, "aaa") tbl.Rows.Add(2, 1, 1, 1, 1, 1, 1, "bbb") tbl.Rows.Add(3, 1, 1, 1, 1, 1, 1, "ccc") tbl.Rows.Add(4, 1, 1, 1, 1, 1, 1, "ddd") tbl.Rows.Add(5, 1, 1, 1, 1, 1, 1, "eee") tbl.Rows.Add(6, 1, 1, 1, 1, 1, 1, "fff") tbl.Rows.Add(7, 6, 5, 4, 3, 2, 1, "ggg") tbl.Rows.Add(8, 7, 6, 5, 4, 3, 2, "hhh") tbl.Rows.Add(9, 8, 7, 6, 5, 4, 3, "iii") '制約を外しておく ds.EnforceConstraints = False DataGridView1.DataSource = tbl DataGridView1.AutoResizeColumns() Button1.Text = "制約で競合検証" Button2.Text = "ループで競合検出" Button3.Text = "LINQで競合検出" End Sub Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Try ds.EnforceConstraints = True MessageBox.Show("エラー無し") Catch Dim sb As New System.Text.StringBuilder() For Each r In tbl.GetErrors() sb.AppendLine(r.RowError) Next MessageBox.Show("エラーあり" & vbCrLf & sb.ToString()) Finally ds.EnforceConstraints = False End Try End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click Dim GetKey As Func(Of DataRow, String) = Function(r) String.Join( _ "-", "F1 F2 F3 F4 F5 F6 F7".Split().Select(Function(f) CStr(r(f)))) Dim sb As New System.Text.StringBuilder() Dim view As New DataView(tbl, "", "", DataViewRowState.CurrentRows) For i = 0 To view.Count - 2 Dim key1 = GetKey(view(i).Row) For j = i + 1 To view.Count - 1 Dim key2 = GetKey(view(j).Row) If key1 = key2 Then sb.AppendLine(String.Format("{0}行目と{1}行目の値が同じです。", i + 1, j + 1)) End If Next Next If sb.Length = 0 Then MessageBox.Show("競合無し") Else MessageBox.Show(sb.ToString()) End If End Sub Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click Dim GetKey As Func(Of DataRow, String) = Function(r) String.Join("-", "F1 F2 F3 F4 F5 F6 F7".Split().Select(Function(f) CStr(r(f)))) Dim Indexes()() As Integer Indexes = tbl.AsEnumerable() _ .Select(Function(Row, Index) New With {Index, .Key = GetKey(Row)}) _ .GroupBy(Function(r) r.Key, Function(r) r.Index) _ .Where(Function(r) r.Count() > 1) _ .Select(Function(r) r.Select(Function(Index) 1 + Index).ToArray()).ToArray() If Not Indexes.Any() Then MessageBox.Show("競合無し") Else Dim sb As New System.Text.StringBuilder() For Each lines In Indexes sb.Append(String.Join("、", lines)).AppendLine("行目が重複しています。") Next MessageBox.Show(sb.ToString()) End If End Sub End Class