【发布时间】:2014-08-15 15:09:07
【问题描述】:
我正在为传出消息设计一个动态缓冲区。数据结构采用具有字节数组缓冲区作为成员的节点队列的形式。不幸的是,在 VBA 中,数组不能是类的公共成员。
例如,这是一个禁忌,不会编译:
'clsTest
Public Buffer() As Byte
您将收到以下错误:“常量、定长字符串、数组、用户定义类型和 Declare 语句不允许作为对象模块的公共成员”
好吧,那没关系,我只需将其设为具有公共属性访问器的私有成员...
'clsTest
Private m_Buffer() As Byte
Public Property Let Buffer(buf() As Byte)
m_Buffer = buf
End Property
Public Property Get Buffer() As Byte()
Buffer = m_Buffer
End Property
...然后在模块中进行一些测试以确保其正常工作:
'mdlMain
Public Sub Main()
Dim buf() As Byte
ReDim buf(0 To 4)
buf(0) = 1
buf(1) = 2
buf(2) = 3
buf(3) = 4
Dim oBuffer As clsTest
Set oBuffer = New clsTest
'Test #1, the assignment
oBuffer.Buffer = buf 'Success!
'Test #2, get the value of an index in the array
' Debug.Print oBuffer.Buffer(2) 'Fail
Debug.Print oBuffer.Buffer()(2) 'Success! This is from GSerg's comment
'Test #3, change the value of an index in the array and verify that it is actually modified
oBuffer.Buffer()(2) = 27
Debug.Print oBuffer.Buffer()(2) 'Fail, diplays "3" in the immediate window
End Sub
测试 #1 工作正常,但测试 #2 中断,Buffer 突出显示,错误消息为“参数数量错误或属性分配无效”
测试 #2 现在可以工作了! GSerg 指出,为了正确调用Property Get Buffer() 并引用缓冲区中的特定索引,需要两组 括号:oBuffer.Buffer()(2)
测试#3 失败 - 原始值 3 打印到立即窗口。 GSerg 在他的评论中指出,Public Property Get Buffer() 只返回一个副本而不是实际的类成员数组,因此修改会丢失。
如何解决第三个问题,使类成员数组按预期工作?
(我应该澄清一般问题是“VBA 不允许数组成为类的公共成员。我怎样才能解决这个问题,让一个类的数组成员表现得好像它是所有实际用途包括:#1 分配数组,#2 从数组中获取值,#3 在数组中分配值和 #4 在调用 CopyMemory 时直接使用数组(#3 和 #4 几乎等效) ?)"
【问题讨论】:
-
我在构建数据结构以缓冲某些网络代码的传出消息时遇到了这个问题。我最终能够解决它,但由于我还没有在 SO 上找到问题,所以我想我会添加它。如果有人知道答案,请随时添加!如果其他人在我能够发布答案之前得到它,我会接受。
-
如果你真的打算每次都复制数组,那么你忘记了the parentheses,
oBuffer.Buffer()(2)。否则你可能想看看例如here. -
@GSerg 这就是我意识到的解决方案 - 如果我只想访问数组中的各个项目,我可以做一些事情,比如将访问器更改为
Public Property Get Buffer(Index As Long) As Byte,但在我的情况下,我需要使用CopyMemory语句中的缓冲区,所以这不起作用。 -
@GSerg 实际上,我一直在尝试使用
HeapAlloc和HeapFree创建自己的clsByteArray类,以解决 VBA 复制数组以进行分配而不是通过引用来完成的事实.你知道是否有一种方法可以使用 Variants 来传递内存中相同数组的引用? (如果用户单击调试器中的停止按钮,HeapAlloc和HeapFree方法会泄漏:'(所以这不是我的首选解决方案) -
您可以construct an array descriptor 覆盖现有(其他数组的)数据。或者您可以保留访问器模式,只需添加另一个属性,该属性会将指针 (varptr) 返回到数组的第一个成员,然后您可以将其传递给
CopyMemory。
标签: arrays vba class-members