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.
如果有人能澄清,确认和启发,那将是非常好的.
不,并非所有类型都有默认成员.
任何类模块都可以有一个默认成员,通过指定一个特殊的成员属性(您必须手动导出和编辑代码文件才能执行此操作,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#时,你根本不会丢失类型安全性和显式性.