cells()

时间:2016-06-16 18:00:58

标签: vba excel-vba excel

我的印象是VBA具有所有对象的默认属性。因此,如果我说Cells(counter, x),附加的默认属性将为.value。另外,我一直使用Cells(counter, x)Cells(counter, x).value互换。但是,当通过for循环向集合添加项目时,我注意到如果我没有包含.value而不是存储该值,它会将值存储为工作表中的位置。这样,如果删除了该位置,则该集合中的引用将丢失。这让我有两个发现:1)集合可以存储非静态引用,2)Cells()和其他对象没有默认属性,如.value

如果有人能澄清,确认和启发,那就太棒了。

1 个答案:

答案 0 :(得分:7)

不,并非所有类型都有默认会员。

任何类模块都可以有一个默认成员,通过指定一个特殊的成员属性(您必须手动导出和编辑代码文件才能执行此操作,VBE不会' t暴露任何功能):

Attribute {member name}.VB_UserMemId = 0

只允许一个成员成为类型的默认成员。

您发现了默认会员的肮脏以及为什么要避免这些行为。

VBA做了很多事情,让我们的生活变得更轻松#34; (例如隐式类型转换),默认成员就是其中之一。

  

集合可以存储非静态引用

我不知道&#34;静态参考&#34;是,但是当您在Collection中存储对象引用时,您不会存储该对象的副本,而是存储引用。< / p>

  

Cells()和其他对象没有默认属性,例如.value

Global.Cells是一个参数化属性getter,它返回一个Range对象引用; Range.Cells也是一个返回Range对象的getter; Excel对象模型中没有Cell类。 Range的默认成员是隐藏的[_Default]成员,似乎已解析为Value。但是当你这样做时:

Dim c As Collection
Set c = New Collection
c.Add ActiveSheet.Cells(1, 1)

然后,您要添加Range返回的.Cells(1, 1)引用,然后执行此操作:

Debug.Print c.Item(1)

将输出Range对象的值。但是这个:

Debug.Print TypeName(c.Item(1))

将输出Range

混淆?是。这就是为什么你应该总是指定Option Explicit,尽可能使用显式类型声明的变量,避免隐式类型转换,...​​并避免使用默认成员。

通过编写完全按照其应有的方式读取的代码,可以避免大量的VBA陷阱,当您最终想要学习一些VB.NET或C#时,您根本不会丢失类型安全性和显式性