VBA全名: Visual Basic Application
準(zhǔn)備·工作
打開VBA
打開左上角的:文件->選項(xiàng) 彈出如下畫面,,選擇“自定義功能區(qū)”,,勾選上“開發(fā)工具”,點(diǎn)擊確定,。Excel的頭上就會(huì)多出一個(gè)選項(xiàng)卡:開發(fā)工具,。
另一種打開方式:
在excel頭部的任意一個(gè)選項(xiàng)卡里單擊右鍵,在彈出的菜單里選第三項(xiàng)“自定義功能區(qū)域”,。也可以彈出如上畫面,。
啟用宏
因?yàn)楹芏嗖《臼强縑BA的宏傳播,,所以excel默認(rèn)禁止執(zhí)行宏,所以要執(zhí)行VBA先要允許宏啟動(dòng),。在“開發(fā)工具”選項(xiàng)卡里點(diǎn)擊“宏安全性”,,選“宏設(shè)置”,選中“啟用所有宏”,。點(diǎn)擊確定按鈕,,然后重啟excel(關(guān)閉excle文件再重新打開)
VBA編輯器
點(diǎn)擊“開發(fā)工具”中的“Visual Basic”,可以打開VBA編輯器,。
VBA編輯器簡(jiǎn)稱BE,,即Visual Basic Editor
在資源管理器中并沒有“模塊”這樣的目錄結(jié)構(gòu),需要添加進(jìn)去,。在資源管理器中,,右鍵單擊,彈出菜單中選擇“插入”,,然后選擇“模塊”
雙擊資源管理器中的“模塊1”,,就可以在右邊開發(fā)代碼。
開發(fā)第一個(gè)小程序
點(diǎn)擊一個(gè)按鈕,,計(jì)算execl中的公式
添加按鈕
1,、點(diǎn)擊“插入”,彈出表單控件,,選中按鈕控件
2,、選中按鈕控件后,在excel需要添加按鈕的地方,,拖動(dòng)鼠標(biāo)左鍵畫出按鈕,,彈出設(shè)置按鈕調(diào)用宏信息的top畫面。給宏起一個(gè)方法名,,然后點(diǎn)擊“新建”按鈕,,創(chuàng)建代碼。然后進(jìn)入VBA編輯器,??吹饺缦麓a。而且在資源管理器中自動(dòng)給我們創(chuàng)建了一個(gè)“模塊2”對(duì)應(yīng)此代碼,。
宏:在VBA中編寫的一段小程序(Macro)
Cells(行,,列) 單元格行列取值
編輯代碼
編輯完代碼后保存文件,會(huì)彈出提示,,我們必須把文件另存為xlsm格式文件,,否者編寫的代碼無法保存。
回到excel畫面,點(diǎn)擊按鈕就會(huì)計(jì)算出A1+A2的結(jié)果,結(jié)果放在C1單元格中,。
編輯按鈕文字 -> 右鍵單擊按鈕選第四項(xiàng)“編輯文字”(也可以拖動(dòng)按鈕位置)
調(diào)整編輯器字體
首先進(jìn)入excle中的VBA編程界面,,在頂部菜單欄中找到“工具”的按鈕,點(diǎn)擊“工具”,找到“選項(xiàng)”按鈕,,然后進(jìn)入選項(xiàng)的編輯界面,,點(diǎn)擊“編輯器格式”,在右邊可以選擇字體的大小。
先寫宏后關(guān)聯(lián)按鈕
1,、先在模塊2中創(chuàng)建一個(gè)做減法的宏代碼
2,、然后新建一個(gè)按鈕,在彈出的top畫面中,,把按鈕關(guān)聯(lián)到這個(gè)宏上,。
這樣點(diǎn)擊這個(gè)新建的按鈕,C1就會(huì)等于A1-B1
VBA語法
變量
區(qū)別:
VBA的變量規(guī)則與java基本一致,,最大的不同有以下兩點(diǎn):
1,、VBA變量大小寫不敏感 xy = XY = xY
2、當(dāng)VBA程序中遇到一個(gè)新的變量名時(shí),,VBA會(huì)自動(dòng)創(chuàng)建該變量,,無需事先聲明。
上面的代碼x取一個(gè)固定單元格的值,,程序根據(jù)單元格的值,,計(jì)算對(duì)應(yīng)行的數(shù)據(jù)。
注意:因?yàn)関ba定義變量不像Java有變量初始化,,Java程序一旦調(diào)用沒有定義過的變量編譯會(huì)出錯(cuò),。vba沒有定義變量初始化,所以調(diào)用一個(gè)不存在的變量不會(huì)報(bào)錯(cuò),,他會(huì)自動(dòng)創(chuàng)建這個(gè)變量,,只是這個(gè)變量沒有值。(所以把一個(gè)變量名修改后,,后面調(diào)用這個(gè)變量的地方一旦漏改,,程序不會(huì)報(bào)錯(cuò),但是結(jié)果會(huì)出錯(cuò))
為了應(yīng)付沒有定義變量調(diào)用也不會(huì)報(bào)錯(cuò)的情況,,可以在程序里事先聲明程序里只使用以下變量,。
強(qiáng)制聲明變量:
必須寫在該模塊文件的第一行寫上Option Explicit,然后在方法體中用Dim聲明,,并用逗號(hào)分隔,。一旦聲明dim的方法體里使用了沒有用dim聲明的變量,編譯就會(huì)報(bào)錯(cuò),。
常量
不可以被修改的變量,一旦定義成了常量,,修改這個(gè)值會(huì)報(bào)編譯錯(cuò)誤,。代碼寫法如下:
Const p = 3.14
FOR循環(huán)
上述代碼for循環(huán)是:i從11循環(huán)到20,,步長是1(循環(huán)一次加1)
注意:For循環(huán)結(jié)束處的 Next i,i可以省略不寫,。(for循環(huán)套for循環(huán)的時(shí)候建議寫,,否者不知道那個(gè)結(jié)束end是屬于哪個(gè)for循環(huán)的)
如果步長是每次增加1,step 1也可以省略不寫,。其他情況例如遞減需要寫成step -1,。
(使用tab鍵讓代碼縮進(jìn)關(guān)系統(tǒng)一)
While循環(huán)
第一種:
While Cells(1,2) <> “”
…
Wend
第二種:(常用)
Do While Cells(1,2) <> “”
…
Loop
例子代碼:遍歷每一個(gè)sheet頁,計(jì)算每一個(gè)sheet頁面的指定表格數(shù)據(jù)
IF ELSE
1,、基本用法
下面的宏關(guān)聯(lián)按鈕后,,點(diǎn)擊按鈕會(huì)根據(jù)A1和A2單元格的值在A3中寫入合格或不合格,以下就是if else的用例:
Sub ifElseTest()
Dim score1, score2
score1 = Cells(1, 1)
score2 = Cells(1, 2)
'當(dāng)A1和A2單元格都大于60的時(shí)候,,A3單元格顯示合格
If score1 > 60 And score2 > 60 Then
Cells(1, 3) = "合格"
Else
Cells(1, 3) = "不合格"
End If
End Sub
2,、如果判斷語句寫在同一行,那么可以不寫End IF,,例:
If score1 > 60 Then Cells(1, 3) = "合格"
3,、ElseIf:(ElseIf 是一個(gè)關(guān)鍵字)
關(guān)系運(yùn)算符
大于:> 小于:< 大于等于: >= 小于等于:<= 不等于: <> 等于:=
邏輯運(yùn)算符
與:And 或:or 非:not
字符串
字符串連接用&符號(hào),記得字符串用&連接時(shí),,字符串與&符號(hào)之間一定要有空格,,否者會(huì)引發(fā)歧義。
str1 = "a"
str2 = "b"
Cells(2, 1) = Cells(2, 1) & str1 & str2
程序調(diào)試debug
1,、設(shè)置斷點(diǎn):直接在vba編輯器中找到要調(diào)試的代碼,,點(diǎn)擊左側(cè)豎欄,生成斷點(diǎn),。運(yùn)行程序代碼會(huì)到此處停下,。
2、單步執(zhí)行 F8 (VBA編輯器點(diǎn)開“調(diào)試”,,里面能看到所有調(diào)試方法和快捷鍵)
3,、添加監(jiān)視:
4、報(bào)錯(cuò)自動(dòng)定位:
如果運(yùn)行時(shí)代碼出錯(cuò),,VBA會(huì)彈出提示出錯(cuò),,點(diǎn)擊彈出框的“調(diào)試”,會(huì)自動(dòng)定位到出錯(cuò)行
宏操作excel
設(shè)置單元格字體顏色
Sub setCellsStyle()
'把A1到C2之間(矩形的左上角與右下角范圍)所有單元格字體變?yōu)榧t色
Range("A1:C2").Font.Color = -16776961
End Sub
根據(jù)上例發(fā)現(xiàn),,Excel中每一個(gè)元素的操作都有對(duì)應(yīng)的對(duì)象,,例如Cells就是操作單元格的,Range就是范圍操作單元格的,,對(duì)應(yīng)的excel中各種圖形等都有固定的調(diào)用方法,,但是我們不可能記住每一種圖形的調(diào)用對(duì)象,所以我們可以利用excel錄制宏的方法操作格個(gè)圖形對(duì)象,然后看錄制宏的代碼,,就知道了每種對(duì)象如何調(diào)用,。
錄制宏-參照宏代碼
Excel提供了一種記錄我們操作excel動(dòng)作的“錄制宏”功能,只要我們記錄住操作excel的動(dòng)作,,再執(zhí)行錄制的宏,,excel就會(huì)重復(fù)我們錄制的動(dòng)作。我們可以查看excel生成的代碼,,了解這些宏如何操作控件,,從而根據(jù)這些代碼來完成我們的代碼。
例:我們想知道刪除行的代碼如何操作
1,、點(diǎn)擊錄制宏
2,、彈出我們要錄制的宏定義,可以直接點(diǎn)擊確定
3,、我們刪除一行代碼,,然后點(diǎn)“停止錄制”
4、發(fā)現(xiàn)我們的代碼里生成了一段這樣的代碼
Sub 宏2()
' 宏2 宏
Rows("4:4").Select
Selection.Delete Shift:=xlUp
End Sub
紅色部分就是刪除行的代碼,,可以解釋為:刪除第四行(從第四行到第四行)
5,、這樣我們就可以開發(fā)一個(gè)程序,把第一列單元格內(nèi)容小于10的進(jìn)行行刪除,。
先建立一個(gè)按鈕,,關(guān)聯(lián)宏方法deleteRow()
Sub deleteRow()
'從20行遍歷到第1行(刪除應(yīng)該倒序遍歷,因?yàn)閕ndex有變化)
For i = 20 To 1 Step -1
If Cells(i, 1) <= 10 Then
'刪除第i行
Rows(i & ":" & i).Select
Selection.Delete Shift:=xlUp
End If
Next i
End Sub
對(duì)象編程excel
主要類
VBA也把excel的各種控件分裝成了對(duì)象,,可以調(diào)用這些定義好的類,、屬性、方法操作控件,。
這里的類,、屬性、方法與Java在概念上一致,。
以下是調(diào)用操作excel常用的類:(當(dāng)這些類被創(chuàng)建對(duì)象,,每個(gè)對(duì)象就代表具體的excel相應(yīng)控件)
Application :正在運(yùn)行的excel系統(tǒng)本身
WorkBook :代表一個(gè)打開的excel文件也成為工作簿 (打開的一個(gè)excel文件就是一個(gè)工作簿)
WorkSheet :代表一張工作表,也是一個(gè)sheet頁
Range :代表一個(gè)或多個(gè)單元格組成的內(nèi)容區(qū)域,。
因?yàn)橐粋€(gè)application中有多個(gè)工作簿,,一個(gè)工作簿(WorkBook)中有多個(gè)工作表
(WorkSheet),一個(gè)工作表包含多個(gè)單元格,。
所以Application類里有一個(gè)屬性是WorkBooks,,他是一個(gè)集合,用來存放多個(gè)WrokBook,。
WorkBook下也有一個(gè)屬性,,是一個(gè)集合,,用來存放工作表,這個(gè)屬性就是WorkSheets,。
WorkSheet下也有一個(gè)屬性,,用來存放一個(gè)單元格對(duì)象,屬性是Cells
Application
Excel系統(tǒng)
|
Range
單元格內(nèi)容區(qū)域
多個(gè)單元格對(duì)象
|
WorkSheets
存放WorkSheet的集合
|
Cells
一個(gè)單元格個(gè)對(duì)象
|
使用類操作excel
1,、定義一個(gè)變量,變量類型是WorkSheet,,寫法如下:
Dim w1 As WorkSheet
2,、給一個(gè)屬于復(fù)雜類型的變量賦值,需要加關(guān)鍵字Set,,寫法如下:
Set w1 = WorkSheets(i);
例子:
Sub test1()
'定義一個(gè)變量存放sheet對(duì)象
Dim w1 As Worksheet
Dim i
'遍歷所有sheet頁
For i = 1 To Worksheets.Count
Set w1 = Worksheets(i)
'讓每個(gè)sheet頁面的10行1列都等于自己的sheet名
w1.Cells(10, 1) = w1.Name
Next i
End Sub
新建一張工作表
WorkSheet的Add方法:在所屬工作簿的文件中新建一個(gè)工作表(sheet頁)
新建工作表例子代碼:
Sub test2()
'定義一個(gè)變量存放sheet對(duì)象
Dim w1 As Worksheet
'在本工作簿中新建一個(gè)sheet頁
Set w1 = Worksheets.Add
'設(shè)定新建工作簿名
w1.Name = "new sheet"
End Sub
獲取工作表對(duì)象
1,、按sheet頁所在順序取工作表對(duì)象:
例:取第二個(gè)sheet頁
Dim w1 As Worksheet
Set w1 = Worksheets(2)
2、按sheet頁名字取工作表對(duì)象
Dim w1 As Worksheet
Set w1 = Worksheets(“new test”)
過程(宏)調(diào)用
過程調(diào)用用Call關(guān)鍵字,,例:
Sub test3()
Dim w1 As Worksheet
Set w1 = Worksheets.Add
w1.Name = "new"
End Sub
Sub test4()
'調(diào)用過程test3
Call test3
End Sub
Call關(guān)鍵字可以省略
函數(shù) Function
函數(shù)是過程的一種,,在執(zhí)行結(jié)束后能將運(yùn)行結(jié)果返回給調(diào)用者
函數(shù)需要不用Sub關(guān)鍵字,用Function,,函數(shù)追后一行寫上:函數(shù)名 = 要返回的值
這樣調(diào)用這個(gè)函數(shù)的過程可以通過變量接受這個(gè)函數(shù),。
函數(shù)可以在excel的單元格中當(dāng)成公式使用
在單元格中可以寫入公式:
系統(tǒng)常用函數(shù):處理字符串函數(shù)
1、Len(str) 返回字符串長度
點(diǎn)三角箭頭運(yùn)行,,彈出str字符串的長度
2,、Trim(str) 去除兩邊空格
3、Replace(str,a,b)把字符串str中所有a都替換成b
4,、Lcase(str) 所有英文字母都編程小寫
Ucase(str) 所有英文字母都編程大寫
5,、Left(str,3)把字符串str從左邊取3個(gè)字符
Right(str,3)把字符串str從右邊取3個(gè)字符
6、Mid(str,2,5) 把字符串str從第二個(gè)字符開始,,取五個(gè)字符
7,、InStr(str,”a”) 在str中尋找a出現(xiàn)的位置,如果沒找到返回0
InStr(3,str,”a”) 在str中,從第3個(gè)字符開始尋找a出現(xiàn)的位置
For Each
操作多個(gè)excel文件()
1,、WorkBooks.open(文件名) 指定路徑打開excel文件
2,、Close關(guān)閉操作的工作簿
上例代碼最后加入如下代碼:
wb.Close
3、新建一個(gè)工作簿
WorkBooks.Add
Range單元格對(duì)象
Cells是定位單元格用的,,并不是單元格對(duì)象,,單元格對(duì)象類是Range
Cells的寫法是我們平時(shí)的簡(jiǎn)寫,如果寫全應(yīng)該是如下格式:
1,、Range屬性
返回任意單元格范圍:Range(“D5”) , Range(“B3 : F7”)
也可以用下面方法定位左上角和右下角位置,,定位到單元格范圍:
2、修改Range范圍內(nèi)單元格內(nèi)容
3,、清除范圍內(nèi)單元格內(nèi)容
例子代碼:
4,、Range的Font屬性
還有color 字體顏色 Bold字體粗細(xì) 等屬性
例子代碼:
5,、Range.Interior屬性:
6、clear清除
7,、Range.Merge合并單元格:將Range范圍內(nèi)單元格合并為一個(gè)單元格
Range.UnMerge拆分單元格: 將Range范圍內(nèi)單元格拆分為一個(gè)個(gè)單元格
合并共同前綴代碼 with
以上代碼可以用with改寫為下面的代碼:
Application對(duì)象
1,、默認(rèn)直接調(diào)用的屬性是Application的屬性
代碼中我們控制一個(gè)單元格常常這么寫:
Cells(3,5) = “text”
那么Cells是誰的屬性呢,?如果我們用以下寫法:
Dim w As Worksheet
Set w = Worksheets(1)
w.Cells(3,5) = “text”
那么我們知道Cells是Worksheet的屬性,,而直接寫Cells,那么他是Application的屬性
等同于:
Application.Cells(3,5)=”test”
Application代表所有打開的excel工作表里,,當(dāng)前正在被我們編輯的工作表(sheet),,也可以理解為當(dāng)前正在顯示的工作表。Application可以默認(rèn)不寫,。
同理直接調(diào)用的這個(gè)代碼:Range(“E3”)=7,這個(gè)Range屬性也是Application下的屬性,。
2、Application.ActiveWorkbook:
當(dāng)前正處于激活狀態(tài)的工作簿(即活動(dòng)工作簿)對(duì)象
3,、Application.ActiveSheet:
當(dāng)前正處于激活狀態(tài)的工作表(即活動(dòng)工作表)對(duì)象
例:記錄我們當(dāng)前工作簿的對(duì)象,,在操作變化后,能找到當(dāng)初的對(duì)象
Dim w1 As Workbook, w1 As Wrokbook
Set w1 = Application.ActiveWorkbook
Set w2 = Workbooks.Add
w2.Wroksheets(1).Cells(2,2) =”a”; '操作新建工作簿的第一個(gè)工作表的2行2列單元格個(gè)
w1.Wroksheet(1).Cells(3,5) = “b” '操作當(dāng)初工作簿第一個(gè)工作表的3行5列單元格個(gè)
以上這個(gè)代碼的功能就是利用Application記住了當(dāng)初的操作文件,,即使操作其他文件后,,也能夠找到原來的操作文件。
4,、Application.WorksheetFunction.公式名:
在VBA代碼中直接調(diào)用Excel表格公式
例如:獲取B2到D7單元格中最大的值
M = Application.WorksheetFunction.Max(Range(“B2:D7”))
也可以寫成:
Set r = Range(Cells(2,2),Cells(7,4))
M = Application.WorksheetFunction.Max(r)
5,、Application.DisplayAlerts
是否顯示Excel警告框。
例如保存一個(gè)文件代碼如下:
W2.SaveAs(“xxx.xlsx”)
W2.Close
執(zhí)行第一次,,很自然生成了一個(gè)xxx.xlsx文件保存到當(dāng)前目錄,,但是再執(zhí)行這個(gè)程序,每次都提示是否覆蓋,,用Application可以關(guān)閉這個(gè)提示,,直接覆蓋。
在代碼中寫入:Application.DisplayAlerts = false
再執(zhí)行保存文件代碼,,文件直接覆蓋,,不再提示是否覆蓋。
記得操作完后,,在調(diào)用close后,,一定要再讓Application.DisplayAlerts = true,
否者excel任何操作都不在彈出提示信息。
6,、Application.quit
退出excel
VBA筆記進(jìn)階篇
數(shù)據(jù)類型
常用類型
字符型:Dim str As String
str = “TEST”
整數(shù)型:Dim strLen As Integer
strLen = 3
變體型:不定義類型,,根據(jù)賦值的數(shù)據(jù)類型定義類型(可以調(diào)整賦值來變化數(shù)據(jù)類型)
Dim str
str = “TEST”
變體類型缺點(diǎn):
1、效率低,,速度慢,,因?yàn)槌绦蛎看味家袛噙@個(gè)數(shù)據(jù)是什么類型
2,、一旦單元格被設(shè)置成文本類型,從單元格抓取數(shù)據(jù),,會(huì)把數(shù)字型當(dāng)成字符型處理
注意:Dim a ,b As String a是變體類型,,b是整數(shù)型
Dim a As Integer, b As String a 和 b 都是整數(shù)型
+ 和 & 的 區(qū)別:
加號(hào)只能鏈接兩邊都是字符串的數(shù)據(jù),而&可以連接字符型也可以連接數(shù)字型
其他類型:
Integer:占用內(nèi)存2字節(jié),,不支持小數(shù),,取值范圍:-32768 到 + 32768
Long:占用內(nèi)存4字節(jié),不支持小數(shù),,取值范圍:-2147483648到 + 2147483648
循環(huán)工作表最好用Long類型數(shù)據(jù)
Double:占用內(nèi)存8字節(jié),,支持小數(shù),有誤差
Currency:占用內(nèi)存8字節(jié),,支持小數(shù),固定4位小數(shù),,數(shù)據(jù)精確,。
特殊符號(hào)代表數(shù)據(jù)類型
1、特殊符號(hào)代表數(shù)據(jù)類型
Dim result As Long
Result = 30000 * 3
上面這兩行代碼會(huì)報(bào)錯(cuò),,因?yàn)?0000*3的結(jié)果會(huì)存放到臨時(shí)空間然后再賦值給result,,即使result是Long型,能裝下這個(gè)結(jié)果,,但是臨時(shí)空間是Integer,,所以臨時(shí)空間報(bào)錯(cuò)。之所以臨時(shí)空間是Integer型,,是因?yàn)?0000和3都是Integer型數(shù)據(jù),,所以臨時(shí)空間會(huì)變?yōu)镮nteger型。所以我們需要讓臨時(shí)空間知道30000需要定義成Long型,,寫法如下:
Dim result As Long
Result = 30000& * 3
Dim a&, b# 等價(jià)于 Dim a As Long ,b As Double
所以&作為連接符號(hào)的時(shí)候必須與左右兩邊留有空格,,否者會(huì)被當(dāng)成Long類型
2、下劃線:
把很長的語句拆分成若干行書寫
3,、冒號(hào)
把很多行語句拼接到同一行,,不浪費(fèi)空間,代碼整潔,。
a1 = Cells(1, 1): a2 = Cells(1, 2): a3 = Cells(1, 3)
4,、^ 冪運(yùn)算
a的6次方 a ^ 6
5、 \ 只保留整數(shù)部分的除法符號(hào)
日期型
例:日期格式默認(rèn) 月日年 時(shí)分秒,,日期兩邊要有#,,聲明式日期
Dim d1 As Date
d1 = #1/19/2016 10:10:01 AM#
MsgBox d1
1、Date函數(shù) 顯示日期
Dim d1 As Date
d1 = Date
MsgBox d1
2,、Time()函數(shù) 顯示時(shí)分秒
3,、Now()函數(shù) 顯示日期+時(shí)間
4,、解析時(shí)間
5、DateDiff函數(shù)
6,、DateAdd函數(shù)
注意:
日期型本質(zhì)上就式一個(gè)Double型的數(shù)字,,0代表1899年12月30日0時(shí)0分0秒
整數(shù)部分增減1就式增減1天,小數(shù)部分0.1代表0.1天,,即2.4小時(shí),。
邏輯類型 Boolean
只返回True和False
邏輯關(guān)系運(yùn)算符:
AND 并且 相當(dāng)于Java的 &&
OR 或則 相當(dāng)于Java的 ||
NOT 非 相當(dāng)于Java的 !
其他
流程控制:
Do While 用法補(bǔ)充
靠條件控制,,不再進(jìn)行下一次循環(huán)
Exit語句
直接跳出一個(gè)循環(huán)結(jié)構(gòu)或一個(gè)子過程(函數(shù)),,
比如退出Do While循環(huán),可以寫做Exit Do
如果是結(jié)束for循環(huán)就是 Exit For,,退出函數(shù)用 Exit Sub
用Exit退出,,Exit下面的代碼將不再執(zhí)行
注意:
1、Do While 可以用Exit Do結(jié)束循環(huán),,While無法使用Exit結(jié)束循環(huán),,所以處理循環(huán)不要用While
2、Exit 和Java中的break一樣,,當(dāng)用在嵌套循環(huán)中,,只能結(jié)束當(dāng)前這個(gè)循環(huán),不能結(jié)束所有循環(huán),。
GoTo 語句
直接跳轉(zhuǎn)到指定標(biāo)簽位置:
因?yàn)镚oTo語句太過隨意,,容易造成代碼混亂,不建議使用,,只建議在處理異常中使用,,如下節(jié)
On Error GoTo MyError
這個(gè)語句的意思是:從下一句開始,一旦發(fā)生錯(cuò)誤就直接跳轉(zhuǎn)到MyError標(biāo)簽處繼續(xù)運(yùn)行
On Error Resume Next
從下面開始,,如果某行運(yùn)行錯(cuò)誤,,就忽略它并繼續(xù)執(zhí)行
函數(shù)
IsDate
驗(yàn)證數(shù)據(jù)是否是日期型,是日期型返回True
例如:驗(yàn)證單元格1行1列是否是日期型:
If IsDate(Cells(1,1)) = True Then
Cells(1,1) = DataAdd(“d”,38, Cells(1,1))
End If
IsNumeric
如果x是某種數(shù)值類型,,比如Integer,,Long,Single,,Double,,Currency等,函數(shù)返回True,,如果是其他類型返回False,。
TypeName
返回?cái)?shù)據(jù)類型的類名
例如:TypeName(“test”) 返回String字符串
數(shù)據(jù)類型的轉(zhuǎn)換函數(shù)
Cbool,Cdate,CStr,Cint,CLng,CDbl,Ccur,Csng,Cbyte,Cdec
VBA中可以自動(dòng)類型轉(zhuǎn)換,不加這些轉(zhuǎn)換函數(shù)也可以,,但是加了會(huì)讓代碼更加清晰,。
如果Double轉(zhuǎn)換成Integer會(huì)進(jìn)行四舍五入,,到那時(shí)他的這個(gè)四舍五入規(guī)則與我們的不同,用的是銀行家舍入法:
Excel工作表中只能存放1900年以后的日期,,如果想存放更之前的日期就需要用Cstr把日期型轉(zhuǎn)換成字符型,,然后存放到excel中。
四舍五入函數(shù)
VBA中的Round(x,n)也是用的銀行家舍入法,,對(duì)x進(jìn)行四舍五入,,并保留小數(shù)點(diǎn)后n位數(shù)字。
如果想使用我們平時(shí)用的規(guī)則,,需要用excel中的公式:
Application.WorksheetFunction.Round(x,2)
Int(x)
如果不是excel文件中沒有上面這個(gè)函數(shù)我們可以用Int()函數(shù)幫忙實(shí)現(xiàn)四舍五入的功能
Int(x)函數(shù),,返回一個(gè)不大于x的最大整數(shù),例如:
所以用如下這個(gè)公式就可以實(shí)現(xiàn)四舍五入:
i = Int(x+0.5)
負(fù)數(shù)的四舍五入規(guī)則不一,,本方法將-2.5舍入為-2,,所以需要根據(jù)業(yè)務(wù)來確定是否符合規(guī)定
Asc和Chr
Asc(“A”) 把字符A轉(zhuǎn)換成ASCII碼
Chr(65) 把ASCII碼轉(zhuǎn)換成對(duì)應(yīng)字符
所有的字符都可以轉(zhuǎn)換成數(shù)字來表示,ASCII就是一種編碼格式,。
所以字符和數(shù)字可以靠上面的兩個(gè)函數(shù)來回轉(zhuǎn)換
用途:
1,、如果需要在字符串中加入換行符,就需要用到上面的函數(shù),。例:
Str = “xxxxxxxxxxxxxxxxxx” & Chr(13) & Chr(10) & “xxxxxxxxxxxxxxxxxxx”
2、如果想把a(bǔ)到z打印到excel中,,可以使用如下寫法:
For i=65 To 90
Cells(i-63,2) = Chr(i)
Next i
我們想把數(shù)字轉(zhuǎn)換成對(duì)應(yīng)的字母,,都可以用Char函數(shù)解決
3、比較字符大小,,可以讀取字符的每一個(gè)字母,,用Asc函數(shù)轉(zhuǎn)換成ASCII碼,然后比較大小,。
ASCII碼轉(zhuǎn)換表:
數(shù)組 Array
定義一個(gè)數(shù)組變量:Dim my_arr(9) As String
解釋:
1,、變量后面帶括號(hào)代表是數(shù)組類型,括號(hào)里放數(shù)組最大下標(biāo),,
2,、數(shù)組下標(biāo)從0開始,這里會(huì)放10個(gè)數(shù)
3、字符型數(shù)組
例:
自定義數(shù)組下標(biāo):
Dim arr (3 To 6)
讓變體(因?yàn)檫@里沒指定數(shù)組類型 )數(shù)組arr的最小下標(biāo)為3,,最大為6,,改數(shù)組的元素包括 a(3) a(4) a(5) a(6)
Lbound(arr)返回?cái)?shù)組最小下標(biāo)
Ubound(arr)返回?cái)?shù)組最大小標(biāo)
以上兩個(gè)函數(shù)的結(jié)果可以給for循環(huán)數(shù)組開始接受位置用
Split函數(shù)
Split(待拆分的字符串,分割符字符串)
將字符串按照指定分隔符拆分成多個(gè)字串,,返回一個(gè)數(shù)組
Dim arr() As String
arr=Split(Cells(1,1),”,”)
For Each 循環(huán)
下面x代表數(shù)組每一個(gè)元素,,a是數(shù)組
For Each x In a
str = x
Next x
文本處理
讀取文本文件
VBA讀取文件流程
1、打開文件
Open “d:\demo\client.text” For Input As #1
For Input 代表輸入,。#1代表代號(hào),,這個(gè)被打開文件的代號(hào),。
2、讀取一行內(nèi)容
Line Input #1,s (讀取#1代表的文件一行記錄,,每執(zhí)行一次這句代碼就會(huì)讀取一行,,執(zhí)行幾次讀取幾行)
3、是否已讀取到末尾
EOF(1) 讀取#1代表的文件,,如果讀取到末尾這個(gè)函數(shù)返回True
4,、關(guān)閉文件
Close #1 關(guān)閉#1代表的文件
例:
寫入文本文件:
1、打開寫入文本文件
Open “d:\demo\client.text” For Output As #1
寫入一個(gè)文件,,如果有同名文件會(huì)覆蓋,,沒有此文件會(huì)創(chuàng)建
Open “d:\demo\client.text” For Sppend As #1
追加內(nèi)容寫入文件,不會(huì)覆蓋原文件內(nèi)容
2,、寫入一行
Print #1 “xxxxx”; 莫非帶分號(hào),,再次寫入,同行追加
Print #1 “xxxxx” 末尾空白,,再次寫入,,字符會(huì)換行
3、關(guān)閉文件
Close #1
Dir函數(shù)讀取目錄所有文件
讀取目錄下所有文件
打開一個(gè)目錄,,目錄結(jié)尾必須是“\”,,f是返回的一個(gè)文件名
f = Dir("c:\testfile\")
然后每執(zhí)行一次f = Dir都返回一個(gè)目錄下的文件名
Sub test8()
Dim f As String
f = Dir("c:\testfile\")
Do While f <> ""
MsgBox f '彈出文件名
f = Dir '讀取下一個(gè)文件名
Loop
End Sub
打開一個(gè)目錄下所有excel文件轉(zhuǎn)換成Wrokbooks對(duì)象:
Set w = Wrokbooks.Open(path & fileName)
讀取指定文件
只想打開xlsx結(jié)尾的文件:
用這個(gè)判斷語句 If Lcase(Right(fileName,5)) = “.xlsx”
更高級(jí)的寫法:
fileName = Dir(“d:\test\*.xlsx”)
判斷目錄是否存在
判斷文件是否存在
Dir(“目錄文件名”)返回空字符串證明沒有這個(gè)文件
返回目錄和子目錄下所有文件名:
只返回一層子目錄
f = Dir(“D:\test\”,”vbDirectory”)
返回目錄下所有文件和所有子目錄文件:
需要用到遞歸方法
判斷是文件夾:
GetAttr(“file dir”) And vbDirectory = vbDirectory
Range對(duì)象高級(jí)使用
Range代表單元格區(qū)域?qū)ο?(可以理解為單元格二維數(shù)組)
Range對(duì)象位置有關(guān)屬性:
1、Range.Row 該Range左上角單元格的行號(hào)
2,、Range.Column 該Range左上角單元格的列號(hào)
3,、Range.Address該Range各個(gè)對(duì)焦頂點(diǎn)的絕對(duì)引用地址。
Set r = Range(“B3:D9”) r.Address返回“$B$3:$D$9”
注意:
當(dāng)Range包含多個(gè)矩形區(qū)域時(shí),,Row和Column只返回其中某一個(gè)矩形的左上角位置,,并不一定是整個(gè)Range的左上角。
比如Range(“D3:E4,A1:B2”)的Row和Column返回的可能是第3行第4列,,而非第一行第一列
Range對(duì)象范圍有關(guān)的屬性:
1,、Range.Count 該Range中的單元格數(shù)量
注意:Range對(duì)象由多個(gè)矩形區(qū)域構(gòu)成時(shí),個(gè)矩形相互重疊的單元格會(huì)被重復(fù)計(jì)算,。
Count計(jì)算的其實(shí)是對(duì)象而非單元格個(gè)數(shù),,而且當(dāng)數(shù)量太大時(shí)會(huì)發(fā)生溢出錯(cuò)誤,所以計(jì)算單元格格最安全的方法是Range.Cells.CountLarge
2,、Range.Rows 容納了該Range中的每一行,,可以使用Range.Rows(n)得到一個(gè)新的Range對(duì)象,代表該區(qū)域第n行的所有單元格,。
注意:如果Range是由多個(gè)矩形區(qū)域構(gòu)成,,Rows只代表其中某一個(gè)矩形區(qū)域的所有行。
例子:Set a = Range(“C4:E12”)
a.Select '將Range對(duì)象全部選中(方便看現(xiàn)象)
Set rw = a.Rows(2) '把Range中的第二行全部取出,rw對(duì)象還是一個(gè)Range
3,、Range.Columns 容納了該Range中的每一列,,可以使用Range.Columns(n)得到一個(gè)新的Range對(duì)象,代表位于該區(qū)域第n列的所有單元格,。
4,、Range.Cells(1,1) 取Range范圍內(nèi)的第一行第一列單元格
特殊的Range對(duì)象
1、代表工作表(sheet)中全部單元格的對(duì)象
WorkSheet的屬性Cells
取得最大行號(hào):ActiveSheet.Cells.Rows.Count
2,、代表工作表(sheet)中全部被使用過的單元格(有效單元格,,包含所有數(shù)據(jù))Range對(duì)象
WorkSheet的UsedRange屬性
返回一個(gè)矩形區(qū)域的Range對(duì)象,正好能夠容納這個(gè)工作表中所有使用過的單元格,。
注:即使一個(gè)單元格修改過格式?jīng)]有填寫內(nèi)容也會(huì)被認(rèn)為是被使用過,,有些情況下單元格內(nèi)容被刪除清空后仍可能被認(rèn)為是使用過的。
例子代碼:把使用過的單元格選中
獲取該行最后一行的行號(hào):r.Row + r.Rows.Count -1 (左上角起始行號(hào)+Range范圍行數(shù)-1)
Range轉(zhuǎn)化二維數(shù)組(提高讀寫excel效率)
如果我們的表格中有大量的單元格要讀取,,用平時(shí)我們用的Cells一個(gè)個(gè)單元格個(gè)讀取效率將會(huì)非常低下,,所以我們可以把要讀取的單元格范圍(Range)轉(zhuǎn)化成二維數(shù)組,然后讀取數(shù)組獲得內(nèi)容,。
二維數(shù)組 Dim arr(3,5) As Long 有4行6列個(gè)元素(起始位置從0開始)
如果只想二維數(shù)組返回三行五列并且從1開始,,可以寫成
Dim arr(1 To 3, 1 To 5) As Long
Ubound(arr,1) 二維數(shù)組第1行數(shù)據(jù)的最大下標(biāo)
Lbound(arr,1) 二維數(shù)組第1行數(shù)據(jù)的最小下標(biāo)
把Range對(duì)象轉(zhuǎn)換為二維數(shù)組的寫法:
Dim arr()
arr=Range(“A2:C3”)
注意:Range轉(zhuǎn)換成二維數(shù)組,數(shù)組的下標(biāo)是從1開始(與Cells的下標(biāo)規(guī)則一樣)
例:
1,、如果讀取的范圍操作Range的返回會(huì)發(fā)生下標(biāo)越界錯(cuò)誤
2,、截取Range的數(shù)組,聲明的時(shí)候必須是動(dòng)態(tài)數(shù)組(數(shù)組后面的括號(hào)里不寫下標(biāo)范圍)
3,、這個(gè)數(shù)組必須是變體類型,,不能聲明成具體數(shù)據(jù)類型。
4,、Range中即使只有一行數(shù)據(jù),轉(zhuǎn)化成數(shù)組后也是二維數(shù)組,,是一個(gè)1行多列的二位數(shù)組,。
把數(shù)組寫入Range中
Dim s(2,3) As Integer
S(0,0)=1 : S(0,1)=2: S(0,2)=3: S(1,0)=4 : S(1,0)=5: S(1,0)=6
Range(“b2:e4”) = s
如果想把一個(gè)維數(shù)組放到execel的一列中,需要使用矩陣轉(zhuǎn)置函數(shù)
Range(“c2:f2”) = Application.Transpose(s)
遍歷Range
Range的結(jié)構(gòu)可以理解成一個(gè)二維數(shù)組的結(jié)構(gòu),,我們可以用雙重循環(huán)遍歷Range,,如果我們不關(guān)心Range每個(gè)單元格的具體行號(hào),只是單純的遍歷處理,,那么我們可以用Each方式遍歷Range的每一個(gè)單元格,。
例:取出所有被使用的單元格,單元格個(gè)內(nèi)容是紅色的相加
Dim r As Range,r1 As Range
Set r = w.UsedRange '取出所有被使用的單元格
For Each r1 In r
If r1.Font.Color = vbRed Then
s = s + r1.Value
End If
Next r1
拆分成兩個(gè)處理:(調(diào)用函數(shù))
Range.HasFormula屬性
當(dāng)Range是一個(gè)單元格時(shí),,此屬性查看單元格中是否有公式,,由公式這個(gè)屬性返回True,沒有返回False
Range.Formula屬性
當(dāng)Range是一個(gè)單元格時(shí),如果單元格是公式則返回公式文本,,如果沒有公式則與Value屬性一樣返回單元格的內(nèi)容,。
Range的Value屬性,如果單元格是公式,,Value返回的是公式的結(jié)果
如果想把一個(gè)單元格設(shè)置成一個(gè)公式,,F(xiàn)ormula和Value都可以:
Range的下標(biāo)
當(dāng)我們得到一個(gè)Range對(duì)象,要遍歷Range的對(duì)象的時(shí)候下標(biāo)是從1開始,,無論這個(gè)Range的單元格在sheet中的什么位置,。而Cells讀取單元格的下標(biāo)都是根據(jù)單元格相對(duì)于sheet中位置定的,必須是從sheet的1,,1開始,。
所以遍歷Range,定義范圍可以用如下方法
Application.Union方法
把多個(gè)Range對(duì)象聯(lián)合成一個(gè)新的Range對(duì)象
Dim r As Range
Set r = Union(Range(a1:b2), Range(c1:d2), Range(e1:f2))
但是Range的區(qū)域如果有重合,,新合并的Range會(huì)有重復(fù)單元格
Application.Intersect方法
找到同時(shí)屬于多個(gè)Range的單元格(各Range重合的部分),,作為一個(gè)新的Range對(duì)象返回。下圖紫色部分就是找出的重合部分
Range.CurrentRegion屬性
返回一個(gè)包含了這個(gè)Range的最大連續(xù)使用區(qū)域,。該區(qū)域與其他任何已使用單元格都不鄰接,。如下圖通過藍(lán)色部分找到藍(lán)色區(qū)域所在表的所有單元格對(duì)象,返回一個(gè)Range對(duì)象,。
例子:找到有“上海市”這幾個(gè)字的單元格,,把這個(gè)單元格所在的表變色
Range.Resize屬性:
以該當(dāng)前Range的左上角單元格為原點(diǎn),生成一個(gè)指定大小的新的Range對(duì)象并返回,。
上面兩句可以合并寫成:
Range.Offset屬性
按照Range的大小,,根據(jù)指定的距離平行移動(dòng),從而得到一個(gè)新的同形狀的Range,。
Range.Rows與Worksheets.Rows (Columns)
選中Range的第一行數(shù)據(jù)
Dim r As Range
Set r = Range("A1:H100")
r.Rows(1).Select
選中當(dāng)前sheet頁的第二行數(shù)據(jù)
Dim r As Range
Set r = ActiveSheet.Rows(2)
r.Rows(1).Select
Range.Rows與Worksheets.Rows均可以一次返回多行或多列,,例如
Rows(“2:3”) 返回第二行和第三行,返回的結(jié)果還是Range
Columns(“B:E”)返回B列到E列,,返回的結(jié)果還是Range
合并單元格
如果D6到E7已經(jīng)合并單元格,,我們用For Each遍歷這個(gè)Range對(duì)象
我們會(huì)發(fā)現(xiàn)他程序還是遍歷了4次,而不是一次,,程序還是認(rèn)為Range中有4格單元格,。但是只有第一個(gè)單元格D6有數(shù)據(jù)(合并單元格中的數(shù)據(jù)),其他單元格都沒有數(shù)據(jù),。
結(jié)論:
1,、多個(gè)單元格合并之后,仍被VBA認(rèn)為是各自獨(dú)立的單元格
2,、第一個(gè)單元格的值為合并后顯示的內(nèi)容,,其他單元格被認(rèn)為是空值
Range.MergeCells屬性
1,、當(dāng)該Range完全合并為一個(gè)單元格時(shí),該屬性為True
2,、當(dāng)該Range完全不包含合并單元格時(shí),,該屬性為False
例如上例:Range(“d6:e7”).MergeCells = True
3、當(dāng)該Range中有合并單元格,,還有一部分沒合并單元格,,返回NULL
判斷是否為Null的時(shí)候要用IsNull函數(shù)
4、把一個(gè)Range對(duì)象合并單元格:
Range(“A1:B3”).MergeCells = True
同理,,解除合并單元格:
Range(“A1:B3”).MergeCells = False
5,、VBA還提供了合并和取消合并單元格的方法。
Range.Merge合并單元格 例: Range(“A1:B3”).Merge
Range.UnMerge 取消合并單元格Range(“A1:B3”).UnMerge
Range(“A1:B3”).Merge True這個(gè)寫法是按行合并單元格
Select
Range(“A1:B3”).Select
讓這個(gè)Range的對(duì)象都被選中(和被鼠標(biāo)選中效果一致)
Dim r As Range
Set r = Selection
獲取鼠標(biāo)選中的單元格,,返回一個(gè)Range對(duì)象
可以根據(jù)錄制宏查看復(fù)制,、剪切、添加等功能,,結(jié)合鼠標(biāo)選中(Select),,做出很多操作excel的功能。
注意:盡量不要用Select獲取Range對(duì)象,,影響性能,。可以用Cells()等方法代替Select
提高VBA代碼的性能:
1,、極可能合并不必要的Select和Selection
2,、盡可能刪除不必要的屬性設(shè)置
3、盡可能減少對(duì)象中“.”的數(shù)量,,用With消減“.”的調(diào)用
函數(shù)的高級(jí)使用技巧
可選參數(shù)
1,、Optional 指定一個(gè)可選參數(shù)
Function mySumProduct(r As Rage, Optional useColumn As Boolean=False)
在調(diào)用此函數(shù)的時(shí)候,可以不寫這個(gè)參數(shù),,不寫這個(gè)參數(shù)默認(rèn)False
IsMissing(a)函數(shù)
判斷一個(gè)可選參數(shù)a是否被提供,,如果沒有提供,則返回True,,否則返回False
要求:該可選參數(shù)必須是變體類型,,且不能有默認(rèn)值。
例子代碼:
myFun(3, ,5)這個(gè)寫法是只傳遞第一個(gè)和第二個(gè)參數(shù),。另外還有一個(gè)更好的調(diào)用方法
2,、指定參數(shù)名傳遞參數(shù):
使用 := 可以按參數(shù)名傳遞參數(shù)數(shù)值
如上例可以寫成:myFun(a:=3, c:=5)
Msgbox函數(shù)
我們常用的Msgbox(彈出對(duì)話框)就是一個(gè)可選參數(shù)
Msgbox “信息,!” , 1
第二個(gè)參數(shù)就是彈出畫面的種類,,只有確認(rèn)按鈕,有確認(rèn)和取消按鈕等
這些數(shù)字在VBA中有對(duì)應(yīng)的常量,,例如:
Msgbox “信息,!” , 1 等價(jià)于 Msgbox “信息!” , vbYesNo
Msgbox還有第三個(gè)可選參數(shù),是顯示titile信息用的
Msgbox的返回值:
i=MsgBox(“please button”,vbYesNo)
在彈出的對(duì)話框上選yes,,i返回6,,選no,i返回7
函數(shù)后面的參數(shù)寫不寫在括號(hào)里:
調(diào)用函數(shù)決定是否寫括號(hào)的三種情況:
1,、沒有參數(shù):不寫
2,、有參數(shù),調(diào)用語句處于一行代碼中間:寫
例1: x = myFun(3,4,5)
例2: If m myFun(3,4,5) >10 Then
3,、有參數(shù),,調(diào)用語句獨(dú)占一行代碼:不寫
例: Sub demo()
myFun 3, 5, 7
End Sub
之所以一行Function,不寫括號(hào)是因?yàn)槌绦驎?huì)把這個(gè)代碼當(dāng)成eval計(jì)算(同js的eval方法)
VBA對(duì)象的默認(rèn)屬性
4,、如果記不住以上規(guī)則,,可以在調(diào)用函數(shù)的時(shí)候加Call
Call mySub(3,5,7)
值傳遞和引用傳遞:
ByRef
VBA在默認(rèn)情況下都是引用傳遞,如果把一個(gè)變量a傳遞給一個(gè)函數(shù),,函數(shù)對(duì)a進(jìn)行了更改,,函數(shù)結(jié)束后,a變量的值也會(huì)跟誰更改,,因?yàn)閂BA是把a(bǔ)這個(gè)對(duì)象傳遞給了函數(shù),。
ByVal
如果想讓VBA值傳遞(也就是只把值傳遞給函數(shù),函數(shù)即使修改了參數(shù)的值,,也不會(huì)影響函數(shù)外面的變量)代碼寫法:Sub 過程名(ByVal a As Integer)
Set
想把一個(gè)對(duì)象賦值給一個(gè)變量必須要用Set,,想把一個(gè)基本類型賦值給一個(gè)變量就不用加Set
例如: Set w = Worksheets(1)
i = 5
以上就是VBA的默認(rèn)屬性導(dǎo)致
Cells(3,2)的默認(rèn)屬性是Value,所以我們想給這個(gè)單元格賦值的時(shí)候可以直接寫Cells(3,2)=1,。
當(dāng)我們寫 r = Cells(3,2)的時(shí)候,,VBA不知道你是想把這個(gè)cells的Value賦值給r,還是想把這個(gè)cells對(duì)象賦值給r,。所以對(duì)象型賦值要用Set標(biāo)記,。
模運(yùn)算MOD
MOD相當(dāng)于java的%,求余數(shù)用
i=7 MOD 4 結(jié)果是3
隨機(jī)函數(shù) Random
取0 1 2 3的隨機(jī)數(shù): i=Int(Rnd()*4)
生成a到b之間的隨機(jī)整數(shù)公式:int(Rnd()*(b-a+1)+a)
Rnd()計(jì)算的是一個(gè)偽隨機(jī)數(shù)
生成沒有規(guī)律的隨機(jī)數(shù)需要如下操作:
事件處理
常用事件
用戶在Excel中的一個(gè)操作,,或者Excel系統(tǒng)自身的一個(gè)變化,,都可以被視作一個(gè)“事件”。Excel會(huì)隨時(shí)監(jiān)聽這些事件,,并可以根據(jù)編碼的要求,,在某個(gè)事件發(fā)生時(shí)自動(dòng)運(yùn)行對(duì)應(yīng)的VBA程序。
事件發(fā)生在哪里,,代碼就要寫在哪里,,如果事件是靠工作簿觸發(fā),事件代碼就要寫到工作簿文件中,。
打開對(duì)應(yīng)文件后,,要起固定的方法名,,例如想workbook一打開就觸發(fā)事件,就要把代碼寫到ThisWorkbook這個(gè)文件里,,而且方法名要叫 workbook_open()
|
如下圖,,在文件中選中Worksheet,在右邊就能看到所有對(duì)應(yīng)sheet的事件名稱,。
工作簿常用事件
新增工作表(sheet)觸發(fā)的事件用Workbook_NewSheet,,sh這個(gè)參數(shù)代表剛剛新建的工作表。
例子代碼:
新建一個(gè)工作表就自動(dòng)在新建的工作表上增加一個(gè)表格:
這樣沒新建一個(gè)工作表,,就會(huì)生成如下表格:
工作表常用事件
SelectionChange事件,,每當(dāng)用戶選中一個(gè)新的單元格時(shí),Selection_Change事件就會(huì)被觸發(fā),。這個(gè)事件帶有一個(gè)參數(shù)Target,,代表剛剛被選中的單元格對(duì)象/區(qū)域。
例如:沒選中一個(gè)單元格,,就彈出這個(gè)單元格的坐標(biāo),。
利用Range的屬性:
Range.EntireRow Range所在單元格的整個(gè)行
Range.EntireColumn Range所在單元格的整個(gè)列
做一個(gè)功能鼠標(biāo)選中這個(gè)單元格,單元格的所在行和所在列都改變顏色
效果如下,,鼠標(biāo)選中哪個(gè)單元格,,單元格所在行和列都變?yōu)樘焖{(lán)色。
注意:這個(gè)事件寫在哪個(gè)sheet里,,就哪個(gè)sheet頁有這個(gè)事件,,而不是所有sheet頁都有這個(gè)事件。
Sheet事件文件與excel的sheet頁一一對(duì)應(yīng),,見下圖:
所以多個(gè)sheet頁都想要同一個(gè)事件效果,,需要把實(shí)現(xiàn)效果的代碼寫在模塊里,寫一個(gè)子過程,,然后每個(gè)sheet頁都調(diào)用這個(gè)子過程就可以了,。
作用域
變量和過程(函數(shù))都有作用域
Private 只能被本模塊內(nèi)部的代碼調(diào)用。
Public 可以被其他模塊的代碼調(diào)用,。
子過程和函數(shù)如果指明,,默認(rèn)為Public
變量若不指明,默認(rèn)為Private
例如:
Private Function test()
…
End Function
Private Sub Test2()
…
End Sub
防止事件級(jí)聯(lián)
Worksheet_Change(Target)
工作表事件,,修改單元格內(nèi)容,,焦點(diǎn)離開,會(huì)觸發(fā),。(沒修改單元格內(nèi)容也會(huì)觸發(fā))
如果我們?cè)赾hange事件發(fā)生后又修改了單元格內(nèi)容,,這樣的操作又會(huì)觸發(fā)change事件,然后就引發(fā)了事件級(jí)聯(lián),,避免發(fā)生的辦法如下:
下面例子是用Application.EnableEvents=False方法解決級(jí)聯(lián)效應(yīng)
|