функция vba, которая может возвращать объекты и скаляры - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь написать функцию vba в Excel, которая может передавать как объектные, так и скалярные типы. Я могу заставить функцию работать должным образом, используя Variant в качестве сигнатуры, однако я не могу получить возвращаемое значение из того места, где оно вызывается из-за объектов, нуждающихся в set, и скаляров, не нуждающихся в этом. Я написал следующий тестовый пример ниже. Может кто-нибудь помочь мне заставить его работать, пожалуйста?

Я работаю над собственной версией модуля класса JSON. Чтобы «загрузить» внешние данные, у меня есть читатель, который использует рекурсивную функцию, которая должна сделать это (если вам интересно).

РЕДАКТИРОВАТЬ: я не могу вызвать функцию дважды, как предложено QHarr. Метод QHarr работает с приведенным ниже кодом, однако это не полный код, а всего лишь пример. Две причины: 1) функция читает внешние данные и дважды вызывает ее, теряя текущую читаемую строку, и 2) реальная функция является рекурсивной, поэтому ее вызов, подобный этому, приведет к непредсказуемым результатам.

Sub test_passing_scalars_and_objects()

    Dim i As Long
    Dim var As Variant

    For i = 0 To 3

        Set var = pass_it(i)
        Debug.Print "cleared index:=" & i

    Next i

End Sub

Function pass_it(ByVal val As Long) As Variant

    Dim d As New Scripting.Dictionary
    Dim c As New Collection
    Dim arr() As Variant

    Select Case val
        Case Is = 0 ' dictionary
            d.Add "101", 101
            d.Add "202", 202
            Set pass_it = d

        Case Is = 1 ' collection
            c.Add "101"
            c.Add "202"
            Set pass_it = c

        Case Is = 2 ' array
            ReDim arr(1)
            arr(0) = "101"
            arr(1) = "202"
            pass_it = arr

        Case Is = 3 ' scalar
            pass_it = "101"
    End Select

End Function

1 Ответ

0 голосов
/ 11 января 2019

Вы можете вернуть массив с логическим значением, указывающим, является ли Object (поскольку IsObject не разрешен из-за вызова только один раз).

Option Explicit
Public Sub test_passing_scalars_and_objects()
    Dim i As Long, var As Variant
    For i = 0 To 3
        var = pass_it(i)
        If var(0) Then
            Set var = var(1)
        Else
            var = var(1)
        End If
        Debug.Print "cleared index:=" & i
    Next i
End Sub

Public Function pass_it(ByVal val As Long) As Variant
    Dim d As New Scripting.Dictionary, c As New Collection, arr() As Variant

    Select Case val
        Case Is = 0 ' dictionary
            d.Add "101", 101
            d.Add "202", 202
            pass_it = Array(True, d)

        Case Is = 1 ' collection
            c.Add "101"
            c.Add "202"
             pass_it = Array(True, c)

        Case Is = 2 ' array
            ReDim arr(1)
            arr(0) = "101"
            arr(1) = "202"
            pass_it = Array(False, arr)

        Case Is = 3 ' scalar
            pass_it = Array(False, "101")
    End Select
End Function
...