我有一个代码可以根据几种不同污染物的定义标准对数据网格中的单元格进行着色,效果很好。但是,通常会出现字符''在类似"< 0.005"的情况下,意味着"低于检测限",并且该例程会使用消息"运营商''未定义类型' DBNull'并输入' Double'。"
编辑:这是JohnG提供的最新代码。当潜艇遇到空单元格或无效字符时,我仍会收到错误消息
<html>
<head>
<title>Consume Click Test</title>
</head>
<body>
<div><a id = "link" style="border: solid 1px black; vertical-align:middle; display:inline-block;" > <button style="position: relative; float: right;" onclick="detectClick('Google')"><img src="cross.png"></button>Google</a> </div>
</body>
</html>
<script type="text/javascript">
function detectClick(message){
window.alert("Detected: " + message);
document.getElementById("link").href = "http://www.google.com";
}
</script>
答案 0 :(得分:1)
我不完全确定我是否遵循你的要求,如果我错了,请纠正我。我猜测值“&lt; 0.005”是DataGridView
单元格中的值。如果是这种情况,那么您需要将此“字符串”值更改为“十进制”。我提供的上一个代码在进行比较之前未检查空数字或无效数字。由于单元格值可以是任何值,因此代码需要检查两件事:空单元格值或空单元格值或无效数字。你得到的错误可能来自两种情况。
您的评论
如何使例程忽略&lt;字符,用“”替换它或用零替换整个字符串?
在这种情况下,当单元格包含值“&lt; 0.005”时,将抛出您看到的错误,因为将字符串与double进行比较将不起作用。由于您在上面说明将该值设置为零(0)就足够了,我建议您使用TryParse
方法。如果TryParse
方法的编号无效,则返回零(0)。您可以使用这些知识来实现您描述的内容。
我建议您使用与Excel单元格相同的策略。我更改了GetElementColorsValues
方法以返回Decimal
数组。如果DataGridView
中的值是十进制值,则必须进行此更改。
Public Function GetElementColorsValues(elementName As String) As Decimal()
Dim ULArray(4) As Decimal
Select Case elementName
Case "Arsenic"
ULArray(0) = 8
ULArray(1) = 20
ULArray(2) = 50
ULArray(3) = 600
ULArray(4) = 1000
Case "Cadmium"
ULArray(0) = 1.5
ULArray(1) = 10
………..
现在有了这个数组,我们可以比较DataGridView
中的小数值。我使用Decimal.TryParse
从单元格字符串值中获取Decimal
值,如下所示
Decimal.TryParse(curValue, decimalValue)
以上curValue
是来自DataGridView
单元格的字符串,decimalValue
是将字符串解析为小数的重新调整的Decimal
值。如果解析成功,整行Decimal.TryParse(curValue, decimalValue)
将返回true,如果不成功则返回false。
方便的一点是,如果解析不成功(比如值<0.005),TryParse
会将变量decimalValue
设置为零(0)。简单地使用Decimal.TryParse
会在变量失败时将变量decimalValue
设置为零,如果成功则将其设置为有效的十进制数。这可以在下面的代码中看到,然后检查null或空值,如果不为null或为空,则使用Decimal.TryParse
来获取用于着色比较的小数值。它使用着色Excel单元格时使用的相同GetElementColorsValues(colName)
方法...您还必须更改excel着色代码以适应Decimal数组...此方法下方
更新编辑以捕获数据表中的BDNULL单元格
我错了,从技术上讲,你可以在DataTable
中有一行不包含列数据。所以行row.Cells(colName).Value
显然会抛出你得到的错误。我不是说这是问题,但这是我能够重现你的错误的唯一方法。因此,下面的代码会检查这些缺失的数据列。我将代码更改为使用DataBoundItems
,因为您在代码中使用了此代码;下面是不使用数据绑定项所需的更改。两者都有效,但是如果表格被排序或行删除等情况可能不是这样的话。我的下一个问题是,如果它们很好,你会把这些空行读入数据表...... EMPTY?
显然,在将网格编写为excel时,您需要进行这些更改。
Private Sub SetDGVColColor()
Dim ULArray As Decimal()
Dim curValue As String
Dim decimalValue As Decimal
Dim colName = ""
For col As Integer = 2 To dgvElements.ColumnCount - 1
colName = dgvElements.Columns(col).Name
ULArray = GetElementColorsValues(colName)
Dim curDataBoundRow
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
curDataBoundRow = row.DataBoundItem ' <-- Added Code
If (Not IsDBNull(curDataBoundRow(colName))) Then ' <-- Added Code
curValue = curDataBoundRow(colName)
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
' the above TryParse line will set decimalValue to 0 if curValue is not a valid decimal i.e `<0.005`
Select Case decimalValue
Case >= ULArray(4)
row.Cells(colName).Style.BackColor = Color.BlueViolet
Case >= ULArray(3)
row.Cells(colName).Style.BackColor = Color.Red
Case >= ULArray(2)
row.Cells(colName).Style.BackColor = Color.Orange
Case >= ULArray(1)
row.Cells(colName).Style.BackColor = Color.Yellow
Case >= ULArray(0)
row.Cells(colName).Style.BackColor = Color.LawnGreen
Case Else
row.Cells(colName).Style.BackColor = Color.DodgerBlue
End Select
End If ' cell is empty
End If ' ignore null cells in data table <-- Added Code
End If ' ignore the new row if present
Next
Next
End Sub
在不使用数据绑定项的情况下更改代码。
…….
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
If (Not IsDBNull(row.Cells(colName).Value)) Then ' <-- ADDED code
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
…….
使用十进制值比较更改color excel单元格方法。
Private Sub SetExcelColColor(worksheet As Microsoft.Office.Interop.Excel._Worksheet, colName As String, colIndex As Integer)
Dim rIndex = 2
Dim cIndex = colIndex
Dim ULArray = GetElementColorsValues(colName)
Dim curValue As String
Dim decimalValue As Decimal
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
Select Case decimalValue
Case >= ULArray(4)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.BlueViolet)
Case >= ULArray(3)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red)
Case >= ULArray(2)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Orange)
Case >= ULArray(1)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
Case >= ULArray(0)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LawnGreen)
Case Else
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.DodgerBlue)
End Select
rIndex += 1
End If ' ignore empty cell
End If ' ignore new row
Next
End Sub
答案 1 :(得分:0)
您报告的错误与“&lt;”的存在无关在你的字符串中。这是因为你试图对空值进行实际的小于比较。那是无效的 - 没有比较价值。在执行操作之前,您需要检查字段是否为null,而是执行其他操作:
If Me.DataGridView2.Rows(i).Cells("Cd (Kadmium)").Value IsNot DBNull.Value Then
'continue with the comparisons
Else
'do something else
End If
然而,你是对的,“&lt;”的存在在尝试将值转换为Double以进行比较时,也会出现问题。
为此你可以做一个简单的字符串替换,例如
Dim val = Me.DataGridView2.Rows(i).Cells("Cd (Kadmium)").Value.ToString().Replace("<", "")
Dim dVal = Convert.ToDouble(val)
If dVal < Ul1Cd Then
'etc
答案 2 :(得分:0)
同时检查你的第二个循环:
For i As Double = 0 To Me.DataGridView2.Rows.Count - 1
你只需要
for i = 0 To Me.DataGridView2.Rows.Count - 1
既然你之前宣称它并且是双倍的? 还要确保在项目编译选项中设置选项strict strict并推断为off。