控制语句

第十篇、VBA核心控制语句(一):条件判断和循环

  接上一篇:操控顶级对象Application(Excel应用程序本身)。①通过改变获取到的Excel属性和状态值,达到控制Excel显示和行为的目的;②和用户的交互;③调用内置函数、高效执行特定的计算;④Application级别的事件所能完成工作,是我们通篇介绍的概括。

  至此,对Excel_VBA的核心对象(第6至9篇)这些个枯燥知识的学习,已经完成了100%。

对于VBA知识的学习过程,每个人的学习路径多多少少会有不同,有的从宏录制开始、有的从认识变量和对象开始、有从基础语法开始、还有的“有基础编程知识”、了解VBA这种语言类型后就立刻能上手的,毕竟编程的底层逻辑和通用概念是相通的。但完整的知识点,都逃不脱对VBA特有的对象模型(Excel的Range、Sheet、Workbook)特点的熟练掌握,认识对象枯燥但不可或缺!

  对Excel_VBA可操控的关键对象学习后,能不能用代码操控它们完成对数据的自动化整理工作呢?答案是:可以!这时你可以自动化操作的内容包括但不限于:选取工作簿、打开工作簿、从工作表取值、单元格计算、数据汇总等等。

  但是想想觉得现在能做的,觉得又缺少点什么?是程序没有思考、不会判断、没有逻辑!如果遇到有选择性获取分析结果时该怎么办?或者说是遇到了情况A就想让它这样执行、遇到了情况B就让它那样执行,这样该如何处理?

  好比微信支付输入了支付密码,如果密码错误了就提醒并清空密码重新输入,如果输入正确但余额不足会提醒是否更改银行卡,如果6位数密码只输入5位一直停留在当前页面啥也不做!

  这就相当于给了程序一个控制,运行时按照某项条件,指引它应该往某个方向去执行!

  任何的编程语言也都离不开控制语句(流程控制),基础编程概念如变量、循环、条件语句这些,在编程语言中几乎是相通用的。VBA作为一种程序语言也不例外,它核心控制语句包括:条件判断、循环执行、错误处理、程序跳转。循环执行我们在第三篇🔗3、了解基础编程知识:循环和第四篇🔗4、其他循环结构>已经做了详细的阐述和示例,也就不再重复。

  接下来的两个篇幅认识条件判断错误处理及程序跳转,它们相对于“对象类型”就显得不那么繁杂,但是应用更加的灵活,各种嵌套应用组合在一起能产生巨大的能量。

  对于编程知识零基础的人,接下来的内容建议阅读和练习同步,手敲代码的同时也思考有无其它方法完成同样的结果!通过VBA学习到的编程基础、逻辑思维和调试经验,如果以后有机会接触其他编程语言,也会有帮助。

本篇视频:

|01 条件判断语句

  条件控制语句主要用于根据不同的条件执行不同的代码分支,核心结构包括If...Then...Else和Select Case,它们理解起来并不复杂。

1-1 If...Then...Else: 用于单条件或多条件判断,支持嵌套和分支扩展

  它理解起来较为简单,if如果满足条件Then就执行代码块1Else否则执行代码块2

  语句有三种使用方式,适用不同的场景。

示例:

  用一个班级评比的示例来演示三种方式

背景:
  • 小学五年级的期末考试,依据语文、数学、英语的成绩和课堂纪律来选择“单科优秀奖”“和“学习小状元奖”;
  • 依据三科的平均分值对每个学生做综合评价“优秀、良好、需要加油、努力赶上”。
条件:
  • “单科优秀奖”评价条件:“语文成绩≥90、数学成绩≥95、英语成≥93”;
  • “学习小状元“评价条件:课堂纪律是“好”且平均分高于80分,其他的需要平均分高于85分;
  • 综合评价:平均分≥90“优秀”,≥75“良好”,≥60“需要加油”,不及格“努力赶上”。
需求:
  • 将“单科优秀奖”的人员名单和单科成绩,复到一个新的工作表中;
  • 将“学习小状元“的人员名单和各课成绩,复制到一个新工作表中内,增加平均值列;
  • 在原本中,增加一列”综合评价“,把评价结果填写到对应的行。
样式:
点击放大的图片
代码:
复制成功!
1

