Excel VBA对象模型

2020-07-28 10:51:13 浏览数 (1)

1、对象模型

上一讲说了Range对象,这一次我们从总体方面来说一下Excel VBA的对象模型。

你真正想了解Excel VBA里的对象的话,看官方文档是最好的,没有比官方文档更准确的了。然后就是自己去测试、使用,不会的就录制,多用就会逐渐的理解。

我们前面说过,Excel VBA的对象都是微软已经做好了,让我们来使用的,所以这些对象和我们平时普通操作Excel都是有联系的,每个对象你都可以想象是在手动操作Excel,手动操作说到底就是做好了一个图形界面让我们去操作,而使用VBA是在后台操作。

如果你看了官方文档,你应该已经发现Excel VBA里有好多对象,这些对象其实都是有层级关系的,就像一棵树一样,树顶上最高级的是Application,然后不停的分叉,衍生里众多的对象。

下图是网上下载的一个帮助文档:

地址:

http://club.excelhome.net/forum.php?mod=viewthread&tid=849024&extra=page=1&page=1&

2、Application对象

你打开一个Excel(注意不要有其他的Excel文件打开了),然后进入到代码编辑器,在菜单视图里点击立即窗口,在立即窗口输入:

代码语言:javascript复制
ThisWorkBook.Close False

立即窗口是一个可以打印输出的窗口,方便调试用,也可以直接运行一些简单的代码,比如你想看一下单元格A1的值,直接在立即窗口输入:

代码语言:javascript复制
?Range("A1").Value

记住有输出的要在前面加个问号,不需要输出的和平时写的语句一样。

这样你关闭了那个唯一打开的Excel文件,但是这时候,Excel这个程序并没有退出,你还可以看到1个界面,这个就是我们安装目录里,那个叫做EXCEL.EXE(我们双击打开这个,会自动创建1个新的工作簿)打开后的东西,也就是Excel VBA对象模型里的最高级的Application。

这个时候你再试试?Range("A1").Value看看,出错了吧,为什么呢?

这个时候最好自己先好好想一下,然后看看那个错误的提示框上什么意思,多想想。

对象定义错误:为什么会有这个错误?Range("A1"),因为这个Range对象根本不存在,我们通过ThisWorkBook.Close False这句代码,已经关闭了工作簿,当前根本没有了单元格了,操作根本不存在的东西,当然出错。

我们这么来理解看看,中国古代封建社会,比如周朝的时候,那时候的天下是1个天子、多个诸侯国、每个诸侯国里有多个家:

代码语言:javascript复制
Application 天下        EXCEL程序
Workbook    国          工作簿
Workbooks   国的集合     所有打开的工作簿
Worksheet   家          工作簿里的工作表
Worksheets  家的集合    1个工作簿里所有的工作表
Range       人          单元格
Cells       家的所有的人  1个工作表里所有的单元格

在天下初建的时候,还没有分封国(Workbook),这时候的状态就和我们用ThisWorkBook.Close False关闭了唯一的工作簿一样,只有Application,也就是只有天下,还没有国。在立即窗口输入:

代码语言:javascript复制
?Application.Workbooks.Count

可以看到,这种情况下,输出返回的是0,天下还没有国,Application还没有Workbook。

天子觉得这样管理太累,自然就要分封了,他分封一个国,在VBA里我们可以这样新建1个Workbook,在立即窗口输入:

代码语言:javascript复制
Application.Workbooks.Add

这时候你能看到,出现了一个空白的工作簿Workbook了,再运行?Application.Workbooks.Count,就会输出1了。

我们要看看这个工作簿的名称:

代码语言:javascript复制
?Application.Workbooks(1).Name

因为这个国Workbook是天子分封的第1个,所以在国集合Workbooks里,他的序号就是1。你可以继续Application.Workbooks.Add试试看。

国Workbook在建立的时候,天子规定了他必须至少要分封一个家,所以新建的Workbook里会有Worksheet,而我们所看到Worksheet的那些单元格,就是最基础的家的人了。

对象模型就是这样一层一层的下来的,你要找某个家Worksheet的国Workbook,在立即窗口输入:

代码语言:javascript复制
?Activesheet.Parent.Name

这样我们找到的就是当前活动Worksheet的Workbook,输出了他的名称,其他都类似,基本都可以用Parent找到他上一层的对象。

在存在工作簿的时候,我们在立即窗口里输入的?Range("A1").Value,标准的输入应该是:

代码语言:javascript复制
?Application.Workbooks(1).Worksheets(1).Range("A1").Value

前面那些之所以能够省略,是因为Excel VBA在管理Workbooks和Worksheets的时候,都会有一个ActiveWorkbook, ActiveSheet,他会记录下当前活动的对象,省略的时候它操作的对象就是当前活动的。

3、打开1个工作簿的时候,Excel到底做了些什么

我们电脑上的Excel文件,其本质只是硬盘上的一些数据,也就是010101那种东西。和其他所有文件都一样,和我们安装的office也一样,和前面说的EXCEL.EXE还是一样,只不过是包含的010101的数量不同、排列组合不同。

你双击一个Excel文件,他能够打开,不是你双击有什么魔力,这一切都是windows操作系统在后面帮忙做了很多很多工作。

我以自己非专业的认识讲一下,可能有不对的地方:

  • 你双击一个Excel文件
  • windows操作系统根据后缀找到注册表里对应文件后缀的可执行文件,也就是EXCEL.EXE
  • EXCEL.EXE首先运行起来
  • 然后EXCEL.EXE读取那个文件在硬盘上的数据,并解析数据放到了内存中
  • 解析过程也就是去创建1个树形的对象模型
  • 解析过程会根据文件的情况创建Workbook、Worksheet对象,其实所谓的创建也只是在内存中按一些规则来组织数据,可以让我们方便找到这些数据的内存地址

所以,我们用这种语句:

代码语言:javascript复制
?Application.Workbooks(1).Worksheets(1).Range("A1").Value

它能输出内容,是因为EXCEL.EXE把数据在内存中解析好了,这个语句只是定位到了内容的内存地址,然后读取出来。

我们用那些Add等语句新添加对象,Excel VBA都会开辟新的内存空间来存放。

所以假如你一直添加新的Workbook、Worksheet对象,内存终将耗尽而无法继续添加。

而修改一些单元格值的时候,有的可能是直接在原来的内存地址修改数据即可,有些仍然要新开辟内存空间存放,然后把原来的空间释放掉。

所以很多读取属性的语句是要比赋值语句快很多。

4、小结

Excel VBA对象模型,和自己平时操作联系到一起,你能操作什么,就能找到对应的VBA对象。

然后就是多去用才能熟悉。

0 人点赞