2008-09-15 3 views
24

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

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

ответ

46

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

+0

Спасибо, это звучит как хороший способ сделать это. – Patrick 2008-09-16 10:29:47

0

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

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

Foo_DescriptiveName1() 

Foo_DescriptiveName2() 

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

0

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

3

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

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 

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