分享

[VBA][基础入门] 第4讲 对象模型

 东西二王 2019-05-17

[VBA][基础入门] 第4讲 对象模型

本文算是一个VBA很有意义的启蒙,本文的内容我以前只给两个有VBA基础的朋友讲过

现在这俩,一个在学python,一个已经开了Office排版公司

本文内容对于小白,有巨大的启蒙作用:

一、理解对象模型

Office有多种文档格式,doc、docm、docx、xls、xlsm、xlsx、ppt、ppa、pptm、vsd、vsdx等等

不管是WPS还是微软,开发这些Office程序之前,肯定要先定义好这些格式的文件结构。

注:微软现在已经公开了所有office文件的结构,这也是为什么现在有不少第三方office文件解析库(例如java的POI, .net的NPOI, 还有商业库aspose系列等等……)的原因。

文件结构里会明确定义,文件头长啥样,文字、图片、表格、OLE对象等等,在文档里以什么形式摆放,等等一套复杂的规则。

定义好之后,就开始写各种代码实现读写这些定义好的文档。

期间会定义很多常量、很多全局变量、会写很多类、定义不少接口,写出很多输入输出的函数……

这个时候,有必要说一下office对象模型,其实是COM(Component Object Model),这个货是微软一个了不起的创造。至于为什么这么说,以后在VBA高阶应用里介绍。

现在你只需要理解,这个对象模型,其实就是微软把他们的工程师开发的一些对象、方法、属性、事件,以一个可视化的文档结构形式展示给用户了,方便用户直接通过对象模型调用底层的一些接口,来实现目标文件的读写操作。

微软爸爸把VB6改造了一下,结合了一下COM,移植到了Office里,改名叫Visual Basic for Application(VBA),然后VBAer就很轻松的,在VBA里通过F2查看对象模型,通过IDE提供的成员提醒(上一讲讲过的Ctrl J记得吧)访问对象模型。很轻松地完成对Office文件的访问了。其酸爽刺激简直不可言喻。

学习Office VBA童鞋们,你们不知道你们是多么的幸运。这么简单的一门语言,给你一个礼拜学不会,都对不起微软爸爸。

对于对象、方法、属性、事件,这几个外星语言,看我来给NewBee举个栗子解释一哈:

你是厨师

柴米油盐酱醋茶锅碗瓢盆就是对象

煎炸焖煮蒸炖炒就是方法

香辣咸淡就是属性

高压锅里的饭煮熟了,就会“叮”一下通知你,这个叮就可以理解为事件

题外话,事件和消息有什么区别呢? 消息是Windows系统最基础的部分,理解Windows消息需要时间,深入理解Windows消息需要更多时间。这个我们以后在VBA高阶应用里再展开。 在这里消息就像是高压锅的各种传感器不停读出的温度、压强。 事件是对消息的封装,在这里当传感器监测温度超过6000°,压强超过70kPa,时间累计30分钟后,就“叮”一下。 这个温度、压强就相当于消息。“叮”就相当于事件。

总结一下,对象模型,你就简单理解为对象、方法、属性、事件等的显式集合。

这个时候,应该有几张图片:

[VBA][基础入门] 第4讲 对象模型

[VBA][基础入门] 第4讲 对象模型

上图看到木?直接光标放在Address这里,按F1,自动弹出Range.Address属性的官方帮助。你们是真的没有意识到F1是个多么庞大的代码宝库吧。

学VBA,花7天时间入门,然后多花时间看看F1,玩玩窗体、数组、集合、字典、正则,不出1个月就能独立解决自己碰到的所有问题了。

二、前期绑定和后期绑定

前期绑定:就是在使用改对象库之前,像讲它引用到工程里,这样就可以在IDE里方便的看到其对象模型成员(啥成员,上面刚讲的那些)了。

[VBA][基础入门] 第4讲 对象模型

添加引用

工具-引用,就可以看到上图界面。

已经勾选的,是当前已经添加的引用,这些我们叫前期绑定好了

如果还想添加列表里没有的内容(不在列表里,证明其没有注册),就直接从浏览按钮进去选中响应的组件加进来。

这里不得不吐槽一下,这个引用界面其实不怎么好用,不过,谁叫微软是你爸爸呢,你也不敢嫌弃,嫌弃也没用,反正爸爸也不会理你。

