
对象概述
使用VBA,你可以创建工程控制Excel的许多东西,同样也可以控制很多其它的应用程序。VBA的伟大来自于它的控制和管理各种各样的对象的能力。但是,“对象”是什么呢?“对象”就好比是你在VBA面前操控的木偶。工作簿本身就是一个对象,使用 Workbook 来代表它;而工作表对象则使用Worksheet 来代表;单元格区域使用 Range 来代表。
对象的属性
在日常生活中,我们习惯性地用各种特征来描绘物体,比如汽车的品牌、颜色、长度、高度等,这些都被视为物体的属性。同样,Excel中的各种对象也拥有描述自身特性的属性。例如,Workbook对象拥有一个Name属性,它就如同工作簿的“身份证”,标明了它的名称;还有一个Author属性,这个属性就如同工作簿的“作者签名”,记录了它的创作来源。而Range对象则拥有一个RowHeight属性,它既能够设置也能够获取单元格区域的“身高”,这使得我们能够对单元格的外观进行精细化管理。。
对象的方法
方法是指对象能够执行的操作,或者我们可以对对象执行的操作。以汽车为例,行驶和刹车都是汽车可以执行的动作。在Excel中,若要在工作簿中添加一个工作表,就需要对Worksheet对象执行添加操作,使用Add代表。Add方法就是Worksheet对象的一个方法。在Excel编程开发中,我们通过使用VBA代码来操作Excel中各种对象的属性和方法,以实现所需的功能。因此,我们需要理解对象及其属性、方法的基本概念,并熟悉Excel中常用的对象。
对象模型

在Excel的浩瀚海洋中,我们依靠VBA语言来驾驭和操控各种Excel对象,从而实现对Excel的无所不能的指挥权。但要驾驭它们,首先需要寻找到心仪的Excel对象,如同球场上那一颗颗等待我们临幸的足球。这些Excel对象,无论是单元格、工作表还是其他,都有其独特的名称和标识,宛如森林中的每一只独一无二的蝴蝶。只有通过准确地找到并锁定这些对象,我们才能进一步地通过VBA对它们进行操作和控制,从而在Excel的海洋中留下我们的烙印。
下面,我们就来认识Excel的一些常用对象,知道怎么样表示它们,这是进入ExcelVBA编程大门的基础。
接下来的内容我们将依次简单地认识 Excel 的下列常用对象:
- Application 对象
- Workbook 对象
- Window 对象
- Worksheet 对象
- Range 对象
- Comment 对象
- Chart 对象
- 返回常用对象的一些属性:ThisWorkbook 属性、ActiveWorkbook 属性、
ActiveWindow 属性、ActiveSheet 属性、Selection 属性、ActiveCell 属性、
Cells 属性、Rows 属性、Columns 属性、ActiveChart 属性
Application对象(Excel顶层对象)
顾名思义,Application对象即代表应用程序本身。在Excel中,Application对象就代表Excel应用程序。它是Excel对象模型的根,所有的Excel对象都是从它这里开始逐层扩展,开枝散叶。
1、ScreenUpdating属性
是否控制屏幕更新,False表示关闭屏幕更新,True表示打开屏幕更新,设置ScreenUpdating=False关闭屏幕更新,将看不到程序的执行过程,可以加快程序的执行速度,让程序显得更直观,专业。
示例①(为关闭屏幕更新下,会弹出对话框):

执行步骤


示例②(关闭屏幕更新,看不到执行过程,程序最终执行完成才能看到最终结果)

执行步骤



2、DisplayAlterts属性
示例①默认状态下,删除sheet时,是有警告提示框的

执行步骤

示例②是否显示警告对话框,False为不显示,True为显示


执行步骤

发现sheet3被删除,但并未出现提示警告。
EnableEvents属性
启用或禁用事件,False为禁用(不让事件发生),True为启用
什么是事件?能被Excel认识的一个操作动作,例如“打开工作簿”、“关闭工作簿”等
- 示例1:编写一个程序,当选中工作表的单元格时,自动在单元格中写入该单元格的地址


执行步骤

