VBA编程教程(基础二)

VBA基础教程

VBA简介

VBAVisual Basic For Appilication,属于VB语言的的子集。

VBA环境简单介绍

无论打开多少EXCEL表格,都会共享一个IDE环境。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQ9eAzWe-1615651551095)(images/VBA基础教程一/打开VB_IDE.gif)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZwXdBfam-1615651551097)(images/VBA基础教程一/image-20210227175708925.png)]
每一个Excel文件,对应的VBA工程都有4类对象,包括: Microsoft Excel对象、窗体、模块和类模块。

Microsoft Excel对象 Microsoft Excel对象代表了Excel文件及其包括的工作薄等几个对象,包括所有的 Sheet和一个Workbook,分别表示文件(工作薄)中所有的工作表(包括图表),例如缺省情况下,Excel文件包括3个Sheet,在资源管理器窗口就包括3个 Sheet,名字分别是各Sheet的名字。

ThisWorkbook 代表当前Excel文件。双击这些对象会打开代码窗口,在此窗口中可输入相关的代码,响应工作薄或者文件的一些事件,例如文件的打开、关闭,工作薄的激活、内容修改、选择等有关事件。

窗体 窗体对象代表了自定义对话框或界面。

模块 模块为自定义代码的载体。作用:1.保存过程和函数 2.定义模块内的私有变量或者整个工程的公有变量。

类模块 类模块则是以类或对象的方式编写代码的载体。

第一个代码

插入一个模块,写上如下代码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fZah1rmT-1615651551099)(images/VBA基础教程一/image-20210227181814339.png)]

Sub MyFirstVBAProgram()
    Dim strName As String
    Dim strHello As String
    strName = InputBox("请输入你的名字:")
    strHello = "你好," & strName & " !"
    MsgBox strHello
End Sub
----------------
解释:下面我们简单看一下这段代码的组成,代码第1行表示这是一个新的过程,名称为“MyFirstVBAProgram",第2、3行定义了2个变量,其类型为字符串类型,第4行调用InputBox这个内置函数,并将返回值赋给strName这个变量,第5行将几个字符串组合成一个新的字符串,第6行调用MsgBox这个函数,显示一个对话框,第7行表示过程结束。VBA程序由不同的模块组成,在模块内部,可以定义不同的变量、过程或函数,由此组成一个完整的程序。

与其他程序设计语言不同,VBA程序是事件驱动的,没有Main函数之类的入口的概念。本质上,VBA代码应该只是一些完成具体工作的集合,而通过界面元素或者Excel的事件驱动执行,你可以通过自定义按钮、菜单,并指定一个宏(VBA过程,自定义界面也可以通过编程手段完成此类工作),通过单击此按钮即可调用相应的VBA代码。

过程

过程是最基本的运行单位,格式如下:

Sub Test()
  ...
End Sub	

------------
[ Private | Public][Static ] Sub name [ (arglist) ]
[ statements]
[Exit sub]
[ statements]
    
 End sub

部分描述
Public可选的。表示所有模块的所有其它过程都可访问这个Sub过程。如果在包含Option Private的模块中使用,则这个过程在该工程外是不可使用的。
Private可选的。表示只有在包含其声明的模块中的其它过程可以访问该Sub过程。
Static可选的。表示在调用之间保留Sub过程的局部变量的值。Static属性对在Sub 外声明的变量不会产生影响,即使过程中也使用了这些变量。
name必需的。Sub 的名称;遵循标准的变量命名约定。
arglist可选的。代表在调用时要传递给Sub 过程的参数的变量列表。多个变量则用逗号隔开。
statements可选的。Sub过程中所执行的任何语句组。

函数

从其它过程调用一个过程(Sub)时,必须键入过程名称以及任何需要的参数值。Call语句可有可无,如果使用它,则参数必须以括号括起来。

[ Public | Private] [static] Function name [ (arglist) ] [As type]
    [ statements]
    [ name = expression]	
    [Exit Function]
    [ statements]
    [name = expression]
End Function

下面的示例展示了调用具有多个参数的Sub 过程的两种不同方法。当第二次调用HouseCalc 时,因为使用Call语句(第3行),所以需要利用括号将参数括起来。

