概述
一 VBA 与对象
1.1 VBA 基础
- application 就是 VBA里的 A
- application 就是 EXCEL程序,VBA寄生的这个宿主工具,估计也可能是WORK,PPT等
- EXCEL程序下,可能开启很多EXCEL工程(多个EXCEL表)
1.2 Application 即 excel , excel 就是 VBA的最大对象集合
- EXCEL
- word
- PPT
1.3 什么是 对象,对象集合?
- VBA的对象就是EXCEL里的各种对象
- 没有从class里 new出来的实例 instance
- 对象:object,比如 thissheet,sheets("a") 或 activesheet
- 对象集合:
- 集合的英文:set ,aggregate (gather,assemble, muster)
- 就是某一层级多个对象组成的一个集合,比如worksheets, workbooks
- 标准写法:Application.workbooks().worksheets().range().value
- EXCEL对象集合,一般是复数形式
- workbooks ()
- sheets()
- worksheets()
- cells()
- range() -----range默认就是复数形式
- rows()
- columns()
- EXCEL的对象都是单数形式 ( 特指形式)
- activesheet
- thissheet
- activecell 等等
- 不同的对象有不同的属性(属性也可以是对象)和方法,有些还比较特别
- 一些更新特殊的对象范围写法
- sheet.usedrange (表上,使用的区域的全部矩形范围)
- range().currentregion (从range() 出发,找到连续不断的范围内的,矩形区域)
- selection
1.4 对象的语法
- 正确写法1: 对象集合()
- workbooks()
- worksheets()
- range()
- rows()
- columns()
- cells()
- 正确写法2: 特定对象.
- thisworkbook.worksheets()
- activesheet.range()
- selection.interior.colorinde
- activecell.value
- 错误写法: 对象.
- workbook()
- worksheet()
- cell()
- row()
- column()
二 EXCEL对象
2.1 excel表里各个可见的东西,都是对象
- application 'excel
- workbook
- worksheet
- range
- cells
2.2 对象之间的从属关系
- 我自己总结了一个图,对象之间的从属关系
- 对象集合一般是复数,对象是单数
- range比较特殊,既是复数也可以是单数,range("a1")也可以----但其实默认是复数形式
- 标准写法:Application.workbooks().worksheets().range().value
2.3 对象和对象集合,划清楚从属的的注意点
- 对象是不会属于对象的
- 对象只会属于对象的集合(数组等)
- 而对象的集合可能属于一个更高级的对象,比如 workbook.worksheets()
- 记住这样一个从属关系:对象---对象集合----父对象
- fso.subfolders
- fso.files
- subfolder.files
- 最近没仔细测,我觉得应该是 folder的下面那个图的层级关系正确。找时间验证下。
2.4 举例:语法错误的例子
- 错误用法: for each worksheet in workbook
- 正确用法: for each worksheet in activeworkbook.worksheets
- 标准写法:Application.workbooks().worksheets().range().value
3 VBA的其他对象
3.1 VBA的所有对象,都属于 object
- dim sh1 as object
- dim sh1 as worksheet
3.2 EXCEL对象只是VBA对象的一部分
- 可能会有一些非EXCEL的对象? 比如 VBA 自带的系统对象,比如fso 比如 dictionary
3.3 非EXCEL的对象举例
- fso 对象
- dim fso as object
- fso=createobject("scrpting.filesystemobject")
- dim s as object
- s= createobject(path)
四 工作簿集合 workbooks 和工作簿 workbook
4.1 工作簿集合 workbooks
- EXCEL程序可能同时打开多个workbook,在VBE里体现为多个工程
- 正确写法: workbooks()
- 错误写法: workbook()
- workbooks("cs11.xlsm") '这里需要填写完整的excel的路径path,包含文件类型后缀!
- workbooks("...path.....cs11.xlsm") '如果是跨文件夹了,需要加路径?
- 为什么要加路径,因为跨文件夹了需要绝对路径引用,而同一个文件夹
- EXCEL文件有多种后缀,xls,xlsm等等,文件名相同可能后缀不同
4.2 工作簿
- 一个工作簿,就是一个EXCEL文件,就是一个workbook
4.3 不同的工作簿含义
- workbooks("cs1.xlsm") XX名字的表
- thisworkbook.name 代码/对象所在的表
- (但是没有 thisworksheet 或者 thissheet,代码放在某个sheet下触发也不行)
- (代码只属于 workbook,不属于worksheet?)
- (部分,放在某些workbook, worksheet的触发型的代码呢?)
- activeWorkbook.name 当前激活正在使用的表
五 工作表对象集合 worksheets() 和 工作簿worksheet()
- 集合正确写法 sheets() worksheets()
- 而指代worksheet 一般不能这么写 worksheet() ,而都是 worksheets("")
- 或者是指代特定的工作簿 activeworksheet
六 工作表 sheet 和 worksheet
6.1 sheet 和 worksheet的区别
- Sheet(包含这一页的多种对象,工作表,和这页的表格,窗体等等)
- 包含 worksheet(专指工作表本身)
- 包含 chart
- 包含 window等其他对象
6.2工作表sheet 和 worksheet的写法
- 引用工作表的三种基础写法
- name,名字的写法: sheets("sheet1").
- codename写法: sheet1.
- index的写法: sheets(1). 注意index次序会变化!
6.3 工作表其他特定写法 thisworkbook 和 activesheet
- 正确写法 Activesheet
- 错误语法 Activeworksheet
- sheets().select '选中的表可能是多个,range等select用法都一样
其他特殊写法
- 正确写法 thisworkbook '只有workbook有thisworkbook写法
- 错误写法 thissheet
- 错误写法 thisworksheet
6.4 sheets() 的多种名字引用方法
- Sheets 和名字的用法
- 1用index作为参数自变量,index是sheet的当前位置,可能随时改变,不准
- Sheets(index) 比如 sheets(1)
- 2 使用表sheet的显示名
- Sheets("sheetname") 如 sheets("a")
- 3 使用sheet的codename,codename也可以修改
- sheet1.codename=sheet101
- codename可以在vbe里查看到
- Sheet1.select 这是OK的
sheet的属性,可以直接显示出来
- sheet1.name 或者 sheets("name").codename
- sheet1.codename
- sheet1.index
Sub a1_test()
MsgBox Sheet1.Name
MsgBox Sheets(1).Name
MsgBox Sheets("c").Name
MsgBox Sheets("c").CodeName
MsgBox Sheets("c").Index
End Sub
七 区域与范围(包含range ,cells)
7.1 本质上 range cells selection region 都是一类东西,表示1~n 个单元格
- 通用性的:都是指sheet表里的单元格
- range()
- cells()
7.2 单元格集合
- cells()
- range()
- 错误写法 cell()
7.3 比较特殊的:
- sheet.usedrange
- range.currentregion
- selection
7.4 (单个)单元格
- 单个单元格,常规只有4种正确写法!!!a1的两种写法,r1c1两种写法
- Range("a1") = [a1]=cells(1,"a") = cells(1,1)
- range("a1") 只支持a1写法
- [a1] 只支持a1写法,而且 这种写法不可带变量做参数,且不需要引号
- 错误写法 ["a1"]
- Cells(1,1) cells只支持r1c1写法
- Cells(1,"a") cells只支持r1c1写法
Sub test1001()
Range("b1") = 1
'Range([b2]) = 1 '运行错误1004,range对象用于global对象时失败
[b3] = 1
Cells(4, 2) = 1
Cells(5, "b") = 1
'Cells("b6") = 1 '运行错误5,无效的过程或调用参数
End Sub
7.5 单元格其他特殊用法
- ActivesCell.value="1"
- Cells(5) 表示e1
- 1个数字代表,index,从按EXCEL的次序,先横向读一行的,然后再读其他行的1维排序
- Cells(,4) 表示D1
- 2个数字代表 pos,按EXCEL的 x-row y-column顺序
- 缺省值默认为row column 默认值为1
Sub test1()
'cells只支持r1c1形式引用
Debug.Print Cells(1, 1)
Debug.Print Cells(1, "a")
'range只支持a1形式引用
'range只能在多单元格情况下嵌套cells,不能只嵌套1个单元格
Debug.Print Range("a1")
Debug.Print Range("a" & 1)
'[]只支持a1形式引用
Debug.Print [a1]
Rem 总结 常规只有4种写法正确
Rem cells(1,1)=cells(1,"a")=range("a1")=[a1]
Debug.Print ActiveCell
Debug.Print Cells(4)
Debug.Print Cells(, 4)
'Debug.Print Cells("a1") '报错
'Debug.Print Range([a1]) '报错
'Debug.Print Range(Cells(1, 1)) '报错
'Debug.Print ["a1"] '这会输出a1 字符串
'Debug.Print [(1,1)] '报错
End Sub
7.6 区分对象和值
严格区分
- range() cells()
- 以及各种公式,函数返回为 range() cells() 都是对象
- 而cells(1,1).value是值
模糊处理和默认值
- 很多情况下,会默认debug.print cells(1,1) 等同于 cells(1,1).value
有些时候必须区分(所以严格的区分 对象 or 值 很重要)
- 比如 if a= cells(1,1).value
- 而 if a= cells(1,1) 如果a只是个变量就是错误的
7.7 范围 range的写法(可以左上右下 ,左下右上,只要划定区域就可以)
Range表示1 单个单元格写法
- Range("a1") = [a1]=cells(1,"a") = cells(1,1)
range本身只能选中1个区域的
- range(,) 自带的符号是,
- range("") 嵌套"" 嵌套内部""里面是EXCEL本身的语法
- range不能靠自己选择多个区域,只能选择1个区域
- range可以通过range("")嵌套选择多个区域,EXCEL本身选多个区域
选择1个区域的例子
- [a1:c3] = Range("a1:c3") =Range("a1","c3")
- 正确写法 range("a1:c3")
- 正确写法 Range("a1","c3") 会按左上右下的角度选择range
- 正确写法 Range(Cells(1, 2), Cells(3, 3)).Select
- 正确写法 [a1:c3] 但是这样写不能支持变量
- 正确写法 Range("a1").resize(3,3)
- 错误写法 Range("a1":"c3") 注意中间是,不是:
- 错误写法 Range(Cells(1, 2)).Select 不能单1个单元格嵌套 range(cells())
- 错误写法 Range(cells("a1"),cells("c3")) cells不支持a1写法
- 错误写法 Range(“a”&1&”c”&3) range不支持r1c1写法
7.6.3 可以嵌套选择多个区域-- 嵌套"" 或者用 union
range 选择多个区域,是嵌套的 "" 内容部分本身是多个区域
- 下面是选择多个区域(range本身只能选中1个区域,能靠""选择多区域。本质选择多区域,还是要靠union)
- [a1:c3,d1;f3]
- Range("a1:c3,d1:f3")
- Union(range("a1:c3"),range("d1:f3"))
- Union([a1:a3], [c1:c3]).Select
错误写法
- Range("a1:c3","d1:f3") 会选择a1:f3之间所有区域
Sub a1_test()
MsgBox Application.Sum(Range("a1:c3"))
MsgBox Application.Sum([a1:c3])
MsgBox Application.Sum(Range("a1", "c3"))
MsgBox Application.Sum(Range("a1").Resize(3, 3))
MsgBox Application.Sum(Range(Cells(1, 1), Cells(3, 3)))
MsgBox Application.Sum([a1:a3,c1:c3])
MsgBox Application.Sum(Range("a1:a3,c1:c3"))
MsgBox Application.Sum(Range("a1:a3", "c1:c3")) '这个写法是有问题的
MsgBox Application.Sum(Union(Range("a1:a3"), Range("c1:c3")))
End Sub
7.7 range().item(index) 其中range=[ ] =cells()
range().item(rowX,columnY) 其中range=[ ] =cells()
- 语法:range().item() 或者 [].item() 或者 cells().items
- 据说可以不写 item,但是我试验直接是 range().() 是不行的
- item(参数个数)
- 1个index值,是第几个元素,比如 [b1:c3].item(2) 不是 b2 而是c1 ,试试就明白了
- 实际测试了,可以按照内部这个index次序,取到超过范围的值。如 range("b;c3").item(10).select选中了c5
- 2个index值,应该就是偏移相对坐标 x,y 实际偏移量为 x-1 ,y-1
- range("b1").item(10,3) 选中了D10 实际偏移量为 9 ,2
7.8 range()() 直接偏移,省略了item 和 点.,但是 [ ] 不能省略item
cells()() 偏移也是一样的
省略item了就不能加点!!!!!!!!!
- 虽然 [] 基本等价于 range("") ,但使用还是有不同
- 而 range().item() 和range()() 都可以 range().()错误
- 注意 []()是错误的
- [].item()可以, 而[]() 是错误的 [].() 是错误的
- 注意是这个区域内左上角的偏移,并且最终目标单元格不一定在区域内
- 只是使用这个范围作为坐标系
Sub test001()
'Range("a1:a3,c1:c3").Select
'Union([a1:a3], [c1:c3]).Select
'Range("b1").Item(10, 3).Select
'Range("b1")(10, 3).Select
'[b1].Item(10, 3).Select
Cells(1, 1).Item(3, 3).Select
' selection
End Sub
7.9 多重偏移
- 注意是这个区域内左上角的偏移,并且最终目标单元格不一定在区域内
- 只是使用这个范围作为坐标系
Range("b1")(3, 3)(2, 2).Select 会选中E4
八 Rows和columns
8.1 Rows
具体写法
- Rows()
- 正确写法 rows的index 写法 Rows(1)
- 正确写法 rows的选中写法 rows("2:2") Rows("1:2")
- entireRow 返回多行对象!,而不是行数等
- Cells(1,1).entireRow.select
- Range("a1").entireRow.delete 可以选中多行
错误写法
- Row()
8.2 columns
- 正确写法
- Columns(1)
- Columns("a:a")
- Cells(1,1).entireColumn.select
- Range(cells(1,1)).entireColumn.delete
- range("c:c")
- range("c:c") .entirecolumn.select
错误写法
- column()
Columns("b").Select
Columns(3).Select
Columns("b:d").Select
'Columns("3:7").Select '错误写法,因为excel里也不能这么写
Cells(1, 1).EntireColumn.Select
Range("b1:c3").EntireColumn.Select
Range("d:d").EntireColumn.Select
九 明确语句返回的是对象还是属性,如果是对象,需要要加到方法/属性层
9.1 举例语法:比如这2个语句返回的都是对象,所以后面如果不带方法/属性,就会报错
- [b1].Item(10, 3).select
- Cells(1,1).entireRow.select
9.2 报错举例
- 报错编译错误,语法错误 [b1].Item(10, 3)
- 属性的使用无效 Range("c3").EntireRow
十 特殊的区域(包含单元格)
VBA提前造好的轮子, 可以节省很多操作
10.1 range.currentRegion --必返回最小矩形区域 (包含这些内容的)
其中range=[ ] =cells()
与起始区域相连的数据区域才算,中间空了断了不算
- currentRegion语法
- 正确与否 (cells range)对象.currentRegion
- 错误写法 sheet1.currentRegion 对象不能是 sheet等
- 错误写法 currentRegion,不能单独使用,必须前面带对象、
- 返回的是一个range对象----一定是一个矩形区域 1
- 数据相连的区域 currentRegion.select ?
- 即使表上还有其他区域,也不会选中---不会选中表中所有使用的区域
- 而是根据9宫格图形选中的有数据区域组成的一个矩形区域,如图中[c4:d5] 而不会只选择[c4] 和[d5]
- 可用代码测试下 :
-
Sub test101() 'Cells(4, 1).CurrentRegion.Select [d5].CurrentRegion.Select End Sub
Sub a1_test()
ActiveCell.CurrentRegion.Select
Cells(2, 1).CurrentRegion.Select
Range("a1").CurrentRegion.Select
Range("a1:c3").CurrentRegion.Select
MsgBox Application.Sum(Cells(1, 1).CurrentRegion())
End Sub
实际测试
有个帖子做了很细致的探索
http://club.excelhome.net/thread-1234213-1-1.html
我自己求证了下
左上角是a11
cells(13,2) cells(14,2) 确实都选中了这个区域,也就是,起点的单元格里是否非空没关系,只把他当起点
cells(14,1) 就不会选中这些区域
形态学原理,从一个单元格为起点,判断,这个单元格所在的 九宫格,有哪几个符合要求,包括判断自己这个格子
判断完毕后,这个格子不再判断
再以上个循环内,符合条件的单元格为起点,继续找相邻的九宫格内,是否有符合条件的单元格
同一级有多个单元格就查找多次。独立查找,
1 | ||||||
10 | 2 | |||||
9 | 3 | |||||
8 | 4 | |||||
7 | 5 | |||||
6 | ||||||
11 | ||||||
图形形态学 算法?
还可以考虑,可以加筛选条件,比如,选择 单元格力cells.value 大于255灰度的,可以实现识别
可以百度 图形形态学
https://jingyan.baidu.com/article/f96699bbf99d9e894f3c1b4c.html
10.2 sheet.usedrange() ---必返回最小矩形区域 (包含这些内容的)
注意usedrange前期必须得有sheet等对象
- usedrange() ----------返回的是这页上所有有值的内容,组成的一个最小矩形区域
- usedregion 语法错误
- sheet对象.usedRange() 对象不能是cell range
- thissheet.usedrange
- Activesheet.usedrange.select
- 一个表默认的usedrange()=a1 !! 也就是说一定不会空白?
- 所有对象上使用过的区域?
- 使用的区域 usedrange() ?
10.3 交叉区域
- set var = Intersect([c:d],activesheet.usedrange).select
- 如果是赋值必须结合 = set 语法一起用,否则报错
Sub a1_test()
Set a = Application.Intersect([a1:a5], [a5:e5])
MsgBox (a)
End Sub
10.4 偏移 cells /range.offset (r,c)
- Cells(1, 0).Offset(5, 5).Offset(1.1).Select 试验了下,不能嵌套
- cells range 会因为offset 整理偏移
- 可以负数
- [c1].offset(0,-1).select 选中b1
- 坐标系 x 应该是row y应该是column
- 正式是向 x 是row的方,向下为正
- 正式是向 Y是column的方,向右为正
10.5 特定单元格
cells range都可以
Cells.specialCells(参数).select
具体有哪些呢?比如
错误值
Range("a:a").SpecialCells(xlCellTypeFormulas, 16).Select
Cells(1, 1).SpecialCells(xlCellTypeFormulas, 16).Select
也没报错,cells(1,1) 指定的范围没问题?
空白格
Cells.specialCells(xlCellTypeBlanks).entires.delete
lastcell 会选中整个sheet的usedrange的最后一个单元格,而不是某个区域的
Range("a:a").SpecialCells(xlCellTypeBlanks).Select
参考文档
https://www.cnblogs.com/huhewei/p/9039140.html
http://club.excelhome.net/thread-872872-1-1.html
最后
以上就是迷你夏天为你收集整理的【整理】VBA学习笔记(2) VBA里的EXCEL对象和对象集合一 VBA 与对象二 EXCEL对象3 VBA的其他对象四 工作簿集合 workbooks 和工作簿 workbook五 工作表对象集合 worksheets() 和 工作簿worksheet()六 工作表 sheet 和 worksheet七 区域与范围(包含range ,cells)八 Rows和columns九 明确语句返回的是对象还是属性,如果是对象,需要要加到方法/属性层十 特殊的区域(包含单元格)参考文的全部内容,希望文章能够帮你解决【整理】VBA学习笔记(2) VBA里的EXCEL对象和对象集合一 VBA 与对象二 EXCEL对象3 VBA的其他对象四 工作簿集合 workbooks 和工作簿 workbook五 工作表对象集合 worksheets() 和 工作簿worksheet()六 工作表 sheet 和 worksheet七 区域与范围(包含range ,cells)八 Rows和columns九 明确语句返回的是对象还是属性,如果是对象,需要要加到方法/属性层十 特殊的区域(包含单元格)参考文所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复