cells()的默认属性

Jos*_*son 3 excel vba excel-vba

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

如果有人能澄清,确认和启发,那将是非常好的.

Mat*_*don 7

不,并非所有类型都有默认成员.

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

Attribute {member name}.VB_UserMemId = 0
Run Code Online (Sandbox Code Playgroud)

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


您正在发现默认成员的肮脏以及为什么应该避免它们.

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

集合可以存储非静态引用

我不知道什么是"静态引用",但是当你在a中存储一个对象引用Collection,你不是存储对象的副本而是存储它的引用.

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

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

Dim c As Collection
Set c = New Collection
c.Add ActiveSheet.Cells(1, 1)
Run Code Online (Sandbox Code Playgroud)

然后你要添加返回的Range引用,.Cells(1, 1)然后这个:

Debug.Print c.Item(1)
Run Code Online (Sandbox Code Playgroud)

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

Debug.Print TypeName(c.Item(1))
Run Code Online (Sandbox Code Playgroud)

会输出Range.

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

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