sub Main ()
HouseCalc 99800,43100
Call HouseCalc (380950,49500)
End sub


sub HouseCalc (price As single, wage As single)
    if 2.5 * wage <= 0.8 * price Then
	MsgBox "You cannot afford this house. "
    Else
	MsgBox "This house is affordable. "
    End If
End Sub

Answer3 = MsgBox ("Are you happy?",4, "Question 3")

MsgBox "Task Completed! ", 0,"Task Box"

如果不在意函数的返回值,可以用调用Sub 过程的方式来调用函数。如下面示例所示,可以省略括号,列出参数并且不要将函数指定给变量:

基本语法

变量

定义变量可以使用Dim语句

Dim 变量名 As 数据类型
-----
变量名命名一般可以这样
change_name
函数命名一般这样
changeName()
数据类型

数据类型,指变量的特性,用来决定可保存何种数据。数据类型包括 Byte、Boolean、Integer、Long、Currency、Decimal、Single、Double、Date、String、Object、Variant(默认)和用户定义类型等。

​ VBA的数据类型、存储空间大小、数值范围

数据类型存储空间大小范围
Byte1个字节0到255
Boolean2个字节True或False
Integer2个字节-32,768到32,767
Long(长整型)4个字节-2,147,483,648 到2,147,483,647
Single(单精度浮点型)4个字节负数时从-3.402823E38到-1.401298E-45;正数时从1.401298E-45到3.402823E38
Double(双精度浮点型)8个字节负数时从-1.79769313486231E308 到一4.94065645841247E-324;正数时从4.94065645841247E-324 到1.79769313486232E308
Date8个字节100 年1月1日到9999年 12月31日
object4个字节任何0bject引用
String(变长)10字节加字符串长度到大约20 亿
Variant(数字)(字符)16 个字节任何数字值,最大可达 Double 的范围
用户自定义(利用Type)所有元素所需数目每个元素的范围与它本身的数据类型的范围相同。
时间函数

​ VBA的日期和函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qQpAha56-1615651551102)(images/VBA基础教程一/image-20210228112134099.png)]

字符串

字符串定义后为空字符串,即没有任何数据的字符串(“”),可以通过以下方式对字符串赋值。字符串在VBA中用双引号表示。

Mystring = "Hello world."
MyFixedstring = "This is a fixed string . 
"MyEmptystring = ""

定长字符串必须是其确定的长度,如果赋值时长度过长或过短,则自动以空格添满或截断。

字符串的连接可以使用“&”或者“+”,不过不推荐使用后者,因为容易和数字运算混淆。例如可以使用以下语句连接字符串。

Mystring ="test"
Mystring = Mystring &" Test Added"
Mystring = Mystring + " Added still"

字符串处理的常用函数如表2-6所示,各函数的具体使用方法可参考VBA的帮助文档。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EgRGkdXE-1615651551109)(images/VBA基础教程一/image-20210228111326468.png)]

Format格式字符串
Dim MyTime,MyDate,Mystr
MyTime = #17:04:23#
MyDate = #January 27,1993#
'以系统设置的长时间格式返回当前系统时间。
Mystr =Format ( Time, "Long Time " )
'以系统设置的长日期格式返回当前系统日期。
MyStr = Format (Date, "Long Date")
Mystr = Format (MyTime,"h :m : s")'返回 "17:4:23"。
Mystr = Format (MyTime,"hh : mm : ss AMPM")'返回"05:04:23 PM"。
'如果没有指定格式,则返回字符串。
MyStr = Format (23)'返回 "23"。
'用户自定义的格式。
MyStr = Format (5459.4,"##,##0.00")  ’返回"5,459.40"。
Mystr = Format (334.9,"###0.00") '返回 "334.90"。
Mystr = Format (5,"0.00%")'返回"500.00%"。
MyStr = Format ("HELLO","<")'返回"hello"。
Mystr = Format ("This is it", ">")'返回"THIS IS IT"。

常量

要声明常量并设定常量的值,需要使用Const语句。常量声明后,不能对它赋一个新的数值。例如,假设需要声明一个常量来保存书本价格,可以使用如下语句:

