gpt4 book ai didi

excel - 如果参数为设置为单元格范围的变体数组,则 CallByName 会出现意外结果

转载 作者:行者123 更新时间:2023-12-02 06:36:22 24 4
gpt4 key购买 nike

我一直在特定应用程序中使用 CallByName 并得到我无法解释的结果。它们可以在以下条件下的简单测试中重现

  • 类对象的属性为 Double 类型
  • 添加的值 (Let) 来自已设置为多单元格区域的变体数组

我希望能对此行为做出解释。以下代码应该重现它(至少在 Excel 2007/Windows 7 中)

工作表单元格A1包含5.8

A2 包含 1.3,A 列中的其余单元格为空白。

类模块(class1)

Private pMyData

Public Property Get MyData()
MyData = pMyData
End Property
Public Property Let MyData(Value)
pMyData = Value
End Property

常规模块

Option Explicit
Sub foo()
Dim class1 As class1

Dim V(1 To 2, 1 To 1) As Variant
V(1, 1) = [a1]
V(2, 1) = [a2]

Set class1 = New class1
CallByName class1, "MyData", VbLet, V(1, 1)

Debug.Print V(1, 1), class1.MyData ' <-- 5.8 5.8

Dim W As Variant
W = Range("A1:A2")

Set class1 = New class1
CallByName class1, "MyData", VbLet, W(1, 1)

Debug.Print W(1, 1), class1.MyData ' <-- 5.8 312080296

CallByName class1, "MyData", VbLet, CDbl(W(1, 1))

Debug.Print W(1, 1), class1.MyData ' <-- 5.8 5.8

End Sub

请注意,第二个 debug.print 行显示 class1.MyData 中存储的值是 312080296,而不是 5.8。

最佳答案

这里也是同样的事情。获取 145842640。如果它有帮助,您不必使用 CallByName。使用下面的行可以帮助我将其正确设置为 5.8。

class1.MyData = W(1, 1)

也可能有助于将 pMyData 声明为 double ,并且也在 Let/Get 语句中。然后,在尝试分配时会出现错误,例如第一个 V(1,1),这将迫使您显式声明转换,在这种情况下这似乎是一件好事(甚至是必要的)。

无法快速找到这样做的原因,或者转换实际上在做什么。希望有人知道,我现在很好奇。

编辑 - CallByName 实际上是将 W(1,1) 的地址传递给 Let 语句。 (换句话说,传递指针的值。)通过 CDbl 进行转换会取消引用指针,获取值,这就是它与显式转换一起使用的原因。 (至少我是这么认为的。)

尝试添加此功能:

Public Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (Var() As Any) As LongPtr

然后对 W(1,1) 执行 debug.pring,对 VarPtr(W(1,1)) 执行 debug.print。我发现 myData 和 W(1,1) 的 VarPtr 值是相同的。我认为这是 CallByName 函数行为的一部分,就传递地址而言,而不是值,但我没有时间进一步研究。希望有帮助。

关于excel - 如果参数为设置为单元格范围的变体数组,则 CallByName 会出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27610176/

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