Sub 期末成绩分析()
    '评价期末成绩,列出“单科优秀奖”和“学习小状元”人员名单,按照平均分对学生评价
    '声明五个变量
    Dim name_max As Long  '存储原表行数
    Dim name_i As Long    '存储循环值

    Dim yw_index As Long  '存储符合条件的语文成绩数
    Dim sx_index As Long
    Dim yy_index As Long
    Dim pj_index As Long

    name_max = ThisWorkbook.Worksheets("五一班期末成绩").UsedRange.Rows.Count() '成绩表末行的行数

    '先增加一个新表,重命名为“单科优秀奖”
    Dim new_sheet As Worksheet
    Set new_sheet = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    new_sheet.Name = "单科优秀奖"
    '重复执行一次,新表命名为“”
    Set new_sheet = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    new_sheet.Name = "学习小状元"

    '新表中增加标题字段
    Worksheets("单科优秀奖").Range("A1").Value = "姓名"  '单个单元格赋值
    Worksheets("单科优秀奖").Range("B1").Value = "语文优秀"
    Worksheets("单科优秀奖").Range("D1:E1") = Array("姓名", "数学优秀") '数组方法赋值
    Worksheets("单科优秀奖").Range("G1:H1") = Array("姓名", "英语优秀")
    Worksheets("学习小状元").Range("A1:F1") = Array("姓名", "语文", "数学", "英语", "课堂表现", "平均分")

    yw_index = 2 '目标表都是从第二行开始填写内容
    sx_index = 2
    yy_index = 2
    pj_index = 2

    '循环学生成绩
    For name_i = 2 To name_max
    '单科优秀奖-----------------------------------------------------------------------------------------------------
    '简单条件的用法
        If Worksheets("五一班期末成绩").Cells(name_i, 2).Value >= 90 Then  '如果满足条件,即成绩大于等于90分时,执行语句
            Worksheets("单科优秀奖").Cells(yw_index, 1).Value = Worksheets("五一班期末成绩").Cells(name_i, 1).Value '原表的“姓名”,赋值到目标表的目标单元格,和copy功能相仿
            Worksheets("单科优秀奖").Cells(yw_index, 2).Value = Worksheets("五一班期末成绩").Cells(name_i, 2).Value '接着是成绩
            yw_index = yw_index + 1  '每符合一次,存储的变量值增加1
        Else '不满足条件时执行的语句,  注意Else有无均可,没有就表示“如果没有符合条件的值,则什么也不做”
            Worksheets("五一班期末成绩").Cells(name_i, 2).Interior.Color = RGB(155, 155, 155)
        End If 'end if结束判断

        '第二个是数学成绩,换一个用copy的方法
        If Worksheets("五一班期末成绩").Cells(name_i, 3).Value >= 95 Then
            Worksheets("五一班期末成绩").Cells(name_i, 1).Copy Destination:=Worksheets("单科优秀奖").Cells(sx_index, 4)
            Worksheets("五一班期末成绩").Cells(name_i, 3).Copy Destination:=Worksheets("单科优秀奖").Cells(sx_index, 5)
            sx_index = sx_index + 1  '每符合一次,存储的变量值增加1
        End If

        '第三个是英语成绩
        If Worksheets("五一班期末成绩").Cells(name_i, 4).Value >= 93 Then
            Worksheets("五一班期末成绩").Cells(name_i, 1).Copy Destination:=Worksheets("单科优秀奖").Cells(yy_index, 7)
            Worksheets("五一班期末成绩").Cells(name_i, 4).Copy Destination:=Worksheets("单科优秀奖").Cells(yy_index, 8)
            yy_index = yy_index + 1  '每符合一次,存储的变量值增加1
        End If

    '学习小状元-----------------------------------------------------------------------------------------------------
    '嵌套条件的用法
        If Worksheets("五一班期末成绩").Cells(name_i, 5).Value = "好" Then '满足条件1
            If Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i)) >= 80 Then '满足条件2
                Worksheets("五一班期末成绩").Range("A" & name_i & ":E" & name_i).Copy Destination:=Worksheets("学习小状元").Cells(pj_index, 1) '区域单元格的复制和粘贴,只需选择目标单元格区域的首个单元格位置就可以
                Worksheets("学习小状元").Cells(pj_index, 6) = Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i))
                pj_index = pj_index + 1
            End If
        Else
            If Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i)) >= 85 Then
                Worksheets("五一班期末成绩").Range("A" & name_i & ":E" & name_i).Copy Destination:=Worksheets("学习小状元").Cells(pj_index, 1)
                Worksheets("学习小状元").Cells(pj_index, 6) = Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i))
                pj_index = pj_index + 1
            End If
        End If

    '综合评价-----------------------------------------------------------------------------------------------------
    '多个分支(ElseIf)
        If Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i)) >= 90 Then '分支1
            Worksheets("五一班期末成绩").Cells(name_i, 6).Value = "优秀"
        ElseIf Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i)) >= 75 Then '分支2
            Worksheets("五一班期末成绩").Cells(name_i, 6).Value = "良好"
        ElseIf Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i)) >= 60 Then '分支2
            Worksheets("五一班期末成绩").Cells(name_i, 6).Value = "需要加油"
        Else       '最后一个分支
            Worksheets("五一班期末成绩").Cells(name_i, 6).Value = "努力赶上"
        End If
    Next name_i

    Worksheets("五一班期末成绩").Cells(1, 6).Value = "综合评价" '增加一个表头
    End Sub