Const BOOKPRICE As Long = 23.50

运算符

VBA中的运算符有以下几类运算符:

  1. 算术运算符,用来进行数学计算的运算符;
  2. 比较运算符,用来进行比较的运算符;
  3. 连接运算符,用来合并字符串的运算符;
  4. 逻辑运算符,用来执行逻辑运算的运算符。

算术运算符

  1. ^运算符:求一个数字的某次方,如A^B;
  2. *运算符:乘法运算;
  3. /运算符:除法运算;
  4. \运算符:对两个数作除法并返回一个整数;
  5. Mod运算符:求两数的余数;
  6. 运算符:加法运算;
  7. -运算符:减法运算;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLZ5kzMS-1615651551113)(images/VBA基础教程一/image-20210228114618550.png)]

比较运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ixp7v9xb-1615651551114)(images/VBA基础教程一/image-20210228114654659.png)]

逻辑运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXaDVbmN-1615651551117)(images/VBA基础教程一/image-20210228114714427.png)]

运算符比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zFNO6fyr-1615651551119)(images/VBA基础教程一/image-20210228110647838.png)]

数组

数组是具有相同数据类型并且共享同一个名字的一组变量的集合。数组中的元素通过索引数字加以区分。定义数组的语法如下:

Dim ArrayName (n) A.s Type
Dim ArrayName (a to b) As Type

其中n、a、b是数组中的元素的数目。n表示数组元素为0到n,共n+1个,a表示数组元素最小索引为a,最大为b,元素个数为(b-a+1)个。
例如,如果要创建保存10个学生名字的数组,可以使用如下语句:

Dim strstudents (9) As string
注意,括号中的数字是9而不是10。这是因为在默认情况下,第一个索引数字是0。数组在处理相似信息时非常有用。

输入和输出

Sub MyFirstVBAProgram()
    Dim strName As String
    Dim strHello As String
    strName = InputBox("请输入你的名字:")
    strHello = "你好," & strName & " !"
    MsgBox strHello
End Sub

如果用户单击O或按下Enter键,则 InputBox函数返回文本框中的内容。如果用户单击Cancel,则此函数返回一个长度为零的字符串 ("")。

控制程序流程

  • 顺序语句:从上到下,由程序的第一行执行到最后一行;
  • 判断分支语句:根据条件跳过部分语句,执行另一部分;
  • 循环语句:循环执行一段语句。

顺序语句

顺序语句是最基础的,按照语句一步一步的执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-62JQ87H5-1615651551120)(images/VBA基础教程一/image-20210307135851911.png)]

判断语句

If...Then..Else语句
If表达式是根据表达式的值有条件地执行一组语句,如果条件为真,则执行其后的语句,否则到下一个判断条件。其语法为:

If condition Then [statements][Else elsestatements]

或者,可以使用块形式的语法:

If condition Then
	[ statements]
[ElseIf condition-n Then
[elseifstatements] ...
[Else

[ elsestatements ] ]
End If

判断条件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHNDC2SD-1615651551122)(images/VBA基础教程一/image-20210228113436731.png)]

在使用判断语句时,也会使用到以下逻辑运算符。

  1. And运算符:通过“result = expression1 And expression2”使用,如果两个表达式的值都是 True,则result是 True。如果其中一个表达式的值是False,则result是False。
  2. Not运算符:通过“result = Not expression”使用,如果 expression是 Tnue,则返回False,否则返回True。
  3. Or运算符:使用同And运算符,如果两个表达式的值有一个是 Tue,则result是True。如果两个表达式的值都是False,则result是False。

例子

Dim Number,Digits,Mystring
Number = 53
'设置变量初始值。
If Number < 10 Then
	Digits = l
ElseIf Number < 100 Then
'若判断结果为True,则完成下一行语句。
	Digits = 2
Else
	Digits = 3
End If

Function Bonus (performance, salary)
    select Case performance
    case l
    Bonus = salary *0.l
    Case 2,3
    Bonus = salary *0.09
    Case 4 To 6
    Bonus = salary *0.07
    Case Is >8
    Bonus = 100
    Case Else
    Bonus = o
    End select
End Function

