VBA簡介、數據類型、變量、數組、運算符、內置函數、過程與函數
一、VBA介紹
1、宏和VBA的關系
vba是編程語言,宏是用vba代碼保存下來的程序。錄制的宏是vba里最簡單的程序,正因為如此,錄制宏存在許多缺陷:如無法進行判斷和循環,不能顯示用戶窗體,不能進行人機交互……
解決錄制宏的這些問題,需要掌握vbs編程的方法,自主的編寫vba程序。
2、VBA程序結構
- 代碼:vba程序由代碼組成。
- 過程:例如Sub過程、Function過程
- 模塊:保存過程的地方,一個模塊可以保存多個不同類型的過程
- 對象:用代碼操作或控制的東西即為對象,例如工作簿、工作表、單元格、圖片、圖表、透視表等
- 對象的屬性:每個對象都有屬性,屬性是對象包含的內容或特點,例如A1單元格的內容:A1.內容,代碼表達為Range("A1).Value
- 對象的方法:方法是指在對象上執行的某個動作,例如Range("A1").Select
- 關鍵字:關鍵字是vba中的保留字或符號,例如語句名稱、函數名稱、運算符等都是關鍵字
3、VBE介紹
VBE即Visual Basic Editor即VBA的編程環境
1)打開VBE編輯器
Alt+F11(Alt+F8是查看宏)
依次執行:(2003版本)工具——宏——Visual Basic編輯器,(2007以上版本)在“視圖”下的“宏”選項卡下
右鍵單擊工作表標簽,執行“查看代碼”命令
2)主窗口:包含“工程資源管理器”、“屬性窗口”、“菜單欄”、“工具欄”、“代碼窗口”、“立即窗口”
3)菜單欄:包含VBE中各種組件的命令
4)工具欄:可以在“視圖”——“工具欄”菜單里顯示或隱藏
5)工程資源管理器:在這里可以看到所有打開的Excel工作簿和已加載的宏,一個Excel的工作簿就是一個工程,工程名稱為“VBA Project(工作簿名稱)”,這里最多可以顯示工程里的4類對象,即Excel對象(包括sheet對象和ThisWorkbook對象)、窗體對象、模塊對象和類模塊對象。
6)屬性窗口:在這里查看或設置對象的屬性
7)代碼窗口:包含對象列表框、過程列表框、邊界標識條、視圖按鈕、代碼編輯區、過程分界線。
8)立即窗口:一個重要用途是用來調試代碼,想顯示立即窗口,可以在視圖選項卡中選擇或者用快捷鍵“Ctrl+G”
4、牛刀小試:用vba生成工資條
Sub 生成工資條() ' ' 生成工資條 宏 ' ' 快捷鍵: Ctrl+m ' Application.ScreenUpdating = False For i = 2 To 7 ActiveCell.Rows("1:1").EntireRow.Select Selection.Copy ActiveCell.Offset(2, 0).Rows("1:1").EntireRow.Select Selection.Insert Shift:=xlDown ActiveCell.Select Next End Sub
二、VBA數據類型
1、VBA中的數據類型
數據類型就是對同一組數據的統稱,如文本、日期、數值等。
VBA里的數據類型有:字節型(Byte)、整數型(Integer)、長整數型(Long)、單精度浮點型(Single)、雙精度浮點型(Double)、貨幣型(Currency)、小數型(Decimal)、字符串型(String)、日期型(Date)、布爾型(Boolean)等,如表3-1
類型聲明符:用特殊符號代替變量類型進行變量類型聲明,例如Dim str$ 中$代表String類型。只有部分數據類型可以使用類型聲明符。
integer % 短整型
long & 長整型
single ! 單精度浮點型
double # 雙精度浮點型
currency @ 貨幣型
string $ 字符型
三、VBA變量、常量
1、變量命名要求
變量必須以字母或漢字開頭,不能包含空格、句號、感嘆號、@、&、$和#,最長不能超過255個字符(一個漢字計2個字符)
2、聲明變量
- 單變量定義:Dim 變量名 As 數據類型
示例:
Dim str As String 聲明一個String類型(變長)的變量,名稱是str
Dim str As String*10 聲明一個String類型(定長,最大存儲10個字符)的變量,名稱為str
Dim str$ 聲明一個String(變長)類型變量,$變量類型聲明符,代表String
- 多變量定義(變量類型相同):Dim 變量1,變量2,…… As 數據類型
Dim x, y, z As String (其中,只有z為String型,x, y變量均為variant類型)
Dim x$ y$ z$ (3個String型)
- 多變量定義(變量類型不同):Dim 變量1 As 數據類型1,變量2 As 數據類型2
Dim str As String,nu As Integer 不同變量之間用逗號隔開
- 不指定類型的變量定義,默認為Variant類型
Dim str 每個變量都要指定數據類型,如果不指定,默認為Variant類型
3、聲明常量
常量定義:Const 變量名稱 As 數據類型=數值
示例:
Const pi As Single=3.14
4、變量的作用域
Public 變量名稱 As 數據類型 【公有變量】
Private 變量名稱 As 數據類型 【私有變量】
Static 變量名稱 As 數據類型 【靜態變量,整個代碼運行期間值不變】
單個變量:本地變量
單個模塊:模塊級變量,用Dim或Private
所有模塊:公共變量,用Public
5、強制聲明所有變量(未定義變量則提示,否則不提示)
Option Explicit 在模塊的第一句表示。
可以在VBE下的“工具”——“選項”——“編輯器”選項卡中進行設置,這里設置后,每個模塊的第一句會自動寫下“Option Explicit”,無需手動輸入。
6、給變量賦值
- 給文本、數值、日期等數據類型變量賦值
語句為:[Let]變量名稱 = 數據 這里的Let可以省略,即:變量名稱=數據
例如:
Dim str As String
Let str = “一起來學習VBA”
- 給對象變量(object型,例如單元格)賦值
語句為:Set 變量名稱=對象 這里Set千萬不能少。
例如:
Dim rng = Range '聲明rng變量為Range類型
Set rng = Worksheets("sheet1").Range("A1") '給變量rng賦值
rng.Value="歡迎來到ExcelHome論壇" '將文本寫入變量指定的單元格
四、VBA數組
1、一維數組
聲明:Public|Dim 數組名(a to b) As 數據類型
示例:
Dim 七6班(1 to 50) As String '聲明一個String類型的數組,名稱為“七6班”,可以存儲50個元素。
等價於:
Public|Dim Arr(0 to 49) As String
Public|Dim Arr(49) As String '數組索引默認是從0開始計數,如果在模塊的第一句寫“Option Base 1”,則數組的起始索引從1開始,而不是0.
七6班(1)="張青"
七6班(2)="鄧城"
……
七6班(50)="馮吉"
2、多維數組:
Dim 醬油(1 to 3,1 to 20)
等價於
Dim 醬油(2,19)
3、多維動態數組
不確定數組中存儲多少個元素,即不能預知元素的大小,可以在首次定義數組時括號內為空,寫成:
Dim 數組名稱()
例子:
Sub dtsz() Dim arr() As String '定義多維動態數組 Dim n As Long '統計A列有多少非空單元格 n = Application.WorksheetFunction.CountA(Range("A:A")) MsgBox n '使用Dim語句聲明變量時,括號內的參數不能是變量,所以必須使用ReDim語句重新指定大小 ReDim arr(1 To n) As String '重新定義數組的大小 End Sub
4、其他常用的創建數組的方式
1)使用Array函數創建數據
Sub ArrayTest() Dim arr As Variant '定義變量 '將1-10的自然數賦給數組 arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) MsgBox "arr數組的第2個元素為:" & arr(1) End Sub
2)使用split創建數組
Sub ArrayTest() Dim arr As Variant '定義變量 '無論是否在模塊中寫入Option Base 1,Split函數返回的數組的最小索引都是0 arr = Split("鄧成,林梅,張青,孔麗,馮吉維,孔佳", ",") '第一個參數包含分隔符或字符串變量,第二個參數是分隔符 MsgBox "arr數組的第2個元素為:" & arr(1) End Sub
3)通過Range對象直接創建數組
Sub ArrayTest() Dim arr As Variant '定義變量 arr = Range("A1:C3").Value '將A1:C3單元格內容存儲到數組arr里 Range("E1:G3").Value = arr '將數組arr的數據寫入大E1:G3 '將數組的值寫入到單元格區域時,單元格區域的大小必須與數組相同 End Sub
5、數組相關函數:UBound和LBound函數
UBound(arr) 獲取數組arr的最大索引號
LBound(arr) 獲取數組arr的最小索引號
數組的元素個數可以表示為:UBound(arr)-LBound(arr)+1
Sub arrcount() Dim arr(10 To 50) 'Char(13)表示回車,_表示代碼換行連接符 MsgBox "數組的最大索引號是:" & UBound(arr) & Chr(13) _ & "數組最小的索引號是:" & LBound(arr) & Chr(13) _ & "數組的元素個數是:" & UBound(arr) - LBound(arr) + 1 End Sub
Sub arrcount() Dim arr(1 To 10, 1 To 100) 'Char(13)表示回車,_表示代碼換行連接符 MsgBox "第一維的最大索引號是:" & UBound(arr, 1) & Chr(13) _ & "第二維的最小索引號是:" & LBound(arr, 2) End Sub
6、數組相關函數:Join函數
將一個以為數組里的元素使用指定的分隔符連接成一個新的字符串
Sub joinTest() Dim arr As Variant, txt As String arr = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) '分割符@可以省略,如果省略,默認使用空格作為分隔符 txt = Join(arr, "@") MsgBox txt End Sub
將數組寫入單元格區域
Sub ArrToRng1() Dim arr As Variant arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9) '將一維數組寫入單元格區域,單元格區域必須在同一行。如果要寫入垂直的一列單元格區域,必須先使用工作表的Transpose函數進行轉換 Range("A1:A9").Value = Application.WorksheetFunction.Transpose(arr) End Sub
五、VBA運算符
1、算術運算符
用於算術運算,返回值類型為數值型。
2、比較運算符
用於比較運算
3、連接運算符
連接運算符用來連接兩個文本字符串,有+和&兩種
示例:
a="歡迎來到"
b="ExcelHome論壇!"
?a+b '問號?告訴VBA在立即窗口中顯示問號后面命令的結果,可以用Print關鍵字代替問號。
歡迎來到ExcelHome論壇!
?a & b
歡迎來到ExcelHome論壇!
?4+5 '符號+兩邊都是數值,執行算術運算
9
?"4"+5 '其中5是數值,執行算術運算
9
?"4"+"5" '兩個都是文本,執行連接運算
45
4、邏輯運算符
邏輯運算符用於判斷邏輯運算式的真假,參與邏輯運算的數據為邏輯型數據,返回結果為Boolean型,只能為True或False。
5、VBA中的通配符
6、運算符優先級
在VBA中要優先處理蒜素運算符,接着處理連接運算符,然后處理比較運算符,最后再處理邏輯運算符,可以用括號來改變運算順序。
7、換行符
VBA中字符換行顯示需要使用換行符來完成。下面是常用的換行符 'chr(10) 可以生成換行符 'chr(13) 可以生成回車符 'vbcrlf 換行符和回車符 'vbCr 等同於chr(10) 'vblf 等同於chr(13) '例: Sub test3() MsgBox "我愛" & Chr(10) & "Excel" ' MsgBox "我愛你" & Chr(13) & "Excel" ' MsgBox "今天" & vbCrLf & "我是大王" End Sub
六、VBA內置函數
使用VBA中內置函數與在工作表中使用工作表函數類似。
例如,我們想知道當前系統時間
Sub NowTime() MsgBox "現在的時間是:" & Time() End Sub
VBA中的內置函數有哪些?查看VBA內置函數的方法:
1、在VBE中“幫助(H)”——“Microsoft Visual Basic 幫助(H) F1”——“Visual Basic 語言參考”——“函數” 或者在VBE下快捷鍵“F1”
地址:https://docs.microsoft.com/zh-cn/office/vba/language/reference/functions-visual-basic-for-applications
2、在VBE代碼窗口中首先鍵入“VBA.”系統會自動提示“函數列表”,如圖
七、VBA控制結構
1、If…Then語句
Sub SayHello1() If Time < 0.5 Then MsgBox "早上好!" If Time >= 0.5 Then MsgBox "下午好!" End Sub Sub SayHello2() If Time < 0.5 Then MsgBox "早上好!" Else MsgBox "下午好!" End If End Sub Sub SayHello3() If Time < 0.5 Then MsgBox "早上好!" ElseIf Time > 0.75 Then MsgBox "晚上好!" Else MsgBox "下午好!" End If End Sub
2、Select Case語句
Sub SayHello1() Select Case Time Case Is < 0.5 MsgBox "早上好!" Case Is > 0.75 MsgBox "晚上!" End Select End Sub Sub SayHello2() Select Case Time Case Is < 0.5 MsgBox "早上好!" Case Is > 0.75 MsgBox "晚上!" Case Else MsgBox "下午好!" End Select End Sub
Sub xingji() Dim xj As String Select Case Cells(2, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(2, "I") = xj End Sub
3、For…Next語句
語法結構:
For <循環變量>=<初值>To<終值> [Step 步長值] <循環體> [Exit For] '可以在循環體中任意處加一句或多句Exit For,當遇到這個語句,退出For循環,執行Next后語句 <循環體> Next [循環變量]
Sub xingji() Dim xj As String, i As Integer For i = 2 To 19 Step 1 Select Case Cells(i, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(i, "I") = xj Next i End Sub
4、Do While語句
- 語法結構1:
Do [While 邏輯表達式] <循環體> [Exit Do] [循環體] Loop
對應示例:
Sub xingji() Dim xj As String, i As Integer i = 2 Do While Cells(i, "H") <> "" Select Case Cells(i, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(i, "I") = xj i = i + 1 Loop End Sub
- 語法結構2
Do <循環體> [Exit Do] [循環體] Loop [While 邏輯表達式]
對應示例:
Sub xingji() Dim xj As String, i As Integer i = 2 Do Select Case Cells(i, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(i, "I") = xj i = i + 1 Loop While Cells(i, "H") <> "" End Sub
5、Do Until語句
do Until 后的邏輯表達式為False則執行循環體,否則退出循環,跟Do While相反。
- 語法結構1:
Do [Until 邏輯表達式] <循環體> [Exit Do] [循環體] Loop
對應示例:
Sub xingji() Dim xj As String, i As Integer i = 2 Do Until Cells(i, "H") = "" Select Case Cells(i, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(i, "I") = xj i = i + 1 Loop End Sub
- 語法結構2:
Do <循環體> [Exit Do] [循環體] Loop [Until 邏輯表達式]
對應示例:
Sub xingji() Dim xj As String, i As Integer i = 2 Do Select Case Cells(i, "H") Case Is < 85 xj = "不評定" Case Is < 100 xj = "一星級" Case Is < 115 xj = "二星級" Case Is < 130 xj = "三星級" Case Is < 150 xj = "四星級" Case Else xj = "五星級" End Select Cells(i, "I") = xj i = i + 1 Loop Until Cells(i, "H") = "" End Sub
6、For Each…Next語句
當前活動工作簿中有許多工作表,但並不知道數量。如果要把所有工作表的名稱按次序寫入活動工作表的A列,For Each…Next是更適合的循環。
For Each 元素變量 In 集合名稱或數組名稱 <語句塊1> [Exit For] [語句塊2] Next [元素變量]
示例1:
Sub shtName() Dim sht As Worksheet, i As Integer i = 1 For Each sht In Worksheets Cells(i, "A") = sht.Name i = i + 1 Next sht End Sub
示例2:
Sub shtName() Dim c As Range, i As Integer i = 1 For Each c In Range("A1:A10") c.Value = i i = i + 1 Next c End Sub
7、GoTo語句
“去到指定地點”,用來讓程序轉到另外一條語句去執行。
Sub he() Dim mysum As Long, i As String i = 1 x: mysum = mysum + i i = i + 1 If i <= 100 Then GoTo x MsgBox "1到100的自然數和是:" & mysun End Sub
8、With語句
當需要對相同的對象進行多次操作時,會編寫一些重復代碼
Sub FontSet() With Worksheets("sheet1").Range("A1").Font .Name = "仿宋" .Size = 12 .Bold = True .ColorIndex = 3 End With '這里的With語句結束標志,不可缺少 End Sub
八、過程Sub
1、Sub定義語句
聲明sub過程的規范語句
'所有[]內容都是可選的 'Exit Sub:可選語句,執行它將中斷執行並退出過程 '如果選用Static,運行程序的過程中將保存該過程里聲明的本地變量 'Private和Public用於聲明過程的作用域名,如果省略,過程默認為公共過程 [Private|Public][Static] Sub 過程名([參數列表]) [語句塊] [Exit Sub] [語句塊] End Sub
2、Sub間調用
被調用過程定義:
Sub SayHello() If Time < 0.5 Then MsgBox "早上好!" ElseIf Time > 0.75 Then MsgBox "晚上好!" Else MsgBox "下午好!" End If End Sub
方法一:過程名[參數1,參數2…]
Sub RunSub() SayHello End Sub
帶參數調用
Sub PrintInfo(info) MsgBox info End Sub Sub RunPara() PrintInfo ("Hello World") End Sub
方法二:Call 過程名[(參數1,參數2…)]
Sub RunSub() Call SayHello End Sub
方法三:利用Application對象的Run方法,Application.Run 表示過程名的字符串(或字符串變量)[,參數1,參數2…]
Sub RunSub() Application.Run "SayHello" End Sub
3、過程的作用域
公共過程:可以跨模塊調用,用Public 或省略不寫。
Public Sub gggc() MsgBox "我是公共過程" End Sub
私有過程:只能在模塊內調用,用Private
Private Sub gggc() MsgBox "我是私有過程" End Sub
九、自定義Function
Function過程也稱為函數過程,編寫一個Function過程,就是編寫一個函數。
1、定義語法格式
'最后必須將結果賦值給函數名稱 [Private|Public][Static] Function 函數名([參數列表])[As 數據類型] [語句塊] [函數名=過程結果] [Exit Function] [語句塊] [函數名=過程結果] End Function
2、定義函數
定義函數:生成1-10之間的隨機整數
Public Function Fun() Fun = Int(Rnd() * 10) + 1 End Function
3、使用函數
- 使用函數方法一:直接在單元格加“=”調用
- 使用函數方法二:通過“函數”——“用戶定義” 選擇
- 用戶定義函數可以和其他函數嵌套使用
- 在VBA過程中使用自定義函數
Sub msg() MsgBox Fun() End Sub
4、函數實例
RGB函數中,R代表紅色,G代表綠色,B代表藍色
RGB(255,255,0) 表示黃色
- 判斷單元格是否是黃色,是則返回1,否則返回0
'最后必須將結果賦值給函數名稱 Function CountColor() If Range("A1").Interior.Color = RGB(255, 255, 0) Then CountColor = 1 '如果是黃色,函數值等於1 Else CountColor = 0 End If End Function
- 統計指定顏色的單元格個數
'最后必須將結果賦值給函數名稱 Function CountColor() Dim rng As Range For Each rng In Range("A1:A10") If rng.Interior.Color = RGB(255, 255, 0) Then CountColor = CountColor + 1 End If Next rng End Function
- 用參數指定計算區域
'最后必須將結果賦值給函數名稱 Function CountColor(arr As Range) Dim rng As Range For Each rng In arr If rng.Interior.Color = RGB(255, 255, 0) Then CountColor = CountColor + 1 End If Next rng End Function
- 給自定義函數第2個參數
'最后必須將結果賦值給函數名稱 Function CountColor(arr As Range, c As Range) Dim rng As Range For Each rng In arr If rng.Interior.Color = c.Interior.Color Then CountColor = CountColor + 1 End If Next rng End Function
- 設置自定義函數為易失性函數
工作表重新計算(按F9重新計算,或重啟工作簿)之后,自定義函數並不會重新計算。
如果將自定義函數設置為易失性函數,無論何時重新計算工作表,函數都會重新計算。
使用命令:Application.Volatile True
'最后必須將結果賦值給函數名稱 Function CountColor(arr As Range, c As Range) Application.Volatile True Dim rng As Range For Each rng In arr If rng.Interior.Color = c.Interior.Color Then CountColor = CountColor + 1 End If Next rng End Function
十、代碼美化
合理縮進:tab
取消縮進:Shift+Tab
更改長行代碼為短行代碼,在子句后面輸入一個空格和一個下划線(_),然后換行,這就把一行代碼分成兩行。
Sub test() Application.Workbooks("Book1").Worksheets("sheet1") _ .Range("A1:D100").Font.Bold = True End Sub
把多行合並為一行,在第一行代碼后加上英文冒號(:),可以接着寫第二行代碼
Sub test() Dim a%, b%, c%: a = 1: b = 2: c = 3 End Sub
注釋:用英文單引號(')表示后面的語句為注釋
注釋Rem:用Rem注釋只能注釋一整行,注釋行不能有代碼邏輯
Sub test() '=================注釋 Application.Workbooks("Book1").Worksheets("sheet1") _ .Range("A1:D100").Font.Bold = True Rem ==============注釋 End Sub
批量注釋:在VBE窗口中,“視圖”——“工具”——“編輯”——“設置注釋塊” 【或解除注釋塊】
十一、VBE其他設置
自動列出成員設置:VBE下“工具”——“選項”——“編輯器”選項卡下——“自動列出成員”