对于VBA编程来讲,是用不到面向对象编程的,但是要了解一些相关的概念,方便后续深入学习。这篇仅用做了解VBA的面相对象,了解即可,对于不理解的地方不用深究。
一、面向对象的概念
实不相瞒,我也没有写过设计模式比较优秀的程序。学VBA和C#的第一个项目都是面向过程的,最多也就用到自定义函数。
关于面向对象,我个人的理解就是把面向过程上升一个维度。把程序处理的过程提炼出来,就成了方法,方法和属性,就构成了对象。面向过程就是把一个问题拆解成步骤,然后一步一步去实现;面向对象是把一个问题拆解成几个小问题,然后再去对小问题一步一步实现。这两个并不是水火不容,而是共存共荣的。
除了方法和属性,对象还包括一些事件,比如要在双击工作表后运行的代码,就应该放到工作表的双击事件中。一般不太用的到,事件里用的最多的应该是放在ThisWorkbook工作簿中的代码,会在加载时运行。
举个现实中的例子,比如小明要出去吃饭。
面向过程就是:1、找个餐馆;2、进去坐下;3、点菜;4、吃饭;5、结账走人。
面向对象是:把这个问题拆成:“小明”、“服务员”和“餐馆”三个对象,“小明”具有“走路”、“点菜”、“吃饭”、“结账”的方法,“小明”的属性,包括身高体重等。这个拆分可以是比较灵活的,比如“餐馆”可以再拆分成“房屋”、“老板”、“厨师”、“服务员”等。“小明”和“服务员”都是人,那么可以创建“人”这个对象,然后“小明”和“服务员”作为“人”的子类,在使用“走路”、“两条胳膊两条腿儿”这些“人”共有的属性和方法的时候就可以直接调用了。
面向过程和面向对象用到什么程度,取决于具体问题的情况,VBA中我最多用到把常用的过程封装成函数。
VBA编程一般就是 对Excel中的对象的属性和方法的 调用过程。Excel软件本身就是一个对象,在VBA中对应的就是“Application”,当然这个Application指的是应用本身,在Excel的VBE中指Excel,在Word中就指Word。这里也说明一下,可能有人不知道Word也是支持VBA的,其实Word、PPT、Access和outlook都支持VBA的。Word的VBA相比Excel比较残废一些,但是也是可以提高工作效率的,有兴趣的话可以自己去找找相关资料学习学习。
二、Excel中的常用对象、方法和属性
Excel中的常用对象有四个,Application、Workbook、Worksheet和range,有了这四个对象基本就可以为所欲为了。
1. Application
https://docs.microsoft.com/zh-cn/office/vba/api/excel.application(object)
Application指的是当前的Excel程序。
在VBE中写代码默认就是在Application对象下的,一般情况下可以省略。这里有个坑,在个别情况下,如果你手速足够快,几乎同时打开两个Excel文件时,会打开两个Application对象。在鼎信诺里面打开底稿,也是单独打开了一个Application对象,跟平时打开的不是同一个对象。
常用的几个属性如下:
① ScreenUpdating
屏幕刷新状态。一般放在代码的开始和结尾,开始运行时关闭屏幕刷新,结束前在打开。对于一些频繁读写Excel的代码,能提高运行速度。(不建议频繁对Excel读写,建议尽量用数组)
’关闭屏幕刷新
ScreenUpdating = False
’打开屏幕刷新
ScreenUpdating = True
② DisplayAlterts
警告弹窗。对于一些操作,默认可能会弹出警告窗体,如果你确认操作是安全的,可以在操作前先关闭警告。默认进程结束时会打开弹窗,但是我不建议这么做,最好还是在程序结束前手动打开。
’关闭警告弹窗
DisplayAlterts = False
’打开警告弹窗
DisplayAlterts = True
③ ActiveWorkbook
活动工作簿属性,返回一个工作簿对象。使用Application.ActiveWorkbook
即可获取到当前活动工作簿。
④ ActiveSheet
活动工作表属性,返回一个工作表对象。使用Application.ActiveSheet
即可获取到当前活动工作簿中的活动工作表。一般情况下操作当前活动工作表可以直接在使用ActiveSheet。如下代码可以把当前活动工作表重命名.
Sub Test()
ActiveSheet.Name = "工作表1"
End Sub
2. Workbook
https://docs.microsoft.com/zh-cn/office/vba/api/excel.workbook
Workbook指的是工作簿对象。Workbooks对象是Workbook的集合,包含当前Application中的所有Workbook对象。
常用的方法和属性如下:
① Workbooks.Add
新建工作簿。这个方法可以指定一个路径参数,表示使用指定的模版新建工作簿。
Workbooks.Add "D:test模版.xltx"
② Workbooks.Open
打开工作簿。平时可能会用到的比较多,Open方法的参数也比较多,最常用的就是路径(FileName)。FileName就是指文件名称了,这个名称包括位置+文件名+后缀,例如:"D:test文件名.xlsx"。
Workbooks.Open "D:test文件名.xlsx"
配合ScreenUpdating,先关闭屏幕刷新,再打开文件,可以做到类似在后台打开文件的效果。
③ Activate
激活工作簿。默认情况下,打开的工作簿中,最前面的那个就是激活的工作簿,使用VBA可以激活指定工作簿。注:使用“Workbooks("文件名")”这种形式,就是指工作簿集合中的指定工作簿,所以这段代码指一个Workbook对象:Workbooks("文件名.xlsx").Activate
④ Close
关闭工作簿。可以使用SaveChanges参数指定是否保存文件。因为SaveChanges是第一个参数,所以也可以省略“SaveChanges:=
”这部分。
Workbooks("文件名.xlsx").Close SaveChanges:=False
Workbooks("文件名.xlsx").Close False
⑤ Save
保存工作簿。
'这是一段保存所有工作簿的代码
For Each w In Application.Workbooks
w.Save
Next w
⑥ SaveAs
另存工作簿。同Workbooks.Open,可选参数比较多,但是常用的也就是第一个参数文件路径(FileName),但是SaveAs的FileName参数跟Open的是有区别的,这个可以只写文件名,即“文件名.xlsx
”即可,这种情况下默认保存在与原文件同一文件夹。
'保存到指定目录
ActiveWorkbook.SaveAs "D:test新文件名.xlsx"
'保存到原工作簿所在目录
ActiveWorkbook.SaveAs "新文件名.xlsx"
⑦ ActiveSheet
活动工作表属性,返回工作表对象。这个跟Application的同名属性的区别是:每个工作簿都有一个活动工作表,就是打开的时候激活的显示的那张表,不加Workbook限定的话默认返回活动工作簿的活动工作表。
⑧ Worksheets
返回工作表集合,可以简写为Sheets。一般用来制定工作表。比如Sheets("工作表1")
就返回"工作表1"这个Worksheet对象。
⑨ Name
名称属性,返回工作簿的名称,包括后缀。类似的有个FullName属性,顾名思义就是完整的文件名,包含路径。当然也有专门返回文件所在的路径的属性:Path。
ActiveWorkbook.Name
'返回"文件名.xlsx"
ActiveWorkbook.FullName
'返回"D:test文件名.xlsx"
ActiveWorkbook.Path
'返回"D:test"
3. Worksheet
https://docs.microsoft.com/zh-cn/office/vba/api/excel.worksheet
Worksheet是指工作表对象。在此强调一下,工作簿和工作表要区分清楚。很多人平时工作中可能习惯把“Workbook工作簿”称为“Excel表”或者“表”,实际上“Worksheet工作表”是指工作簿中的一页。
常用的方法和属性如下:
① Activate
激活工作表。工作簿中显示的就是激活的工作表,使用Activate方法可以激活指定工作表。
ActiveWorkbook.Sheets("工作表1").Activate
前面的ActiveWorkbook可以省略,即可以写成Sheets("工作表1").Activate
。
② Delete
删除工作表。
Sheets("工作表1").Delete
③ Name
工作表名。使用Worksheet.Name
可以获取或设置工作表名。
'将活动工作表重命名为“工作表1”
ActiveSheet.Name = "工作表1"
'将活动工作表名写入单元格A1
ActiveSheet.Range("A1").Value = ActiveSheet.Name
④ Range
单元格属性,返回一个Range对象。也可以用Cell,Cell适用于指定行列数时对单一单元格的操作。Range的适用范围更广,所以我一般都用Range。参数为单元格区域,可以输入多个单元格区域,中间拿英文逗号隔开即可。例如Range("A1:B2")
或者Range("A1:B2,A5:B6")
'将指定区域填充为1
Range("A1:B2,A5:B6") = 1
⑤ Visible
可见属性,布尔值。表示当前工作表是否可见。使用Worksheet.Visible
可以获取或设置工作表的可见性。
'将“工作表1”隐藏
Sheets("工作表1").Visible = False.Visible = False
'将“工作表1”的可见性写入ActiveSheet单元格A1
ActiveSheet.Range("A1").Value = Sheets("工作表1").Visible
4. Range
https://docs.microsoft.com/zh-cn/office/vba/api/excel.range(object)
Range是VBA中最常用的一个对象,因为在一般情况下,我们都是对活动工作表中的单元格进行操作,这种情况在代码中是可以省略ActiveWorkbook和ActiveSheet这两个对象的。直接使用Range("A1")这种格式即可。在多工作表/工作簿切换时请避免这种写法,用指定工作簿、工作表的方式对代码的可读性有很大帮助。
Row(行)和Column(列)可以理解为特殊的Range对象,一般用到的情况为自动调整列宽:Worksheets("工作表1").Columns("A:I").AutoFit
也可以写成Worksheets("工作表1").Range("A:I").Columns.AutoFit
Range的常用对象和方法如下:
① Clear
清空。用于清空单元格的内容和格式。
'清空单元格区域A1:B3的内容和格式
Worksheets("工作表1").Range("A1:B3").Clear
② Copy
复制。复制单元格区域,可以直接复制到指定区域,也可以复制到剪切板。
'复制“工作表1”的“A1:D4”单元格到“工作表2”的“E5:H8”
Worksheets("工作表1").Range("A1:D4").Copy destination:=Worksheets("工作表2").Range("E5")
'这里粘贴的时候不需要再指定到“E5:H8”,等同于手工操作复制粘贴的逻辑,如果指定也没问题。
'复制到剪切板
Worksheets("工作表1").Range("A1:D4").Copy
'激活单元格“F1”
Worksheets("工作表1").Range("F1").Activate
'粘贴到“F1:K4”。由于Range没有Paste方法,粘贴时使用Worksheet的Paste方法
Worksheets("工作表1").Paste
③ Merge/UnMerge
合并单元格/取消合并单元格。合并单元格对于后期处理是很大的坑,建议尽量避免使用合并单元格。
'合并“A1:A3”单元格
Range("A1:A3").Merge
'取消合并单元格
Range("A1").MergeArea.UnMerge
④ Borders
边框属性。可以用来设置边框样式。
'将"工作表1"中"B2"单元格的底边设置为红色细边框
Sub SetRangeBorder()
With Worksheets("工作表1").Range("B2").Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = 3
End With
End Sub
⑤ Formula
公式属性。用于获取或设置单元格的公式。如果单元格包含公式内容,Value属性获取到的是显示的值,此时可以用Formula获取公式,如果单元格不是公式内容,使用Formula获取到的也是显示的值,所以在需要保留公式时用Formula即可。
'设置单元格A1的公式
Worksheets("工作簿1").Range("A1").Formula = "=$A$4+$A$10"
⑥ MergeArea
合并单元格区域。返回包含指定区域的合并单元格区域Range对象。
'也可以用来检查单元格是否为合并单元格
Set ma = Range("A3").MergeArea
If ma.Address = "$A$3" Then
MsgBox "没有合并"
Else
ma.Cells(1, 1).Value = "42"
End If
⑦ Value/Value2
单元格的值。如果选中的是区域(例如“A1:B3”),返回一个从(1,1)开始二维数组;如果是单个单元格(例如“A1”),返回的数据格式根据单元格格式而定。
Value2和Value的区别是Value2属性不使用Currency和Date数据类型。Currency是专门用来表示货币的数字类型,一般我们不太会用到,double就足够了。相比之下Date类型用到的更多,Value属性返回的是时间戳,Value2返回的是单元格显示的字符串。一般我会用Value2。
三、结语
以上就是VBA中常用的对象属性和方法。我翻了一遍微软官方的文档,挑出我认为常用的列示。再次强调一下,这个仅作为字典使用,不用去记,知道有就行了,当然官方文档是更好的字典。
下一篇介绍数据类型。