--------------
Sub Discount3 ()
Dim Quantity As variant
Dim Discount As Double
Quantity = InputBox("Enter Quantity: ")
    select Case Quantity
    Case ""
    Exit Sub
    Case 0 To 24
    	Discount = 0.1
    Case 25 To 49
    	Discount = 0.15
    Case 50 To 74
    	Discount = 0. 2
    Case Is >= 75
    	Discount = 0.25
    End select
    MsgBox "Discount: " & Discount
End Sub

循环语句

For Next语句

For I = l To 10
	For J = l To 10
		For K= l To 10
			...
		Next K
	Next J
Next I

Dim Found,My0bject,MyCollection
Found = False
'设置变量初始值。
For Each Myobject In MyCollection
'对每个成员作一次迭代。
	If Myobject.Text = "Hello" Then
		Found = True
		′将变量 Found的值设成True。
		Exit For
		’退出循环。
	End If
Next

For Each-Next语句

在前面的章节中讲过,“集合”是一组相关的对象。例如,Workbooks集合是所有打开的Workbook 对象的集合,还可以使用很多其他的集合。假设要在集合的所有对象上执行某个动作,或要对集合的所有对象求值并在特定条件下采取动作,这些都是使用For Each-Next结构的好机会,因为在使用For Each-Next结构时,不必知道集合中有多少元素。
For Each-Next结构的语法如下所示:

For Each element In collection
[instructions]
[Exit For]
[instructions]
Next [element]

下面的过程在活动工作簿中的 Worksheets集合上使用For Each-Next结构。在执行这个过程的时候,MsgBox 函数显示出每个工作表的Name属性(如果活动工作簿中有5个工作表,就调用MsgBox函数5次)。

Sub countsheets ()
Dim Item as worksheet
For Each Item In Activeworkbook.worksheets
	MsgBox Item.Name
Next Item
End sub
Exit语句
Exit Do
Exit For
Exit Function
Exit Property
Exit sub

循环中可以在任何位置放置任意个Exit For语句,随时退出循环。**Exit For经常在条件判断之后使用,例如 If…Then,并将控制权转移到紧接在 Next 之后的语句。可以将一个For…Next循环放置在另一个For…Next循环中,组成嵌套循环。不过在每个循环中的counter要使用不同的变量名。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JM4mJJTV-1615651551123)(images/VBA基础教程一/image-20210228121354922.png)]

With语句

With语句可以对某个对象执行一系列的语句,而不用重复指出对象的名称。例如,要改变一个对象的多个属性,可以在With控制结构中加上属性的赋值语句,这时候只是引用对象一次而不是在每个属性赋值时都要引用它。下面的例子显示了如何使用With语句来给同一个对象的几个属性赋值。

with MyLabel
    .Height = 2000
    .width = 2000
    .caption = "This is MyLabel"
End with

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7x9CK3Ca-1615651551125)(images/VBA基础教程一/image-20210307135705978.png)]

程序一旦进入With 块,object就不能改变。因此不能用一个With语句来设置多个不同的对象。可以将一个With块放在另一个之中,而产生嵌套的With语句。但是,由于外层With块成员会在内层的With 块中被屏蔽住,所以必须在内层的With块中,使用完整的对象引用来指出在外层的With块中的对象成员。

With语句经常使用在对一个对象或用户自定义类型需要进行反复引用的情况下,特别是在循环中,如果要反复引用某个对象,那么最好通过With语句来引用该对象。

调试程序

Debug调试

Debug对象可以在运行时将输出发送到立即(Immediate)窗口。Debug对象有2个方法: Assert和 Print方法,Assert 判断1条条件语句,如果为False,则挂起执行,暂停在Assert语句的地方,Print语句则向立即窗口输出一段文本,例如以下代码:

Dim i As Long
    For i = l To 10 step 1
    Debug.Print i
    Debug.Assert i <8
Next i

当程序执行到3行Debug.Print时,程序向立即窗口输出i的值,而当i大于等于8时,Debug.Assert判断的表达式为False,程序挂起。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0fCwsvP-1615651551126)(images/VBA基础教程一/image-20210307123111262.png)]

IDE调试