●示例2:选中活动单元格,记录对应单元格地址,并将活动单元格向下移动一个单元格


执行步骤

WorksheetFunction属性
使用WorksheetFunction调用Excel内置函数
- 示例1:统计A1:A50单元格中数值大于1000的单元格有多少个?


执行步骤

工作表界面相关命令

Application的常用属性

Workbook对象
Workbook对象代表工作簿,所有Workbook对象组成Workbooks集合。换句话说,单个的Workbook对象是Workbooks集合中的一个成员。我们可以在Workbooks集合中指定工作簿的名称来表示要处理的工作簿。
1、怎么引用工作簿
引用工作簿,就是指明工作簿的位置及名称,共有两种方式
方式一:利用索引号引用工作簿,Workbook.Item(3),这里的Item可以省略,即Workbook(3)
方式二:利用工作簿名称引用,Workbook("Book1")或Workbook("Book1.xls"),如果本地文件显示拓展名(且文件已经保存),则文件名必须带拓展名,否则会报错。
Workbook名片信息

执行结果:

创建工作簿
- 使用方法:Workbooks.Add
如果不带任何参数,将创建包含一定数目空白工作表的新工作簿(数目由SheetsInNewWorkbook属性决定)
- 也可以给Add方法设置参数(参数表示现有Excel名称的字符串,选用该参数,新建的工作簿将以该文件作为模板)
Workbooks.Add "C:\Program Files\Microsoft Office\Templates\2052\ADDRESS\ADDRESS.XLS"
- 也可以通过参数指定新建工作簿中包含的工作类型
Workbooks.Add xlWBATChart '新建图表工作表
打开工作簿
使用Workbooks的Open方法(参数名要写含路径的名称)

执行结果:

参数名成可以省略不写(Open除了Filename参数外,还有14个参数,让用户决定以何种方式打开指定的文件,可以通过系统的帮助来查看更多的信息)
激活工作簿
同事打开多个工作簿,但是同一时间只能有一个窗口是活动的,调用Workbooks对象的Active方法可以激活一个工作簿。

保存工作簿
保存工作簿调用Workbooks的Save方法

如果想将文件另存为一个新的文件,或者第一次保存一个新建的工作簿,就用SaveAs方法。
参数指定文件保存的路径及文件名如果省略路径,则默认将文件保存在当前文件夹中

使用SaveAs方法将工作簿另存为新文件后,将自动关闭原文件,打开新文件,如果希望继续保留原文件不打开新文件,可以用SaveCopyAs方法

关闭工作簿
关闭工作簿使用Workbooks的Close方法,如果不带参数,则关闭所有打开的工作簿

如果想关闭指定的工作簿,需要指定参数

如果关闭之前被更改过的内容没有保存,关闭工作簿前Excel会询问用户是否保存更改,如果不想显示该对话框,可以给Close方法设置参数

关闭并保存的参数savechanges也可以省略不写:

ThisWorkbook与ActiveWorkbook
同是Application对象的属性,同是返回Workbook对象,但二者并不是等同的。
ThisWorkbook是对程序所在的工作簿的引用
ActiveWorkbook是对活动工作簿的引用
新建的工作簿总会成为活动工作簿


Worksheet对象
Worksheet表示一张普通的工作表,Worksheets表示多个Worksheet对象的集合。
1、引用工作表
可以使用工作表的索引号或者标签名称引用它
Worksheets.Item (1) '引用工作表里的第一张工作表
Worksheets (1) '引用工作表里的第一张工作表
Worksheets ("Sheet1") '引用工作簿里标签名称为"Sheet1"的工作表
因为代码名称只能在【属性窗口】里修改,不会随着工作表标签名称或索引号的变化而变化。因此,当工作表的索引号或标签名称经常变化时,使用代码名称引用工作表会更方便。
使用代码名称引用工作表,只需直接写代码名称
例如:第一张工作表的A1单元格输入100,代码为:Sheet1.Range("A1")=100
查看工作表的代码名称,可以读取它的CodeName属性,如果想知道活动工作表的代码名称,代码为:

结果:

工作表的名称还可以在VBE里看到,如下图所示:

新建工作表
新建工作表使用Worksheets的Add方法
不带任何参数,将在活动工作表新建一张工作表
Worksheets.Add
可以用参数给新建的工作表指定位置
Worksheets.Add before:=Worksheets(1) '在第一张工作表前插入一张新的工作表
Worksheets.Add after:=Worksheets(1) ‘在第一张工作表后插入一张新的工作表
还可以同时插入多张工作表
Worksheets.Add Count:=3 '在活动工作表前插入3张工作表,Count参数的缺省值为1
可以同时使用多个参数,不同参数之间用英文逗号隔开


执行结果:

在最后一张工作表后插入两张工作表,代码如下:

- Add方法有哪些参数?请看VBE的提示

更改工作表标签名称
更改工作表标签名称,设置工作表Name属性
Worksheets(2).Name="工资表" '更改第二张工作表的标签名称为“工资表”
新建工作表时在程序中更改标签名称


执行结果:

- 新建工作表同时指定它的标签名称

- 如果同时添加多张工作表(即Count参数值大于1),并不能使用一句代码同时命名
删除工作表
删除工作表使用Worksheets对象的Delete方法
Worksheets("Sheet1").Delete '删除Sheet1工作表
激活工作表
激活工作表可以使用Activate方法和Select方法
Worksheets(1).Activate '激活第一张工作表
Worksheets(1).Select '激活第一张工作表
复制工作表
复制工作表使用Copy方法

移动工作表
移动工作表与复制工作表类似,使用方法Move

隐藏和显示工作表
使用工作表的Visible属性显示或隐藏工作表
'以下这三行代码作用一样,等同于从【格式】菜单中隐藏工作表
Worksheets("工资条").Visible = False
Worksheets("工资条").Visible = xlSheetHidden
Worksheets("工资条").Visible = 0
用下面方法隐藏的工作表,跟上面3种方法不一样,且通过这种方法隐藏的工作表,无法通过菜单取消隐藏,只能通过VBA在属性窗口设置或者用代码取消隐藏
Worksheets("工资条").Visible = xlSheetVeryHidden
Worksheets("工资条").Visible = 2
无论以何种方式隐藏了工作表,都可以用如下代码中的任意一句显示它
Worksheets("工资条").Visible = True
Worksheets("工资条").Visible = xlSheetVisible
Worksheets("工资条").Visible = 1
Worksheets("工资条").Visible = -1
获取工作表的数目
使用Worksheets.Count
Dim mycount%
mycount=Worksheets.Count
Sheets与Worksheets
不同的命令,返回相同的结果
Sheets(2).Name
Worksheets(2).Name
Sheets.Count
Worksheets.Count
Range对象
Worksheet(或Range)对象的Range属性
- 引用单元格并赋值
Worksheets("sheet1").Range("A1").Value=50


执行结果:

- 通过设置“单元格区域名称”调用Range



运行结果:

- 引用多个不连续的区域,用逗号隔开
Sub rng()
Range("A1:A10,A4:E6,C3:D9").Value = 200
End Sub
- 用空格而不是逗号,则表示选中区域交集部分
Sub rng()
Range("A1:B10 A4:D9").Value = 200
End Sub

Worksheet(或Range)对象的Cells属性
- 指定单元格

执行结果:

- 全部单元格

执行结果:

- 更简短的快捷方式

执行结果:

[]是Application对象的Evaluate方法的简写形式,这种简写形式非常适合饮用一个固定的Range对象,但是因为不能再方括号中使用变量,所以这种引用方式缺少灵活性。
其他获取单元格的方式(除了Range、Cells外)Rows
ActiveSheet.Rows '选中活动工作表的所有行
ActiveSheet.Rows(3).Select '选中活动工作表的第3行
ActiveSheet.Rows("3:3").Select '选中活动工作表的第3行
ActiveSheet.Rows("3:5").Select '选中活动工作表的第3行到第5行
Rows("3:10").Rows("1:1").Select '选中第3行到第10行区域内的第一行
其他获取单元格的方式(除了Range、Cells外)Columns
ActiveSheet.Columns '选中活动工作表的所有列
ActiveSheet.Columns (6) '选中活动工作表中的第6列
ActiveSheet.Columns ("F:G") '选中活动工作表中的F至G列
Columns("B:G").Columns("B:B").Select '选中B:G区域中的第2列
Application的Union方法
Union方法像一支强烈的粘合剂,将不连续的多个单元格区域粘在一起,可以同时对其进行操作。

