VBA编程基础2:处理对象和过程控制
处理对象和集合
VBA编程要在处理对象和集合方面花费大量时间。VBA提供了两个重要的结构,可以简化对象和集合的处理。
With-End With结构
With-End With结构适用于对单个对象执行多项操作,可提高执行速度。在录制VBA宏时,Excel一旦有机会就会使用With-End With结构。以下两段代码等效:
Sub ChangeFont1()
Selection.Font.Name = "仿宋"
Selection.Font.Bold = True
Selection.Font.Italic = True
Selection.Font.Size = 14
Selection.Font.Underline = xlUnderlineStyleSingle
Selection.Font.ThemeColor= xlThemeColorAccentl
End Sub
Sub ChangeFont2()
With Selection.Font
.Name = "仿宋"
.Bold = True
.Italic = True
.Size = 14
.Underline = xlUnderlineStyleSingle
.ThemeColor= xlThemeColorAccentl
End With
End Sub
For Each-Next结构
“集合”是一组相关的对象。假设要在集合的所有对象上执行某个动作,或要对集合的所有对象求值并在特定条件下采取动作,这些都是使用For Each-Next结构的好机会。使用For Each-Next机构时,不必知道集合中有多少个元素。
For Each-Next结构的语法如下("[]"内表示可选,非必须):
For Each element In collection
[代码]
[Exit For] '遍历完所有元素之前可以退出循环
[代码]
Next element
以下为示例:
Sub CountSheets()
'显示打开的工作表名称
Dim Item as Worksheet
For Each Item In ActiveWorkbook.Worksheets
MsgBox Item.Name
Next Item
End Sub
Sub ToUpper()
'把选中的单元格内容转换为大写
Dim Cell As Range
Dim Cnt as Integer
Cnt = 0
For Each Cell In Selection
Cell.Value = UCase(Cell.Value)
Cnt = Cnt + 1
Next Cell
MsgBox "已完成所选" & Cnt & "个单元格内容转换。"
End Sub
Sub FirstNegative()
'找到并选中A1:A10区域第1个负数
Dim Cell As Range
For Each Cell In Range("A1:A10")
If Cell.Value < 0 Then
'如果单元格中为负值,则选中并结束循环
Cell.Select
Exit For
End If
Next Cell
End Sub
控制代码执行过程
VBA过程中需要控制代码的执行过程(流程),通过跳过某些语句、多次执行某些语句或通过测试条件决定接下来做什么。上面的For Each-Next结构是一种循环结构,除此之外,VBA主要还有以下流程控制结构:
- If-Then 分支结构
- Select Case 分支结构
- For-Next 循环结构
- Do While 循环结构
- Do Until 循环结构
- GoTo 跳转语句
If-Then分支结构
通过分支结构赋予程序决策能力,好的分支结构是成功编程的关键。If-Then分支机构用于有条件的执行一条或多条语句,Else子句可选,若包含Else子句,那么当测试条件不是True时,Else子句执行一条或多条语句。
单行语句示例:
If Time < 0.5 Then MsgBox "早上好!"
If Time < 0.5 Then MsgBox "早上好!" Else _
MsgBox "下午好!"
多行语句示例:
If Time < 0.5 Then
MsgBox "早上好!"
' 多行语句
End If
If Time < 0.5 Then
MsgBox "早上好!"
' 多行语句
Else
MsgBox "下午好!"
' 多行语句
End If
If Time < 0.5 Then
MsgBox "早上好!"
ElseIF Time >=0.5 And Time < 0.75 Then
MsgBox "下午好!"
Else
MsgBox "晚上好!"
End If
If Time < 0.5 Then
MsgBox "早上好!"
Else
IF Time >=0.5 And Time < 0.75 Then
MsgBox "下午好!"
Else
MsgBox "晚上好!"
End If
End If
Select Case分支结构
在三个或多个选项之间做出选择时,Select Case结构很有用处,他是If-Then-Else结构很好的替代。
例如:
Sub GreetMe()
Dim Msg As String
Select Case Time
Case Is < 0.5
Msg = "早上好!"
Case 0.5 To 0.75
Msg = "下午好!"
Case Else
Msg = "晚上好!"
End Select
MsgBox Msg
End Sub
Sub GreetMe2()
Select Case Weekday(Now)
Case 2, 3, 4, 5, 6
MsgBox "今天是工作日!"
Case Else
MsgBox "周末愉快!"
End Select
End Sub
Sub GreetMe3()
Select Case Weekday(Now)
Case 2 To 6
MsgBox "今天是工作日!"
Case Else
MsgBox "周末愉快!"
End Select
End Sub
如果每个情况下只有一句指令,可以(通过VBA语句分隔符:冒号)把指令和关键字Case放在同一行,使代码更简洁:
Sub GreetMe3()
Select Case Weekday(Now)
Case 2 To 6 : MsgBox "今天是工作日!"
Case Else : MsgBox "周末愉快!"
End Select
End Sub
For-Next循环结构(计数循环)
For-Next循环结构是最简单的一种循环。语法如下("[]"内表示可选,非必须):
For counter = start To end [Step stepval]
[代码]
[Exit For]
[代码]
Next counter
示例:
Sub SumSquareRoots()
'求前100个数的平方根总和
Dim Sum As Double
Dim Count As Integer
Sum = 0
For Count = 1 To 100
Sum = Sum + Sqr(Count)
Next Count
MsgBox Sum
End Sub
Sub DeleteRows()
' 删除单元格行
Dim RowNum As Long
For RowNum = 10 To 2 Step -2
Rows(RowNum).Delete
Next RowNum
End Sub
Sub NestedLoops()
' 循环嵌套
Dim MyArray(1 to 10, 1 to 10, 1 to 10)
Dim i As Integer, j As Integer, k As Integer
For i = 1 To 10
For j = 1 To 10
For k = 1 To 10
MyArray(i, j, k) = 1
Next k
Next j
Next i
End Sub
Do While循环结构(条件循环)
Do While循环是VBA中另一种循环结构,只有在满足指定条件时才会执行Do While循环。Do While循环有两种语法结构,如下("[]"内表示可选,非必须):
Do [While condition]
[代码]
[Exit Do]
[代码]
Loop
'或者
Do
[代码]
[Exit Do]
[代码]
Loop [While condition]
示例:
Sub EnterDate1()
' Do While, with test at the beginning
Dim TheDate As Date
TheDate = DateSerial(Year(Date),Month(Date),1)
Do While Month(TheDate) = Month(Date)
ActiveCell = TheDate
TheDate = TheDate + 1
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
Do Until循环结构(条件循环)
Do Until循环结构与Do While结构非常类似。Do Until一直执行循环,直到测试条件为True时结束循环。Do Until也有两种语法格式("[]"内表示可选,非必须):
Do [Until condition]
[代码]
[Exit Do]
[代码]
Loop
'或者
Do
[代码]
[Exit Do]
[代码]
Loop [Until condition]
示例:
Sub EnterDate2()
' Do Until, with test at the beginning
Dim TheDate As Date
TheDate = DateSerial(Year(Date),Month(Date),1)
Do Until Month(TheDate) <> Month(Date)
ActiveCell = TheDate
TheDate = TheDate + 1
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
GoTo 跳转语句
改变流程最直接的方式是使用GoTo语句,该语句只是将程序的执行转移到一条新的指令,必须要有标签标识此指令(带冒号的文本字符串货不带冒号的数字)。VBA过程可以包含任意数量的标签,但是GoTo语句不能转移到过程之外的指令。
一般只有没其它办法时才使用GoTo语句。除非进行错误处理,否则不建议使用GoTo语句。示例:
Sub GoToDemo()
UserName = InputBox("请输入用户名:")
If UserName <> "哎喂可乐" Then GoTo WrongName
MsgBox ("欢迎哎喂可乐……")
'更多代码
Exit Sub
Wrong Name:
MsgBox "抱歉,只有哎喂可乐可以执行此程序。"
End Sub