VBA提供了以下几种调试工具供使用。这些工具包括:

  • 立即窗口:可以交互式运行VBA代码;
  • 监视窗口:监视变量、对象的值或内容;
  • 断点:程序执行到此后会进入中断状态,可以单步执行,查看变量对象等;
  • 单步执行代码(F8)

错误处理

  • On Error Resume如果有运行时刻的错误发生,那么程序将从导致错误发生的语句处重新开始执行;

  • On Error Resume Next如果有运行时刻的错误发生,那么程序就从导致错误发生的语句的下一句继续执行下去。

Sub debugPrint()
    Dim i As Long
    For i = l To 10 Step 1
        Debug.Print i
		On Error Resume Next  '暗示下面只要有错误的语句都可以跳过
        a = 8 / 0
        b = 8 / 0
        Debug.Assert i < 8
    Next i
End Sub

事件触发

工作簿的事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-glTNUj1h-1615651551128)(images/VBA基础教程一/image-20210313231603781.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qgRGRvtf-1615651551129)(images/VBA基础教程一/image-20210313231621287.png)]

窗体事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbX6496s-1615651551131)(images/VBA基础教程一/image-20210313231925836.png)]

OnTime事件

OnTime事件在一天中的某个特定时刻发生。下面的示例展示了如何进行Excel编程,使其在下午3点发出叫声并显示消息:

Sub SetAlarm ()
Application.onTime Timevalue("15:00:00"),"DisplayAlarm"
End Sub
Sub DisplayAlarm()
Beep
MsgBox "wake up. It's time for your afternoon break ! "
End Sub

该示例中,SetAlarm过程使用Application对象的OnTime方法来设置OnTime事件。该方法使用了两个参数:时间(在示例中为3 pm)和该时间到来时执行的过程(在示例中为DisplayAlarm过程)。执行SetAlarm过程后,DisplayAlarm过程将会在下午3点被调用,弹出如图19-10所示的对话框。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AOFtOtEL-1615651551133)(images/VBA基础教程一/image-20210313232141231.png)]

如果想要通过相对于当前时间来确定事件的发生时间,例如,从现在开始的20分钟之后,那么可以这样来编写指令:

Application.onTime Now + TimeValue ( "00:20:00"),"DisplayAlarm"

也可以使用OnTime方法来确定某个特定日期过程发生的时间。下列语句在2010年4月1日上午 12:01运行DisplayAlarm过程。

Application. OnTime DateSerial (2010, 4,1)+TimeValue ("00:00:01"), "DisplayAlarm"
   Dim NextTick As Date

Sub UpdateClock()
'   Updates cell A1 with the current time
    ThisWorkbook.Sheets(1).Range("A1") = Time
'   Set up the next event five seconds from now
    NextTick = Now + TimeValue("00:00:05")
    Application.OnTime NextTick, "UpdateClock"
End Sub

Sub StopClock()
'   Cancels the OnTime event (stops the clock)
    On Error Resume Next
    Application.OnTime NextTick, "UpdateClock", , False
End Sub

窗体

窗体是事件驱动类型的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k8X7TDg4-1615651551134)(images/VBA基础教程一/image-20210307125227582.png)]

按钮控件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXE4DDQg-1615651551136)(images/VBA基础教程一/image-20210307125438516.png)]

文本框控件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b2cDuYwM-1615651551138)(images/VBA基础教程一/image-20210307125542768.png)]

双击按钮控件,会生成单机代码,函数名称为cmdHello_Click()(即为按钮控件的名称+事件名称)

Private Sub cmdHello_Click()  
    Me.txtMsg.Text = "Hello VB!"  'txtMsg即为文本框控件的名称  Me相当于This
End Sub

excel里面的窗体使用

最关键的就是插入一个图片或者窗体控件,然后制定宏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnJwos7J-1615651551139)(images/VBA基础教程一/image-20210307130024180.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SkqkoLwj-1615651551141)(images/VBA基础教程一/image-20210307130040357.png)]

为其指定宏,就可以点击它控制后面的程序了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nxUUB3y9-1615651551142)(images/VBA基础教程一/image-20210307130303622.png)]

  • 25
    点赞
  • 294
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值