710 likes | 865 Views
数据库应用基础. 第 15 章 VBA 程序设计基础. 第 15 章 VBA 程序设计基础. 15.1 顺序结构程序设计. 所谓顺序结构,是指代码中包含的一组语句,这些语句将按其在代码中的排列逐个顺序执行。 此类语句的特点是无论在代码中的何处出现,总是按排列顺序依次执行。 注释语句、赋值语句、过程调用语句等都属于这类语句。. 15.1 顺序结构程序设计. 语句通常都包含在过程内部,一般情况下,一行写一条语句,但 VBA 允许以下两种例外情况: 一行写多条语句:如果语句较短,可以在一行写上多条语句,这时要求各语句之间用 “ : ” 隔开;
E N D
数据库应用基础 第15章 VBA程序设计基础
15.1 顺序结构程序设计 • 所谓顺序结构,是指代码中包含的一组语句,这些语句将按其在代码中的排列逐个顺序执行。 • 此类语句的特点是无论在代码中的何处出现,总是按排列顺序依次执行。 • 注释语句、赋值语句、过程调用语句等都属于这类语句。
15.1 顺序结构程序设计 • 语句通常都包含在过程内部,一般情况下,一行写一条语句,但VBA允许以下两种例外情况: • 一行写多条语句:如果语句较短,可以在一行写上多条语句,这时要求各语句之间用“:”隔开; • 一条语句写在多行上:如果语句较长,一行写不下时,可以使用续行符“_”(一个空格字符加上一个下划线字符)。这时在这条语句需要换行的地方写放上一个续行符然后再回车换行。 • 例如: X=5 : y=6 Z=Left(“中华人民共和国”,1) & Right(“中华人民共和国”,1)& _ Mid(“中华人民共和国”,3,2)
15.1.2 赋值语句 • 赋值语句可以将一个表达式的值赋给一个变量、对象的属性。 • 赋值给变量 • <变量名>=<表达式> • 例如: Total = 101 A = 36 + Total/2 ReadOut = "GoodMornig!“ A=10 : B=15 : A=A+B : B=A+B A=10 : B=15 :T=A : A=B : B=T
15.1.2 赋值语句 • 赋值给对象的属性 • Access建立的数据库对象及其属性,均可以看作VBA程序代码中的变量来加以引用。 • 在VBA中,对Access窗体与报表对象的引用格式分别为: [Forms!窗体名称!]控件名称[.属性名称] [Reports!报表名称!]控件名称[.属性名称] • 例如: lblZm.Caption = "字母字符的个数为:" & Str(zm) lblSds.Caption = "应缴个人所得税:" & Str(jssds(ysr)) & "元"
15.1.3 输入对话框 • 当应用程序需要从用户那里取得数据,以便进行下一步的处理时,则需要用到输入对话框。 • 输入对话框是由InputBox函数实现的,其格式如下: • InputBox(<信息内容>[,<对话框标题>][,<默认内容>]) • 使用该函数可以产生一个用于输入数据的对话框,等待用户输入数据。当用户输入完数据并点击了确定按钮时,关闭对话框并返回输入的内容。该内容通常赋给一个接收数据的变量。
15.1.3 输入对话框 • 当应用程序需要从用户那里取得数据,以便进行下一步的处理时,则需要用到输入对话框。 • 输入对话框是由InputBox函数实现的,其格式如下: • InputBox(<信息内容>[,<对话框标题>][,<默认内容>]) • 使用该函数可以产生一个用于输入数据的对话框,等待用户输入数据。当用户输入完数据并点击了确定按钮时,关闭对话框并返回输入的内容。该内容通常赋给一个接收数据的变量。
15.1.3 输入对话框 • 其中,函数的第一个参数<信息内容>是必须的,其他参数是可选的。 • 信息内容:是一个字符串,基本长度不超过255个字符。它是在对话框内显示的信息,用来提示用户。 • 对话框标题:是一个字符串,作为对话框的标题显示在对话框顶部的标题区。 • 默认内容:是一个字符串,可用此缺省字符串作为输入值。如果用户不想用这个缺省字符串作为输入值,可在输入区直接键入数据,以取代缺省值。如果省略该参数,则对话框的输入区为空白,等待用户键入信息。
15.1.3 输入对话框 • Msg=InputBox("请输入你的名字","Hi","Name")
15.1.4 消息对话框(MsgBox) • 消息对话框主要由一条文字消息和若干按钮组成,用来向用户传达信息,不需要用户输入数据,但可以获取用户的判断或选择结果。 • 消息对话框可以使用函数和语句两种方式来实现。 • MsgBox函数 • MsgBox语句
15.1.4 消息对话框(MsgBox) • MsgBox函数的格式为: • MsgBox(<信息内容>[,<对话框类型>[,<对话框标题>]]) • 例: X=MsgBox(“你完成了本章作业吗?“,4,“请回答“) 类型参数的组成原则是从每一类中选择一个值,把这几个值加在一起就是对话框类型的值。不同的组合会有不同的结果。 例如:35=3+32+0,则显示“是”、“否”、“取消”三个命令按钮(3)及“?”图标(32),默认活动按钮为Yes(0)。
15.1.4 消息对话框(MsgBox) • msg=MsgBox("请确定此数据是否正确!",3+48+0,"数据检查“) • MsgBox函数的返回值是一个整数,这个整数与所选择的命令按钮有关。返回值情况为:1,确定;2,取消;3,终止;4,重试;5,忽略;6,是;7,否。
15.1.4 消息对话框 • MsgBox语句 • MsgBox <信息内容> [,<对话框类型> [,<对话框标题>]] • MsgBox语句与MsgBox函数的功能类似,最主要的差别是MsgBox语句仅仅用于向用户显示一个信息,所以MsgBox语句一般只有一个“确定”按钮,用来告诉用户某一信息,只要用户知道即可,不需要用户做出任何选择。
15.2 分支结构程序设计 • VBA中提供了用于选择、判断的程序控制结构,该结构可以根据给出的条件有选择的执行某些语句。 • 这种结构也叫分支结构。 ?
是 否 C S2 S1 15.2 分支结构程序设计 • 双分支结构,采用一个条件控制两个分支。 • 该结构执行时,首先判断条件C是否成立,如果成立执行S1,否则执行S2。
是 C 否 S1 15.2 分支结构程序设计 • 单分支结构,一个条件控制一个分支。 • 该结构执行时,首先判断条件C是否成立,如果成立执行S1,否则什么也不做。
是 C1 是 C2 否 是 C3 否 … Sn S3 S2 S1 … 否 15.2 分支结构程序设计 • 多分支结构,共计有n-1个条件,n个分支。 • 需要特别注意的是,多分支结构的n个分支,最多只会执行其中一个分支,也就是说第i个条件满足,就会执行第i个分支,然后退出当前多分支结构。
15.2.1 IF语句 • 单行IF语句 • 单行IF语句必须写在一行上,不允许分成两行或者多行来写。其语法格式为: • If <条件表达式> Then <语句1> [Else <语句2>] • 该语句中的<条件表达式>用以描述判断条件,是一个关系表达式或者逻辑表达式,<条件表达式>的结果为True或者False,分别表示条件成立或不成立。 • 由于只能写在一行上,<语句1>和<语句2>一般都是比较短的简单语句,如赋值语句、输入或输出语句等。
15.2.1 IF语句 • 单行IF语句 • 该语句的执行过程为:对<条件表达式>进行判断,如果取值为True,则执行<语句1>;否则执行<语句2>。然后,执行该条件语句的下一语句。 • 该语句中的Else部分可以省略,此时,如果<条件表达式>取值为True,则执行<语句1>,否则什么也不执行。
15.2.1 IF语句 • 多行IF语句 • 语法结构如下: If <条件表达式> Then <语句序列1> [Else <语句序列2>] End If • 执行该语句时,如果<条件表达式>成立,则执行<语句序列1>中的所有语句,否则执行<语句序列2>中的所有语句。其中,Else部分也是可以缺省的,这时条件语句的作用就是控制<语句序列1>是否执行。
15.2.1 IF语句 • IF结构的嵌套 If <条件表达式1> Then …… If <条件表达式2> Then ′嵌套的IF语句 …… Else …… End If …… Else …… IF <条件表达式3> Then …… Else …… ′嵌套的IF语句 …… End IF
15.2.1 IF语句 • ELSEIF结构 If <条件表达式1> Then <语句序列1> ElseIf <条件表达式2> Then <语句序列2> …… ElseIf <条件表达式n> Then <语句序列n> [Else <语句序列n+1>] End If
15.2.1 IF语句 • 例:编一个程序过程,输入x的值,按下列公式计算并输出y的值。
15.2.1 IF语句 • 解决方法1:嵌套的方案 Sub test1( ) Dim x As Single, y As Single x = InputBox("请输入x的值为:") If x <= 1 Then y = x + 10 Else If x < 10 Then y = Sqr(2 * x ^ 2 + 3) Else y = Log(x) / Log(10) End If MsgBox "经过计算,y的值为:" & y End Sub
15.2.1 IF语句 • 解决方法2:ElseIf结构 Sub test2( ) Dim x As Single, y As Single x = InputBox("请输入x的值为:") If x <= 1 Then y = x + 10 ElseIf x < 10 Then y = Sqr(2 * x ^ 2 + 3) Else y = Log(x) / Log(10) End If MsgBox "经过计算,y的值为:" & y End Sub
15.2.2 Select Case语句 • 当要解决的问题需要进行多次判断,并且每次判断都是基于同一表达式,只是对其值的不同情况加以区分时,可以使用Select Case语句。 Select Case <被测试表达式> Case <表达式列表1> <语句序列1> Case <表达式列表2> <语句序列2> …… Case <表达式列表n> <语句序列n> [Case Else <其他语句序列>] End Select
15.2.2 Select Case语句 • 在该语句中,<被测试表达式>可以是数值表达式、字符串表达式、逻辑表达式,或者日期表达式;而每个Case后面的<表达式列表>,均由一个或多个表达式构成,当存在多个表达式时,各个表达式之间用“,”隔开。 • <表达式列表>中的表达式还支持以下两种特殊形式 • <表达式1> To <表达式2>。用来指定一个可能的取值范围。例如,当被测试表达式为一字符串表达式时,Case "a" To "f",表示其可能的取值为6个小写字母。 • Is <关系运算符> <表达式>。用来指定一个可能的取值关系,例如:Case Is < #1/1/2001#,用于判断日期是否在2001年1月1日前。
15.2.2 Select Case语句 • 例:输入一个年份和月份,输出该月的天数。 Sub test3( ) Dim y As Integer, m As Integer, d As Integer y = InputBox("请输入年份:") m = InputBox("请输入月份:") Select Case m Case 1, 3, 5, 7, 8, 10, 12 d = 31 '大月有31天 Case 4, 6, 9, 11 d = 30 '小月有30天 Case 2 If y Mod 400 = 0 Or y Mod 100 <> 0 And y Mod 4 = 0 Then d = 29 '闰年的2月为29天 Else d = 28 End If End Select MsgBoxStr(y) + "年" + Str(m) + "月有" + Str(d) + "天" End Sub
15.3 循环结构程序设计 • 所谓循环结构就是使得某些代码段重复执行若干次,但显然不能是无数次,应该有一个约束条件,通过这个约束条件可以控制循环的终止,这个约束条件就称之为循环条件。
(1) (1) (2) (2) s (3) (3) 假 P 真 (4) (4) 假 P 真 s 15.3 循环结构程序设计 当型循环结构 直到型循环结构
15.3 循环结构程序设计 (1) S是循环中被重复执行的语句序列,称之为循环体。循环体可以是一条语句,也可以是多条语句。 (2) 当型循环与直到型循环最本质的区别在于:当型循环先判断条件,再执行循环体;而直到型循环先执行循环体再判断条件。 (3) 当型循环的循环体有可能一次都不执行,而直到型循环的循环体至少被执行一次。
15.3.1 Do…Loop循环 • Do…Loop循环的语法形式比较灵活,具体可以概括为以下两种: • 当型循环结构 Do [<While> |<Until> <条件>] [<语句序列1>] [Exit Do] [<语句序列2>] Loop • 直到型循环结构 Do [<语句序列1>] [Exit Do] [<语句序列2>] Loop [<While> |<Until> <条件>]
15.3.1 Do…Loop循环 • 例:编写程序段,计算1~100的平方和。 • Sum = 1×1+2×2+3×3+…+100×100 • 方法一 i = 1 Sum = 0 Do While i <= 100 Sum = Sum + i * i i = i + 1 Loop Debug.Print Sum
15.3.1 Do…Loop循环 • 方法二 i = 1 Sum = 0 Do Until i >100 Sum = Sum + i * i i = i + 1 Loop Debug.Print Sum
15.3.1 Do…Loop循环 • 方法三 i = 1 Sum = 0 Do Sum = Sum + i * i i = i + 1 Loop While i <= 100 Debug.Print Sum
15.3.2 For…Next循环 • For…Next语句称为计数循环语句,如果已知循环将执行的次数,使用For…Next语句比Do…Loop语句更方便。 • For…Next语句的语法格式为: For <循环变量>=<初值> To <终值> [Step <步长>] [<语句序列1>] [Exit For] [<语句序列2>] Next [循环变量]
15.3.2 For…Next循环 • 相关说明如下: • 循环变量,为一数值型变量,通常是一个整型变量,其值作为循环控制的条件。 • 初值、终值,均为数值表达式,用以表示循环变量的变化范围。 • 步长,也是一个数值表达式,用以决定一次循环后循环变量值变化的幅度(增量),其值可以是正数或负数,但不能为0。如果步长为1,可省略“step 1”。 • 在Next后面的循环变量必须与For后面的循环变量相同,也可省去不写。 • Exit For与Do…Loop语句中的Exit Do功能类似,用于退出当前的For…Next循环。
For…Next循环流程图 15.3.2 For…Next循环 Sum=0 For i=1 to 100 Sum=Sum+i*i Next i Debug.Print Sum
15.4 数组 • 数组的目的和其他类型的变量一样,用于保存在内存中的数据。但不同的是:同一个数组拥有多个数组元素,而每个数组元素可以像简单变量那样存储数据,也就是说:同一个数组可以保存多个数据。 • 但VBA中,要求同一个数组的所有数组元素的数据类型都是一致的。所以,简单地说:数组就是同一种数据类型的一组数据的集合。
15.4.1 数组的定义 • 定义数组一般使用Dim语句,其语法格式为: • Dim <数组名>(<下标表>) [As <类型>] [,<数组名>(<下标表>) [As <类型>]……] • 相关说明如下: (1)任何数组都必须有一个名字,数组名的命名规则与变量名相同; (2)下标表中可以说明数组所具有的下标维数及每一维下标的范围,其格式为: [下标1下界 To ] 下标1上界[,[下标2下界 To ] 下标2上界……] (3)类型用于定义数组的元素类型,可以是String,Integer…等标准数据类型,也可以是自定义的数据类型。如果省略类型,默认为Variant。
15.4.1 数组的定义 • Dim语句声明了数组的名字、维数(下标界的个数就是数组维数)、大小以及数组元素的类型。 • 例如: Dim m(1 to 30) As Integer Dim lArray(3,4) As Long • 第一个语句定义了一个名为m的一维数组,具有30个整型元素,下标下界为1,下标上界为30。 • 第二个语句定义了一个名为lArray的二维数组(4行5列),具有20个长整型元素,第一维下标的下界为0,上界为3,第二维下标的下界为0,上界为4。
15.4.1 数组的定义 • 请注意下面两个内容: (1)数组声明中默认的下标下界为0,如果需要也可以指定1作为下标下界的默认值。使用的语句是: Option Base 1 Option Base语句必须放在模块的“通用-声明”段中。 例如,如果模块的“通用-声明”段中有语句: Option Base 1 则上面Dim lArray(3,4) As Long定义的数组,其元素个数就是12而不是20了。 (2)一个语句也可以定义多个数组,各个数组定义之间用逗号分隔。比如,上面的二个语句可以合并为如下一个语句: Dim m(1 to 30) As Integer, lArray(3,4) As Long
15.4.2 数组的访问 • 数组一旦定义,就可以访问其元素,VBA中,数组元素的访问格式为: • <数组名>(<下标值1>[,<下标值2>……] • 对于一维数组,只能有一个下标,对于多维数组,则有多个下标,这时,不同维的下标之间用“,”隔开。但需要注意的是:不论是第几维的下标,都必须在对应维的下标下界和上界范围内,否则将会发生数组下标越界的错误。
15.4.2 数组的访问 • 例:编写过程,定义一个10个元素的整型数组,输入10个元素的值,将其输出在立即窗口中,并找出其中的最大值。 Sub test4( ) Dim a(1 To 10) As Integer Dim i As Integer,Max As Integer For i = 1 To 10 '读入10个元素的值 a(i) = InputBox("请输入数组元素的值:") Next i For i = 1 To 10 '输出10个元素的值 Debug.Print a(i) Next i Max=a(1) ‘找出10个元素中的最大值 For i = 2 To 10 If a(i)>Max Then Max=a(i) Next i Debug.Print "数组中的最大值:", Max End Sub
15.5.1过程定义 • VBA中的过程包括两类: • 子程序(Sub)过程: 一般是完成一系列的操作,没有返回值。 • 函数(Function)过程: 有一个返回值。 • 过程必须先定义后调用,也就是说调用一个过程前一定要先定义这个过程。 • 定义过程实际上就是对过程调用的形式进行约定,对过程的功能进行详细地说明和实现。
15.5.1过程定义 • 子程序过程的定义格式 [Private|Public] [Static] Sub <过程名> [ (<参数表>)] [<语句块>] [Exit sub] [<语句块>] End Sub
15.5.1过程定义 • 函数过程的定义格式 [Private|Public][Static] Function<函数名>[ (<参数表>)] [As<类型>] [<语句块>] [<函数名>=<表达式>] [Exit Function] [<语句块>] [<函数名>=<表达式>] End Function
15.5.1过程定义 • 过程定义的说明 • 在过程定义中,如果使用Private关键字,则这个过程只能在定义该过程的模块中调用;如果使用Public定义,则该过程可以在整个应用程序中调用。定义过程时如果使用了Static关键字,则该过程中的所有变量都成为静态变量。 • 子程序过程的功能通常是实现一个特定的操作,比如排序、打印等。而函数过程的功能为获取一个函数值,所以函数过程定义的首行相对于子程序过程多了个可选项“As<类型>”,该项用于说明该函数返回值的数据类型。函数返回值的数据类型,可以是任意VBA数据类型,包括自定义类型。