[英]Get DataGridView cell value in nested For Loops
我在DataGridView
上显示了一些数据,在我的btnSave_Click
事件中,我调用了一个子例程来验证网格中的数据,然后将其保存到我的数据库中。
我这样做的方法是为每一行使用一个循环,在每个行中使用另一个for循环。
然后我需要比较它正在验证的单元格值中的每个字符(行dr,单元直流)。 但是,我无法解决使用行/列坐标来获取单元格中的值的方法。
这有点难以解释我的意思,但是在这段代码中,我在前2行设置For Loops
,然后在第3行,注意If IsDBNull(dc.TextInCell)
- TextInCell是我需要替换的。
在排队; 博士和专栏; dc,我需要验证存储在该单元格中的值...
For Each dr As DataGridViewRow In dgvImport.Rows
For Each dc As DataGridViewColumn In dgvImport.Columns
If dc.HeaderText = "Product Code" Then
If IsDBNull(dc.TextInCell) = True Or dc.TextInCell = Nothing Or dc.TextInCell = "" Then
Me.Cursor = Cursors.Default
MsgBox("Import failed. One or more required fields were not entered", MsgBoxStyle.OkOnly, "Error")
Exit Sub
End If
For Each c As Char In dc.TextInCell
If Not Char.IsLetterOrDigit(c) Then
If Not Char.IsWhiteSpace(c) Then
If c <> "&" AndAlso c <> "-" AndAlso c <> "(" AndAlso c <> ")" Then
Me.Cursor = Cursors.Default
MsgBox("Import failed. One or more cells contains an invalid character", MsgBoxStyle.OkOnly, "Error")
Exit Sub
End If
End If
End If
Next
如何从此处将单元格值转换为变量以通过验证发送?
它(几乎)总是更快地迭代数据表中的行而不是通过控件的根。 您的代码中至少还有一个效率低下:
For Each dr As DataGridViewRow In dgvImport.Rows
For Each dc As DataGridViewColumn In dgvImport.Columns
If dc.HeaderText = "Product Code" Then
您不需要为每一行找到目标列 - 它将在每行的相同索引处。
我不知道这些预期的模式是什么,但如果有一个定义的模式,如“N-LLL-AAA-NLN”(例如: 9-WDM-6K6-6ZC
),您可能需要查看RegEx以进行全面的模式测试。 例如,您的代码基本上只是在字符串中的任何位置测试一组有限的特殊字符; 如果有(
不应该在任何之前)
?
你肯定需要摆弄实际的验证代码,但这要快很多倍:
'... code to fill the DT
' add a column to track if the row is valid
dtSample.Columns.Add(New DataColumn("IsValid", GetType(Boolean)))
Dim specialChars = "&-()"
Dim txt As String = ""
Dim bValid As Boolean
Dim prodIndex As Int32
' index of the target column using the column name
prodIndex = dtSample.Columns.IndexOf("ProductCode")
For Each dr As DataRow In dtProduct.Rows
' get the text
txt = dr.Field(Of String)(prodIndex)
' first check for nothing from DBNull
bValid = String.IsNullOrEmpty(txt) = False
' if there is text data, check the content
If bValid Then
' each char must be letter, digit or authorized special char
For n As Int32 = 0 To txt.Length - 1
If Char.IsLetterOrDigit(txt(n)) = False AndAlso
specialChars.Contains(txt(n)) = False Then
bValid = False
Exit For
End If
Next
End If
' unabiguously set the column for each row
dr("IsValid") = bValid
Next
dgv1.DataSource = dtSample
' hide our scratch column
dgv1.Columns("IsValid").Visible = False
结果:
未显示RowPrePaint
事件中的2-3行,以对IsValid
为false的行着色。 更重要的是,它很快:处理75,000行125毫秒 ; 通过DGV挖掘并反复找到相同的列需要7-8秒。
即使没有RegEx,您也可以测试特定位置的特殊字符(假设固定模式)。 例如,要测试"A-78*X(2012)"
:
bValid = pcode(1) = "-"c AndAlso
pcode(4) = "*"c AndAlso
pcode(6) = "("c AndAlso
pcode(11) = ")"c
您还可以按字符分割字符串,以便测试parts(3)
是2010年和2015年之间的值或其他任何值,如果您想要执行该级别的测试。 你做的越多,RegEX就会越有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.