首先发布在这里。如果我应该在其他地方或其他地方发布,请随时告诉我。 :)
我用Google搜索了“字符串比较”和“字符串不等式”的变体,但它们的结果毫无用处。我的问题是我正在检查字符串不等式,当一方为空而另一方不是时,我得到了令人惊讶的结果。请考虑以下演示代码:
TestStr "foo", "foo", "="
TestStr "foo", "bar", "<>"
TestStr Null, "foo", "<>"
TestStr "foo", Null, "<>"
Sub TestStr(left, right, expected)
' I actually don't care about this - it's here for reference
If left = right Then
WScript.Echo "left = right - expected " & expected
Else
WScript.Echo "left <> right - expected " & expected
End If
If left <> right Then
WScript.Echo "left <> right - expected " & expected
Else
WScript.Echo "left = right - expected " & expected
End If
WScript.Echo ""
End Sub
运行此代码会产生以下输出(“编码”,因此未格式化):
left = right - expected =
left = right - expected =
left <> right - expected <>
left <> right - expected <>
left <> right - expected <>
left = right - expected <>
left <> right - expected <>
left = right - expected <>
正如您所看到的,当一方为空而另一方不是时,字符串不等式会失败 - 我目前正在经历这种情况。我知道我可以做下面的事情,但我想知道我是否错过了一个更简单的方法:
If (left = right) Then
Else
' Do inequality stuff here...
End If
[编辑]我收到了很好的反馈为什么这种情况正在发生。谢谢大家!但是,我也对如何避免这种情况感兴趣。
[编辑2]我希望的是一种简单的方法来了解字符串何时不同(感谢Ekkehard.Horner的建议)。
因此,就我的目的而言,“预期”以及我的演示代码中实际发生的事情是足够的。
答案 0 :(得分:1)
我认为你错过了VBScript中Comparison Operators的基础。
与Null
相比,始终返回Null
,而不是布尔值(True / False)。
<强>更新强>
字符串比较区分大小写,但在某些情况下,您的脚本会将String
与Null
进行比较,而您的第二个问题是如何简化此任务,对吧?在这种情况下,编写函数是个好主意。
Function CompStr(sVal1, sVal2)
CompStr = False
If VarType(sVal1) <> vbString Then Exit Function
If VarType(sVal2) <> vbString Then Exit Function
CompStr = sVal1 = sVal2
End Function
答案 1 :(得分:1)
说明Panayot的陈述(+1)并使其易于实验:
' vbEmpty 0 Uninitialized (default)
' vbNull 1 Contains no valid data
' vbInteger 2 Integer subtype
' vbLong 3 Long subtype
' vbSingle 4 Single subtype
' vbDouble 5 Double subtype
' vbCurrency 6 Currency subtype
' vbDate 7 Date subtype
' vbString 8 String subtype
' vbObject 9 Object
' vbError 10 Error subtype
' vbBoolean 11 Boolean subtype
' vbVariant 12 Variant (used only for arrays of variants)
' vbDataObject 13 Data access object
' vbDecimal 14 Decimal subtype
' vbByte 17 Byte subtype
' vbArray 8192 Array
Dim aData : aData = Array(Empty, Null, CInt(0), CLng(0), "", "a", Nothing)
Dim sXfx : sXfx = Space(25)
Dim k : k = 0
Dim i, j
For i = 0 To UBound(aData)
For j = 0 To UBound(aData)
WScript.Echo _
Right(1000 + k, 3) _
, Right(sXfx & toTypeStr(aData(i)), 25) _
, Left(toTypeStr(aData(j))& sXfx, 25) _
, compareX(aData(i), aData(j))
k = k + 1
Next
Next
Function toTypeStr(vX)
Dim aTmp : aTmp = Array(VarType(vX), TypeName(vX), "")
Select Case aTmp(0)
Case vbEmpty : aTmp(2) = "<Empty>"
Case vbNull : aTmp(2) = "<Null>"
Case vbString : aTmp(2) = """" & vX & """"
Case vbObject : aTmp(2) = "<Object>"
Case Else : aTmp(2) = CStr(vX)
End Select
toTypeStr = Join(aTmp, ":")
End Function
Function compareX(vLHS, vRHS)
Dim vEQ
On Error Resume Next
vEQ = vLHS = vRHS
If Err.Number Then compareX = Err.Description : Exit Function : End If
On Error GoTo 0
Select Case True
Case VarType(vEQ) = vbNull
compareX = toTypeStr(vEQ) & " - can't compare with Null"
Case VarType(vEQ) <> vbBoolean
compareX = toTypeStr(vEQ) & " surprise"
Case vEQ
compareX = "equal"
Case Else
compareX = "not equal"
End Select
End Function
输出:
000 0:Empty:<Empty> 0:Empty:<Empty> equal
001 0:Empty:<Empty> 1:Null:<Null> 1:Null:<Null> - can't compare with Null
002 0:Empty:<Empty> 2:Integer:0 equal
003 0:Empty:<Empty> 3:Long:0 equal
004 0:Empty:<Empty> 8:String:"" equal
005 0:Empty:<Empty> 8:String:"a" not equal
006 0:Empty:<Empty> 9:Nothing:<Object> Object variable not set
007 1:Null:<Null> 0:Empty:<Empty> 1:Null:<Null> - can't compare with Null
008 1:Null:<Null> 1:Null:<Null> 1:Null:<Null> - can't compare with Null
009 1:Null:<Null> 2:Integer:0 1:Null:<Null> - can't compare with Null
010 1:Null:<Null> 3:Long:0 1:Null:<Null> - can't compare with Null
011 1:Null:<Null> 8:String:"" 1:Null:<Null> - can't compare with Null
012 1:Null:<Null> 8:String:"a" 1:Null:<Null> - can't compare with Null
013 1:Null:<Null> 9:Nothing:<Object> Object variable not set
014 2:Integer:0 0:Empty:<Empty> equal
015 2:Integer:0 1:Null:<Null> 1:Null:<Null> - can't compare with Null
016 2:Integer:0 2:Integer:0 equal
017 2:Integer:0 3:Long:0 equal
018 2:Integer:0 8:String:"" not equal
019 2:Integer:0 8:String:"a" not equal
020 2:Integer:0 9:Nothing:<Object> Object variable not set
021 3:Long:0 0:Empty:<Empty> equal
022 3:Long:0 1:Null:<Null> 1:Null:<Null> - can't compare with Null
023 3:Long:0 2:Integer:0 equal
024 3:Long:0 3:Long:0 equal
025 3:Long:0 8:String:"" not equal
026 3:Long:0 8:String:"a" not equal
027 3:Long:0 9:Nothing:<Object> Object variable not set
028 8:String:"" 0:Empty:<Empty> equal
029 8:String:"" 1:Null:<Null> 1:Null:<Null> - can't compare with Null
030 8:String:"" 2:Integer:0 not equal
031 8:String:"" 3:Long:0 not equal
032 8:String:"" 8:String:"" equal
033 8:String:"" 8:String:"a" not equal
034 8:String:"" 9:Nothing:<Object> Object variable not set
035 8:String:"a" 0:Empty:<Empty> not equal
036 8:String:"a" 1:Null:<Null> 1:Null:<Null> - can't compare with Null
037 8:String:"a" 2:Integer:0 not equal
038 8:String:"a" 3:Long:0 not equal
039 8:String:"a" 8:String:"" not equal
040 8:String:"a" 8:String:"a" equal
041 8:String:"a" 9:Nothing:<Object> Object variable not set
042 9:Nothing:<Object> 0:Empty:<Empty> Object variable not set
043 9:Nothing:<Object> 1:Null:<Null> Object variable not set
044 9:Nothing:<Object> 2:Integer:0 Object variable not set
045 9:Nothing:<Object> 3:Long:0 Object variable not set
046 9:Nothing:<Object> 8:String:"" Object variable not set
047 9:Nothing:<Object> 8:String:"a" Object variable not set
048 9:Nothing:<Object> 9:Nothing:<Object> Object variable not set
从#001和#007-#013可以看出,应用于Null值的操作(此处为:=)的结果始终为Null。
<强>更新强>
对于特殊情况(仅Null或Strings,两个Null都被认为是相等的):
Dim aData : aData = Array(Null, "", "a")
Dim sXfx : sXfx = Space(25)
Dim k : k = 0
Dim i, j
For i = 0 To UBound(aData)
For j = 0 To UBound(aData)
WScript.Echo _
Right(1000 + k, 3) _
, Right(sXfx & toTypeStr(aData(i)), 25) _
, Left(toTypeStr(aData(j))& sXfx, 25) _
, CStr(compareStrNull(aData(i), aData(j)))
k = k + 1
Next
Next
Function compareStrNull(vLHS, vRHS)
Dim ntLHS : ntLHS = VarType(vLHS)
Dim ntRHS : ntRHS = VarType(vRHS)
Select Case True
' If both are null, then one could argue that they aren't the same, but they're same enough for me.
Case ntLHS = ntRHS And ntLHS = vbNull
compareStrNull = True
' If one is null and the other is not, then they're different - pretty obviously.
Case ntLHS = vbNull Or ntRHS = vbNull
compareStrNull = False
' If both are not null, then they are the same if they're the exactly the same - including case sensitivity.
Case ntLHS = ntRHS And ntLHS = vbString
compareStrNull = vLHS = vRHS
Case Else
Err.Raise 4711, "compareStrNull", "surprise"
End Select
End Function
输出:
000 1:Null:<Null> 1:Null:<Null> True
001 1:Null:<Null> 8:String:"" False
002 1:Null:<Null> 8:String:"a" False
003 8:String:"" 1:Null:<Null> False
004 8:String:"" 8:String:"" True
005 8:String:"" 8:String:"a" False
006 8:String:"a" 1:Null:<Null> False
007 8:String:"a" 8:String:"" False
008 8:String:"a" 8:String:"a" True
更新II:
比较功能的简化/优化版本:
Function compareStrNull02(vLHS, vRHS)
compareStrNull02 = vLHS = vRHS ' native compare
If VarType(compareStrNull02) = vbNull Then ' at least one param is Null
compareStrNull02 = VarType(vLHS) = VarType(vRHS) ' are both Null?
End If
End Function
处理数组或对象需要进一步的工作。
答案 2 :(得分:-1)
尝试将其添加为第一行:
如果是isnull(左)或isnull(右)然后退出sub