为了未来的读者:
根本问题是区分大小写,通过确保比较是 Text 而不是 Binary 来解决
这是证据
请注意,布尔值显示为大写,居中对齐。字符串值的原始大小写,左对齐,数字右对齐。
这是一个版本,针对基于文本的测试进行了优化,可处理错误、数字和自包含(这不是以下测试中使用的版本,因为它包含附加功能)
Public Function ConvertToBoolean(Val As Variant) As Variant
If IsError(Val) Then
ConvertToBoolean = Val
ElseIf IsEmpty(Val) Then
ConvertToBoolean = vbNullString
ElseIf StrComp(Trim$(Val), "True", vbTextCompare) = 0 Then
ConvertToBoolean = True
ElseIf StrComp(Trim$(Val), "False", vbTextCompare) = 0 Then
ConvertToBoolean = False
Else
ConvertToBoolean = Val
End If
End Function
测试基于此代码
Option Explicit
Option Compare Text
Public Function ConvertToBoolean1a(InputString As String) As Variant
Dim TempResults As Variant
If InputString = "True" Then
TempResults = True
ElseIf InputString = "False" Then
TempResults = False
Else
TempResults = InputString
End If
ConvertToBoolean1a = TempResults
End Function
Public Function ConvertToBoolean2a(InputString As String) As Variant
Dim IsBoolean As Boolean
Dim ReturnString As String
Dim ReturnBoolean As Boolean
If InputString = "True" Then
IsBoolean = True
ReturnBoolean = True
ElseIf InputString = "False" Then
IsBoolean = True
ReturnBoolean = False
Else
IsBoolean = False
ReturnString = InputString
End If
If IsBoolean Then
ConvertToBoolean2a = ReturnBoolean
Else
ConvertToBoolean2a = ReturnString
End If
End Function
在一个单独的模块中(我稍微修改了 Davids 的版本以进行公平比较。他的原始版本处理前导/尾随空格,但这是一个额外的功能并且需要时间)
Option Explicit
Public Function ConvertToBoolean1b(InputString As String) As Variant
Dim TempResults As Variant
If InputString = "True" Then
TempResults = True
ElseIf InputString = "False" Then
TempResults = False
Else
TempResults = InputString
End If
ConvertToBoolean1b = TempResults
End Function
Public Function ConvertToBoolean2b(InputString As String) As Variant
Dim IsBoolean As Boolean
Dim ReturnString As String
Dim ReturnBoolean As Boolean
If InputString = "True" Then
IsBoolean = True
ReturnBoolean = True
ElseIf InputString = "False" Then
IsBoolean = True
ReturnBoolean = False
Else
IsBoolean = False
ReturnString = InputString
End If
If IsBoolean Then
ConvertToBoolean2b = ReturnBoolean
Else
ConvertToBoolean2b = ReturnString
End If
End Function
Public Function ConvertToBoolean3(Val As String) As Variant
If StrComp(Val, "True", vbTextCompare) = 0 Then
ConvertToBoolean3 = True
ElseIf StrComp(Val, "False", vbTextCompare) = 0 Then
ConvertToBoolean3 = False
Else
ConvertToBoolean3 = Val
End If
End Function
Public Function ConvertToBoolean4(Val As Variant) As Variant
Dim s As String
s = UCase$(Val)
Select Case s
Case "TRUE", "FALSE"
ConvertToBoolean4 = CBool(s)
Case Else
ConvertToBoolean4 = Val
End Select
End Function
我还使用此代码进行了速度测试以比较性能
Sub Test()
Dim n As Long, i As Long, j As Long
Dim T1 As Single, T2 As Single, T3 As Single, T4 As Single
Dim res As Variant
Dim Dat2(1 To 5) As String
Dat2(1) = "true"
Dat2(2) = "false"
Dat2(3) = " true"
Dat2(4) = "zx"
Dat2(5) = ""
Dim cl As Range
Application.Calculation = xlCalculationManual
n = 1000000
T1 = Timer()
For i = 1 To n
For j = 1 To 5
res = ConvertToBoolean1a(Dat2(j))
Next
Next
T2 = Timer()
T3 = Timer()
For i = 1 To n
For j = 1 To 5
res = ConvertToBoolean2a(Dat2(j))
Next
Next
T4 = Timer()
'Verion 1a OP 1
[F22] = (T2 - T1) / n * 1000000#
'Verion 2a OP 2
[H22] = (T4 - T3) / n * 1000000#
n = n / 100
Set cl = [f10:f15]
T1 = Timer()
For i = 1 To n
cl.Calculate
Next
T2 = Timer()
Set cl = [h10:h15]
T3 = Timer()
For i = 1 To n
cl.Calculate
Next
T4 = Timer()
'Verion 1a OP 1 UDF
[F23] = (T2 - T1) / n * 1000000#
'Verion 2a OP 1 UDF
[H23] = (T4 - T3) / n * 1000000#
End Sub
和
Sub Test2()
Dim n As Long, i As Long, j As Long
Dim T1 As Single, T2 As Single, T3 As Single, T4 As Single
Dim res As Variant
Dim Dat2(1 To 5) As String
Dat2(1) = "true"
Dat2(2) = "false"
Dat2(3) = " true"
Dat2(4) = "zx"
Dat2(5) = ""
Dim cl As Range
Application.Calculation = xlCalculationManual
n = 1000000
T1 = Timer()
For i = 1 To n
For j = 1 To 5
res = ConvertToBoolean3(Dat2(j))
Next
Next
T2 = Timer()
T3 = Timer()
For i = 1 To n
For j = 1 To 5
res = ConvertToBoolean4(Dat2(j))
Next
Next
T4 = Timer()
'Verion 3 mine
[J22] = (T2 - T1) / n * 1000000#
'Verion 4 david
[K22] = (T4 - T3) / n * 1000000#
n = n / 100
Set cl = [j10:j15]
T1 = Timer()
For i = 1 To n
cl.Calculate
Next
T2 = Timer()
Set cl = [K10:K15]
T3 = Timer()
For i = 1 To n
cl.Calculate
Next
T4 = Timer()
'Verion 3 mine UDF
[J23] = (T2 - T1) / n * 1000000#
'Verion 4 david UDF
[K23] = (T4 - T3) / n * 1000000#
End Sub