1-2 Select Case: 多分支选择结构,简化多重条件判断

  和If Then...ElseIf Then...ElseIf Then*...适用于多分支类似,Select Case也同样适用于多分支选择,它常用来替代复杂的if...Elseif链,代码更简洁易读。

基本语法
复制成功!
1

Select Case 测试表达式
    Case 值1
        ' 匹配值1时执行
    Case 值2, 值3
        ' 匹配值2或值3时执行
    Case 值4 To 值5
        ' 值在值4到值5范围内时执行
    Case Is > 值6
        ' 值大于值6时执行
    Case Else
        ' 默认情况
End Select

示例:
  • 仍以小学五年级的期末考试的综合评价为例,看Select Case的使用
复制成功!
1

Sub 综合评价_Select_case()

    Dim name_max As Long  '存储原表行数
    Dim name_i As Long    '存储循环值

    Dim pj_index As Long

    name_max = ThisWorkbook.Worksheets("五一班期末成绩").UsedRange.Rows.Count() '成绩表末行的行数


    For name_i = 2 To name_max
        'select case 替代 if...elseif,更简洁易读
        Select Case Application.WorksheetFunction.Average(Worksheets("五一班期末成绩").Range("B" & name_i & ":D" & name_i))
            Case Is >= 90
                Worksheets("五一班期末成绩").Cells(name_i, 7).Value = "优秀"
            Case 75 To 90
                Worksheets("五一班期末成绩").Cells(name_i, 7).Value = "良好"
            Case Is >= 60
                Worksheets("五一班期末成绩").Cells(name_i, 7).Value = "需要加油"
            Case Else
                Worksheets("五一班期末成绩").Cells(name_i, 7).Value = "努力赶上"
        End Select

        'select case 多值匹配
        Select Case Worksheets("五一班期末成绩").Cells(name_i, 1).Value
            Case "张雅婷", "杨文嘉"
                Worksheets("五一班期末成绩").Cells(name_i, 1).Interior.Color = RGB(155, 155, 155)
        End Select

    Next name_i

    Worksheets("五一班期末成绩").Cells(1, 7).Value = "综合评价_select方法" '增加一个表头

End Sub

  既然If...ElseIfSelect Case的使用场景类型,可以相互替代,但是要知道,同一个程序语言中不会创造出来两个不同的语句实现共一个功能,它俩之间肯定是有差别的。

下一篇:VBA核心控制语句二:错误处理和程序跳转

   条件判断和循环的套用,让程序执行变得不在是从第一句一行行执行到最后一句,而是随着条件的不同有取舍的执行,代码显得高效和富有逻辑些!

  想想日常工作,是每件事情一旦开始了就都必须要从头做到尾吗?无论过程怎样都要把预先设定的工作流程完整执行一遍吗?

  接到任务去A地参加会议,如果发现重要文件没带上是不是就得立刻终止前进?导航到A结果走到半路接到通知地点变更到B,是不是得立刻结束当前导航重新将目的地切换到B。

  这就和程序执行的问题一样,当发现某个问题(错误或者缺失等)时如何处理。也就是我们下一篇所要了解的:错误处理和跳转

  下一篇了解控制语句(二):错误处理和程序跳转。

请开发者喝杯咖啡 请开发者喝杯咖啡!