التحميل الزائد للوظيفة وUDF في Excel VBA
-
09-06-2019 - |
سؤال
أنا أستخدم 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(), =فو(رقم), ، أو =فو("خيط").
نصائح أخرى
إذا كان بإمكانك التمييز من خلال عدد المعلمات، فسيعمل شيء مثل هذا:
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، على سبيل المثال.
VBA فوضوي.لست متأكدًا من وجود طريقة سهلة للقيام بالأحمال الزائدة المزيفة:
في الماضي، استخدمت الكثير من الاختيارات، أو استخدمت وظائف متنوعة.على سبيل المثال
Foo_DescriptiveName1()
Foo_DescriptiveName2()
أود أن أقول استخدم الوسيطات الاختيارية التي لها إعدادات افتراضية معقولة ما لم تصبح قائمة الوسيطات غبية، ثم قم بإنشاء وظائف منفصلة لاستدعاء الحالات الخاصة بك.
قد ترغب أيضًا في التفكير في استخدام نوع بيانات مختلف لقائمة الوسائط الخاصة بك ثم معرفة النوع باستخدام عبارة TypeOf، ثم استدعاء الوظائف المناسبة عندما تكتشف ما هو...