【整理】VBA学习笔记(2) VBA里的EXCEL对象和对象集合

一 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对象集合,一般是复数形式
  1. workbooks ()
  2. sheets() 
  3. worksheets()
  4. cells() 
  5.  range() -----range默认就是复数形式
  6. rows()
  7. columns()

  • EXCEL的对象都是单数形式 ( 特指形式)
  1. activesheet 
  2. thissheet 
  3. activecell 等等

  • 不同的对象有不同的属性(属性也可以是对象)和方法,有些还比较特别
  • 一些更新特殊的对象范围写法
  1. sheet.usedrange            (表上,使用的区域的全部矩形范围)
  2. range().currentregion    (从range() 出发,找到连续不断的范围内的,矩形区域)
  3. selection

1.4 对象的语法

  • 正确写法1:   对象集合()    
  1. workbooks()
  2. worksheets()
  3. range()
  4. rows()
  5. columns()
  6. cells()
  • 正确写法2:   特定对象.
  1. thisworkbook.worksheets()
  2. activesheet.range()
  3. selection.interior.colorinde
  4. activecell.value
  • 错误写法:  对象.
  1. workbook()
  2. worksheet()
  3. cell()
  4. row()
  5. 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   
 102 
 93 
84
 75 
  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

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值