VB.NET如何检测DataGridView中不连续的重复数据?
Got it, let's sort out this duplicate data issue in your VB.NET code. The root problem with your original nested loop is that it only checks adjacent rows—so when duplicates are scattered across non-consecutive rows, it misses them entirely, leading to accidental execution of save_data() and form closure.
Here are two reliable approaches to catch all duplicate values in the 0th column, regardless of their position:
Approach 1: Use a HashSet for Efficient Detection
This method uses a HashSet to track values we've already seen. It's fast (O(n) time complexity) and stops as soon as it finds the first duplicate.
' Initialize a HashSet to store unique values from column 0 Dim seenValues As New HashSet(Of String)() Dim duplicateFound As Boolean = False ' Iterate through each row in the DataGridView For Each row As DataGridViewRow In YourDataGridViewName.Rows ' Skip the new blank row (if your grid allows user row additions) If row.IsNewRow Then Continue For ' Handle null/DBNull values to avoid errors Dim cellValue As String = If( row.Cells(0).Value Is DBNull.Value Or row.Cells(0).Value Is Nothing, "", row.Cells(0).Value.ToString().Trim() ) ' Skip empty cells (adjust this logic if empty values should be considered duplicates) If String.IsNullOrEmpty(cellValue) Then Continue For ' Check if the value already exists in our HashSet If seenValues.Contains(cellValue) Then duplicateFound = True MessageBox.Show("Duplicate Data!") Exit For ' Stop checking further once a duplicate is found Else ' Add the new value to the HashSet seenValues.Add(cellValue) End If Next ' Only proceed to save and close if no duplicates were found If Not duplicateFound Then save_data() Me.Close() End If
Key Notes for This Approach:
- If your 0th column stores numeric values (like integers or decimals), replace
HashSet(Of String)withHashSet(Of Integer)(or the appropriate numeric type) to avoid string conversion issues. - Adjust the empty cell handling based on your requirements—if empty cells should be treated as duplicates, remove the
If String.IsNullOrEmpty(cellValue) Then Continue Forline.
Approach 2: Use LINQ to Find All Duplicates
If you need to identify all duplicate values (not just the first one), LINQ is a clean way to group and count occurrences. This is useful if you want to show the user exactly which values are duplicated.
' Use LINQ to group rows by column 0 values and find groups with multiple entries Dim duplicateGroups = From row In YourDataGridViewName.Rows.Cast(Of DataGridViewRow)() Where Not row.IsNewRow Let cellValue = If( row.Cells(0).Value Is DBNull.Value Or row.Cells(0).Value Is Nothing, "", row.Cells(0).Value.ToString().Trim() ) Where Not String.IsNullOrEmpty(cellValue) Group row By cellValue Into RowGroup = Group Where RowGroup.Count() > 1 ' Check if any duplicates exist If duplicateGroups.Any() Then ' Optional: List all duplicate values in the message Dim duplicateValues = String.Join(", ", duplicateGroups.Select(Function(g) g.cellValue)) MessageBox.Show($"Duplicate Data! Found duplicates for: {duplicateValues}") Else save_data() Me.Close() End If
Why This Works Better Than Your Original Nested Loop:
Your original code likely compared each row only to its immediate neighbor (e.g., row(i) vs row(i+1)), which only catches consecutive duplicates. By using a HashSet or LINQ grouping, we check every value against all previously seen values, ensuring no non-consecutive duplicates slip through.
内容的提问来源于stack exchange,提问作者Rak