执行结果:

Range对象的Offset属性
Offset属性用来基于基于单元格的位置移动
Offset(x,y)两个参数,x表示行移动,即x>0表示向下移动,x<0表示向上移动;y表示列移动,即y>0表示向右移动,y<0表示向左移动。
参数移动方向示意图


执行结果:

Range对象的Resize属性
使用Range对象的Resize属性扩大或缩小指定的单元格区域,得到一个新的单元格区域。
Resize共有两个参数,第一个参数确定新区域的行数,第二个参数确定新区域的列数,两个参数的值都是正整数,最小为1.
新区域把该对象最左上角的单元格当成自己左上角第一个单元格

Worksheet对象的UsedRange属性
UsedRange属性返回工作表中已经使用的单元格围成的矩形区域(不管这些区域间是否有空行,空列或空单元格)。


执行结果:

Range对象的CurrentRegion属性
CurrentRegion返回当前区域,即以空行和空行的组合为边界的区域

执行结果:

Range对象的End属性
End属性返回当前区域结尾处的单元格,等同于在源单元格按<End+方向键(上下左右)>得到的单元格。
共有4个参数,说明如下:

什么情况会用到End属性?工作表中记录的行数随时都在变化,应该把新记录写入工作表的第5行还是第10行?可以用End属性解决这个问题


执行结果:
①rngEnd

②rngUsed

③rngCurr

操作单元格,还需要了解
单元格内容-Value
Range("A1:B2").Value = "abc"
Range("A1:B2") = "abc" 'Value是Range的默认属性,在给区域赋值时可以省略。
单元格个数-Count
Range("B4:F10").Count '统计单元格数量
ActiveSheet.UsedRange.Rows.Count '统计活动单元格的行数
ActiveSheet.UsedRange.Columns.Count '统计活动单元格的列数
单元格地址-Address
MsgBox "当前选中的单元格地址为"&Selection.Address
选中单元格-Active与Select
以下两组代码是等效的。
ActiveSheet.Range("A1:B10").Select
ActiveSheet.Range("A1:B10").Activate
选择性清除单元格-Clear
Range("B2:B15").Clear '清除B2:B15单元格所有内容(包括批注、内容、注释、格式等)
Range("B2:B15").ClearComments '清除B2:B15单元格批注
Range("B2:B15").ClearContents '清除B2:B15单元格内容
Range("B2:B15").ClearFormats '清除B2:B15单元格格式
复制&粘贴单元格区域-Copy&Paste
- 录制复制和粘贴的宏内容如下:
Sub Macro1()
Range("A1").Select
Selection.Copy
Range("C1").Select
ActiveSheet.Paste
End Sub
- 但在执行复制或者粘贴操作之前并不需要选中单元格,所以代码可以简化为:
Sub Macro1()
Range("A1").Copy Range("C1") 'A1是源单元格,C1是目标单元格
End Sub
- 带参数的复制-Destination
Sub Macro1()
Range("A1").Copy Destination:=Range("C1") 'A1是源单元格,C1是目标单元格,Destination是目标
End Sub
- 带参数的复制-CurrentRegion
要复制的单元格区域不能确定大小,可以只指定一个单元格作为目标区域的最左上角单元格
Sub Macro1()
Range("A1").CurrentRegion.Copy Range("C1") 'A1是源单元格,C1是目标单元格,Destination是目标
End Sub
- 想粘贴源区域的数值(以下两个式子等价)
Sub rngCopyValue_1()
Range("A1:A10").Copy
Range("F1:F10").PasteSpecial Paste:=xlPasteValues '仅粘贴数值
End Sub
Sub rngCopyValue_2()
Range("A1:A10").Value = Range("F1:F10").Value
End Sub
剪切单元格-Cut
Sub rngCut()
Range("A1:A5").Cut Destination:=Range("G1") '把A1:A5剪切到G1:G5,这里G1表示以G1为左上角第一个单元格的区域
Range("F6:F10").Cut Range("G6") '把F1:F10剪切到G6:K10,参数Destination可以省略
End Sub
删除单元格-Delete
Range("B5").Delete Shift:=xlToLeft '删除B5单元格,删除后右侧单元格左移
Range("B5").Delete Shift:=xlUp '删除B5单元格,删除后下方单元格上移
Range("B5").EntireRow.Delete '删除B5单元格所在的行
Range("B5").EntireColumn.Delete '删除B5单元格所在的列