前期绑定后,怎么玩呢,下面来一个代码。

以Word里访问Excel为例:

[VBA][基础入门] 第4讲 对象模型

在WordVBA里加上Excel的引用

Sub UserModel()
Dim xlApp As Excel.Application 
Dim xlBook As Excel.Workbook 
Dim xlSht As Excel.Worksheet
Dim xlRng As Excel.Range 
'注意对象赋值用Set
Set xlApp = New Excel.Application '新建一个Excel.Application进程
Set xlBook = xlApp.Workbooks.Open('c:\1.xlsm') '通过进程打开一个已有Excel工作簿
Set xlSht = xlBook.Worksheets('Sheet1') '访问这个工作簿里名称为'Sheet1'的工作表
Set xlRng = xlSht.UsedRange '返回该工作表里使用的区域
Debug.Print xlRng.Address '打印Range对象的地址属性
End Sub

上面四句声明做几条简单解释:

1.前期绑定后,才能这样声明Excel里的对象

2.强烈建议新手在前期绑定时,不要省略前缀,这样才能加快你对对象模型的理解

很多人在写代码时,跟上面的风格完全不同,他们习惯这样写的。

Dim xl As Application

Dim bk as workbook

dim sht as worksheet

dim r as range

下面,请你们自己把我上面的代码,改成下面的这些

然后F5运行,再F8单步试试,看看到底发生了什么。有收获可以在评论里分享。

3.写VBA代码时,严格按照对象模型来声明和使用是有很大的好处的

Dim r, s

set r = range('A1')

s = worksheets(1).name

代码TM这样写,遗患无穷。

所以,经常会见到新人提问,我的代码怎么又报错了,F8试过了,怎么还是不对啊,都疯了。

原因其实就在这里。

上述代码相当于如下代码:

Dim r As Variant, s as Variant '一个效率极低的类型

Set r = Application.ActiveWorkbook.ActiveSheet.Range('A1') '省略的是当前激活的工作表

s = Application.ActiveWorkbook.Worksheets(1).Name

都怪微软爸爸对你们太好,让你们不认祖先,都可以写代码,而且大部分情况下,还都能成功完成任务。

如果你像我前面说的那样写代码,时刻注意返回值适不适合存到变量里。你特么最少能少60%的问题。

很多人在学VBA时,学习的方法就错了,不停地走弯路。

很多人在教VBA时,教育的方法就错了,光教怎么吃鱼,不教怎么钓鱼。

后期绑定:我想你也能猜出来,就是你不用引用就可以直接使用咯。

先来后期绑定的语法:

Dim xlApp As Object, xlBook as Object

Set xlApp = CreateObject('Excel.Application')

Set xlBook = xlApp.Workbooks.Open('c:\1.xlsx')

是不是发现跟上面差别不大?

然而,你图样了,变量声明的时候全部用的是Object,为毛不像有些人那样就偷懒,Dim xlApp, xlBook呢,使用Variant又不是不能存Object。

我TM大宝剑都快按捺不住了。Object本身效率就没有前期绑定高,然后Variant比Object效率还要低,你说你用啥。

肯定还会有人抬杠,这点效率差别,相比代码完成后的效率前后对比,可以忽略不计。

如果你这么说,我只能说:好的,好的,你说的都对,你开心就好。

还有在后期绑定里,可就没有一分半点相关的成员提醒了,你按Ctrl J按到手抽筋也不会有。

当然后期绑定也有一大好处:就是我特么就不用管你引用的类库的版本了。

你的代码是Word里引用了Excel 2010,如果是前期绑定,放到Excel2013里,还得重新引用。

而用后期绑定,极大概率代码不需要修改。除非相关使用到的内容,在2013的对象模型里相比2010有调整。

下面给一张前期绑定和后期绑定的对应整理(不全):

[VBA][基础入门] 第4讲 对象模型

常用的对象的前期绑定和后期绑定都有了。

当然,怎么知道后期绑定的字符呢。这个暂时也不讲了,后面在高阶应用里一起扒,因为文章是发出去了再被我撤回来加的上面图片。

一下子又扒了3k多字,本来还预定了一个实战操作,改下一讲分解吧。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多