提问人:Greg 提问时间:11/27/2022 最后编辑:Greg 更新时间:12/5/2022 访问量:448
将 Variant 数组中的元素作为参数传递给 ParamArray
Pass Elements in Variant Array as Arguments to ParamArray
问:
背景
我正在创建一个名为 的 VBA 函数 (UDF),它包装了 CallByName()。
MyUDF()
我希望精确地模仿 CallByName()
的签名和参数行为。此外,MyUDF(
) 必须将其 Args() 参数复制到模块化变量 ArgsCopy
(一个 Variant
数组)中,然后 MyUDF
()
将该变量的元素作为进一步的参数传递给 CallByName()。
不要问为什么——这是一个很长的故事。
参考
CallByName()
在VBA编辑器中显示如下
语法
CallByName (对象, procname, calltype, [args()]_)
CallByName 函数语法具有以下命名参数:
部分 描述 对象 必需:变体(对象)。将在其上执行函数的对象的名称。 procname 必需:Variant (String)。一个字符串表达式,包含对象的属性或方法的名称。 呼叫类型 必需:常量。vbCallType 类型的常量,表示所调用过程的类型。 参数() 可选:变体(数组)。
看起来 “” 实际上是一个 ParamArray
,而不是一个简单的数组,但如果没有进一步的文档,我不能完全确定。args()
Variant
格式
我的暂定设计形式如下:
' Modular variable.
Private ArgsCopy() As Variant
' Wrapper function.
Public Function MyUDF( _
ByRef Object As Object, _
ByRef ProcName As String, _
CallType As VbCallType, _
ParamArray Args() As Variant _
)
' ...
' Copy the argument list to the modular variable.
ArgsCopy = Args
' ...
' Pass the arguments (and modular variable) to 'CallByName()'.
MyUDF = VBA.CallByName( _
Object := Object, _
ProcName := ProcName, _
CallType := CallType, _
Args := ArgsCopy _
)
End Function
显示的签名
与 相反,在 VBA 编辑器中显示如下,并以 :CallByName()
MyUDF()
ParamArray Args() As Variant
只有从 a 更改为数组 (),我们才能使它们显示相同:Args()
ParamArray
Variant
ByRef Args() As Variant
但是,后者将与下面描述的功能行为发生冲突。CallByName()
参数化行为
不幸的是,不能按名称 () 传递,因为显然是 a,因此只接受未命名的参数:ArgsCopy
Args
Args := ArgsCopy
Args
ParamArray
VBA.CallByName( _
Object, ProcName, CallType, _
ArgsCopy(0), ArgsCopy(1), ..., ArgsCopy(n) _
)
注意
请忽略返回 的事实,该 可能(也可能不是)必须设置
的 。我已经在我的实际代码中考虑到了这一点。CallByName()
Variant
Object
问题
我如何构造,尤其是它的参数,使得MyUDF()
Args()
- 它的签名在其参数的 和 ity 上都模仿了 的签名;和
CallByName()
Type
Optional
- 它准确地传递给 ?
CallByName()
Args()
理想情况下,还将MyUDF()
- 在 Mac 和 Windows 上都能正常工作;和
- 像在VBA编辑器中一样显示:
CallByName()
这第 3 和第 4 个标准是一个奖励,但我不需要它们。
建议
Visual Basic (VB) 建议可以如上所述将参数传递给它:参数是与 相同类型的数组中的元素,并且此数组作为单个参数提供。但是,我在 VBA 中既没有找到记录也没有实验等价物。ParamArray
MyUDF()
ParamArray
我确实在 Stack Overflow 上找到了这三个 VBA 问题,但我缺乏在这里应用他们的课程的经验。
更改方法签名
第一个问题有一个解决方案,它更改了 的方法签名,使得它是一个参数:一个数组。CallByName()
Args()
Any
但是,我不熟悉“任何
”类型,第三个问题(未回答)使我怀疑这种预处理器“魔术”是否可以在 Mac 上运行:
#If VBA7 Or Win64 Then Private Declare PtrSafe Function rtcCallByName Lib "VBE7.DLL" ( _ ByVal Object As Object, _ ByVal ProcName As LongPtr, _ ByVal CallType As VbCallType, _ ByRef args() As Any, _ Optional ByVal lcid As Long) As Variant #Else Private Declare Function rtcCallByName Lib "VBE6.DLL" ( _ ByVal Object As Object, _ ByVal ProcName As Long, _ ByVal CallType As VbCallType, _ ByRef args() As Any, _ Optional ByVal lcid As Long) As Variant #End If
Public Function CallWithArgs( _
ByRef Object As Object, _
ByRef ProcName As String, _
CallType As VbCallType, _
ByRef Args() As Variant _
)
CallWithArgs = rtcCallByName(Object, ProcName, CallType, Args)
End Function
答: 暂无答案
评论
ByRef
RunObjMethod
ParamArray
255
MAX_PARAMARRAY_SIZE <- 255
Case
VBA.CallByName()
Application.Run()
rtcCallByName
rtcCallByName