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

系列:
VBA编程基础1:注释、变量、数据类型、赋值运算
VBA编程基础2:处理对象和过程控制

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 可以通过在属性窗口设置名称来给对象重新命名,名字可以由字母、汉字(2字符)、数字以及下划线组成,但必须以字母或汉字...
    重头再来0706阅读 2,161评论 0 1
  • 公司位于上海市徐汇区飞洲国际广场, 地铁1/ 3/ 4/ 9号线均可到达。薪资待遇可面议,公司环境优雅静谧,vie...
    付简阅读 267评论 0 0
  • 序章 加害你的,也必保护你。 黑暗就是你的蜡烛。 你的边界,就是你追寻的起点。——鲁米 海市的夏天,空气潮湿闷热,...
    章非阅读 761评论 0 2
  • 晚上看到《中国式关系》中古奶奶去世,马国梁说的一番话,想起了小时候的外婆。外婆因为意外,已经离开了18年,有人说1...
    苦行僧_李政阅读 342评论 0 0
  • 今天,上午接到老婆的电话,说儿子在学校又有大瞌睡的行为,当时我听到这个事消息以后,我就在想,怎样改变孩子的做作业的...
    江力群阅读 186评论 0 0