Ради будущих читателей:
Основной проблемой была чувствительность к регистру, решаемая путем обеспечения сравнения на 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