单元格名称,Names集合
Excel中定义的名称就是给单元格区域(或数值、常量、公式)取的名字,一个自定义的名称及时一个Name对象,Names是工作簿中定义的所有名称的集合
- 新建名称
录制的宏告诉我们,怎样新建一个名称
'Add新建名称的方法,RefersToR1C1表示使用R1C1引用样式
ActiveWorkbook.Names.Add Name = "date", RefersToR1C1:="Sheet1!R5C[-2]"
R5C[-2]说明:R后面的数值表示行号,C后面的数值表示列号,[]中括号表示相对引用,默认是绝对引用,相对应用时R>0表示向下移动,C>0表示向右移动
R[2]C[3]:对活动单元格下方的第二行与右边的第3列相交的单元格的引用
R2C3:对工作表中第二行与第3列相交的单元格的引用
- 另一种单元格引用方式:A1样式引用
'Add新建名称的方法,RefersToR1C1表示使用A1引用样式,$表示相对绝对引用,将把活动单元格当做A1单元格
ActiveWorkbook.Names.Add Name = "date", RefersTo:="Sheet1$B$4"
- 定义名称更简单的方式
Range("A1:C10") = "date"
- 怎样引用名称
ActiveWorkbook.Names("date").Name = "姓名"
ActiveWorkbook.Names("姓名").Name = "张三"
- 也可以使用名称索引引用名称
Sub UseName()
Dim i, mx As Integer
mx = ActiveWorkbook.Names.Count '统计一共有多少个单元格
For i = 1 To mx
activateworkbook.Names(i).Visible = False '隐藏名称
Next
End Sub
单元格批注,Comment对象
一个批注就是一个Comment对象,Comments是工作簿中所有Comment对象的集合
- 给单元格增加批注
Range("B5").AddComment Text:="我用VBA新建的批注"
- 怎么知道单元格是否有批注
Sub wbComment()
Range("B5").AddComment Text:="我用VBA新建的批注"
If Range("B5").Comment Is Nothing Then '判断是否存在Comment对象
MsgBox "B5单元格中没有批注"
Else
MsgBox "B5单元格中已有批注"
End If
End Sub
- 操作批注
Sub operComment()
Range("B5").AddComment Text:="我用VBA新建的批注" '新建批注
Range("B5").Comment.Visible = False '隐藏B5单元格批注
Range("B5").Comment.Delete '删除B5单元格批注
End Sub
给单元格设置
- 设置字体-Font
Sub FontSet()
With Range("A1:L1").Font
.Name = "宋体" '设置字体为宋体
.Size = 12 '设置字号为12号
.Color = RGB(255, 0, 0) '设置字体颜色为红色
.Bold = True '设置字体加粗
.Italic = True '设置字体倾斜显示
.Underline = xlUnderlineStyleDouble '文字添加双下划线
End With
End Sub
- 给单元格增加底纹-Interior
Sub InteriorSet()
Range("A1:L1").Interior.Color = RGB(255, 255, 0) '增加黄色底纹
End Sub
- 给表格设置表框
Sub InteriorSet()
With Range("A1").CurrentRegion.Borders
.LineStyle = xlContinuous '设置单线边框
.Color = RGB(0, 0, 255) '设置边框颜色
.Weight = xlHairline '设置边框线条样式
End With
End Sub
- 其他设置
可以在“单元格格式”对话框中进行其他设置,如果想用代码实现而不知道代码怎么写,可以手动操作,用宏录制器录下它。