gpt4 book ai didi

vba - 如何通过 CallByName 传递参数数组 ByRef?

转载 作者:行者123 更新时间:2023-12-03 03:47:43 25 4
gpt4 key购买 nike

我目前正在使用 CallByName 来动态调用方法。我每天从服务器的表中获取几种方法以及参数。因此,我将参数数组发送到 CallByName,而不是参数数组,因为直到运行时我才知道参数的数量。鉴于 CallByName 需要一个参数数组,我使用私有(private)声明函数来绕过 VBA 类型定义。

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

Public Function CallByNameMethod(Object As Object, ProcName As String, ByRef Args () As Variant)
AssignResult CallByNameMethod, rtcCallByName(Object, StrPtr(ProcName), VbMethod, Args)
End Function

Private Sub AssignResult(target, Result)
If VBA.IsObject(Result) Then Set target = Result Else target = Result
End Sub

当我传递一个方法更改其基础属性的对象时,这会起作用。但是,在某些方法中,我传递一个对象和一个更改所传递参数值的方法。例如,我传递一个带有以下参数的数组

 Dim Name as String, Value1 as double, Value2 as double, Value3 as double
Dim Array(3) as Variant

String = "Name"
Value1 = 0
Value2 = 0
Value3 = 0

Array(0) = Name
Array(1) = Value1
Array(2) = Value2
Array(3) = Value3

当我传递该数组时,该方法仅返回具有相同值的数组,但我期望 Array(1)、Array(2)、Array(3) 为 double 类型值。有什么想法吗?

最佳答案

答案的第一个线索在于 rtcCallByName 的函数声明(从 vbe7.dll 的导出表中提取):

function CallByName(Object: IDispatch; ProcName: BSTR; CallType: VbCallType; Args: ^SafeArray; out lcid: I4): Variant; stdcall;

请注意,Args 被声明为指向 SafeArray 的指针,但声明为 out范围。这意味着该函数的 COM 契约基本上是说,如果您传递 ParamArray,它所做的唯一保证是它不会更改指向 ParamArray 本身的指针。 Declare Function 中的 ByRef 仅表明您正在传递指针。

至于ParamArray内部的值,我确实没有太多专门针对 VBA 的 Microsoft 文档,但是 VB.NET version of the documentation给出了第二条线索:

A ParamArray parameter is always declared using ByVal (Visual Basic).

CallByName的上下文中,这是非常有意义的。 rtcCallByName 函数本身不(也不能)知道被调用方法的哪些参数是ByRef 本身声明的>ByVal,因此它必须假设它无法更改它们。

就解决此限制的实现而言,我建议要么重构以消除在 CallByName 调用的代码中传递 ByRef 的返回值,要么包装所需的类中的功能。

关于vba - 如何通过 CallByName 传递参数数组 ByRef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37432304/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com