Перегрузка функций и UDF в Excel VBA - PullRequest
28 голосов
/ 15 сентября 2008

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

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

Ответы [ 4 ]

51 голосов
/ 16 сентября 2008

Объявите ваши аргументы как 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 (" строка") .

5 голосов
/ 16 сентября 2008

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

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

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

0 голосов
/ 15 сентября 2008

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

0 голосов
/ 15 сентября 2008

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

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

Foo_DescriptiveName1()

Foo_DescriptiveName2()

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

...