从函数返回不同的类型

时间:2019-06-05 20:29:01

标签: excel vba

因此,我编写了一个函数,用于检查提供给它的字符串是否为true,false或其他。如果为True,我希望它返回布尔值true,如果它为false,我想返回布尔值false,如果它是其他值,我希望它继续返回字符串。

Public Function ConvertToBoolean(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

    ConvertToBoolean = TempResults


End Function

但是,它始终默认为字符串。我可以将其变暗为布尔值,但随后常规字符串将返回为TRUE,而不是字符串。

如何强制/使函数类型转换起作用?可能需要在if语句中使用它,但是我不知道该怎么做。

不能在if内调暗(尽管也许我可以重新调暗?要检查)

编辑:进一步的测试表明,在大多数情况下,返回一个布尔值-但是偶尔它会返回一个字符串,而所有相关问题都是我首先要解决的。所以我的问题还是一样:

如何显式声明一个函数(或变量)以返回一种给定的类型?

编辑2:由于人们似乎并不相信代码并非每次都能始终完美或相同:

enter image description here enter image description here enter image description here enter image description here

3 个答案:

答案 0 :(得分:3)

除非我缺少任何东西:

List names = Util.list("jagadeesh","varma","jampana","vikash");
List<Person> people = Person.update(name = ?, last_name = ?", "name IN ('" + Util.join(names, "', '") + "')", "John", "Doe");

enter image description here

答案 1 :(得分:3)

为了将来的读者:

根本问题是区分大小写,可以通过确保比较使用Text而不是Binary来解决

这是证据

enter image description here

请注意,布尔值显示大写字母,居中对齐。原始情况下的字符串值,左对齐,数字右对齐。

这是一个版本,针对基于文本的测试进行了优化,可处理错误,数字和自包含内容(这是 not 在以下测试中使用的版本,因为它包含其他功能)

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

答案 2 :(得分:-2)

非常感谢@MathieuGuindon向我确切解释了变体如何工作,并为我指明了正确的道路。

有了,我的代码现在是:

INSERT zsac_figl01.zsaplikp02
SELECT * FROM zsac_figl01.zsaplikp02_delta   

当然,正如@MathieuGuindon所提到的,如果您想使此代码实际起作用(而不是作为“强制类型”练习),则需要添加StrComp()(首选)或Option比较文字(不太可取,显然是越野车)