我在DataGridView
上显示了一些数据,在btnSave_Click
事件中,我正在调用子程序来验证网格中的数据,然后将其保存到我的数据库中。
我正在这样做的方法是为每一行使用一个循环,并为每个列使用另一个for循环。
然后我需要比较它正在验证的单元格值中的每个char(row dr,cell dc)。但是,我无法解决使用行/列坐标来获取单元格中的值的方法。
有点难以解释我的意思,但是在这段代码中,我在前2行设置For Loops
,然后在第3行设置,注意If IsDBNull(dc.TextInCell)
- TextInCell是我的意思需要更换。
In Row;博士和专栏; 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
如何从此处将单元格值转换为变量以通过验证发送?
答案 0 :(得分:3)
迭代数据表中的行(几乎)总是比通过控件的行更快。您的代码中至少还存在一个低效率:
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
),你可能想要查看 { {3}} 用于全面的模式测试。例如,你的代码基本上只是在字符串中测试一组有限的特殊字符 where ;如果有(
不应该在任何)
之前?
你肯定需要摆弄实际的验证码,但这要快很多倍:
'... 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
为假的行着色。更重要的是,它很快: 125毫秒来处理75,000行;通过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就会越有用。