Вопрос

Я использую Excel VBA для записи UDF.Я хотел бы перегрузить свой собственный UDF несколькими разными версиями, чтобы разные аргументы вызывали разные функции.

Поскольку VBA, похоже, не поддерживает это, может ли кто-нибудь предложить хороший, не запутанный способ достижения той же цели?Должен ли я использовать необязательные аргументы или есть лучший способ?

Это было полезно?

Решение

Объявляйте свои аргументы следующим образом Optional Variants, затем вы можете проверить, отсутствуют ли они, используя IsMissing() или проверьте их тип с помощью TypeName(), как показано в следующем примере:

Public Function Foo(Optional v As Variant) As Variant

    If IsMissing(v) Then
        Foo = "Missing argument"
    ElseIf TypeName(v) = "String" Then
        Foo = v & " plus one"
    Else
        Foo = v + 1
    End If

End Function

Это может быть вызвано из рабочего листа следующим образом =FOO(), =FOO(число), или =FOO("строка").

Другие советы

Если вы можете различать по количеству параметров, то сработало бы что-то вроде этого:

Public Function Morph(ParamArray Args())

    Select Case UBound(Args)
    Case -1 '' nothing supplied
        Morph = Morph_NoParams()
    Case 0
        Morph = Morph_One_Param(Args(0))
    Case 1
        Morph = Two_Param_Morph(Args(0), Args(1))
    Case Else
        Morph = CVErr(xlErrRef)
    End Select

End Function

Private Function Morph_NoParams()
    Morph_NoParams = "I'm parameterless"
End Function

Private Function Morph_One_Param(arg)
    Morph_One_Param = "I has a parameter, it's " & arg
End Function

Private Function Two_Param_Morph(arg0, arg1)
    Two_Param_Morph = "I is in 2-params and they is " & arg0 & "," & arg1
End Function

Если единственный способ отличить функцию по типам, то вам фактически придется делать то, что делают C ++ и другие языки с переопределенными функциями, то есть вызывать по сигнатуре.Я бы предложил, чтобы вызов выглядел примерно так:

Public Function MorphBySig(ParamArray args())

Dim sig As String
Dim idx As Long
Dim MorphInstance As MorphClass

    For idx = LBound(args) To UBound(args)
        sig = sig & TypeName(args(idx))
    Next

    Set MorphInstance = New MorphClass

    MorphBySig = CallByName(MorphInstance, "Morph_" & sig, VbMethod, args)

End Function

и создание класса с несколькими методами, которые соответствуют сигнатурам, которые вы ожидаете.Однако вам, вероятно, потребуется некоторая обработка ошибок, и имейте в виду, что количество распознаваемых типов ограничено:например, даты имеют тип Double.

VBA - это грязно.Я не уверен, что есть простой способ сделать поддельные перегрузки:

В прошлом я либо использовал множество опций, либо использовал различные функции.Например

Foo_DescriptiveName1()

Foo_DescriptiveName2()

Я бы посоветовал использовать необязательные аргументы, которые имеют разумные значения по умолчанию, если только список аргументов не станет глупым, затем создайте отдельные функции для вызова в ваших случаях.

Возможно, вы также захотите рассмотреть возможность использования вариантного типа данных для вашего списка аргументов, а затем выяснить, что к какому типу относится, используя оператор TypeOf, а затем вызвать соответствующие функции, когда вы выясните, что к чему...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top