Visual Basic for Applications

Visual Basic for Applications（VBA）是Visual Basic的一种宏语言，主要能用来扩展Windows的应用程序功能，特别是Microsoft Office软件。也可说是一种应用程序视觉化的Basic Script。1994年发行的Excel 5.0版本中，即具备了VBA的宏功能。

## 数据类型

### 基本数据类型

即Primary Type Data，下述列表的括号内为字节数：

- Byte (1)：无符号类型，取值范围0-255
- Boolean (2)
- Integer (2)
- Long (4)
- Single (4)
- Double (8)
- Currency (8)
- Decimal (14)
- Date (8)
- String
- Object (4)
- Variant （根据分配确定）

### 自定义的数据类型

相当于C语言的struct，例如：

```
Type 自定义类型名
     元素名  As 类型
      …
     [元素名 As 类型]
End Type 
```

### 数组

```vb
Option Base 0 '數組索引值從0開始
Option Base 1 '數組索引值從1開始
Dim MyArray(10) '聲明一個數組變量，10是最大的可用的數組索引值
MyArray(5) = 101 '給數組的元素賦值
Dim Data(10,5) '聲明一個二維數組變量
Data(1,1) = "A001" '給數組元素賦值
Dim cArr(-11 To 20, 1 To 3) As String '聲明一個數組，定義數組索引值的上下界
Dim dArr() As String '聲明動態數組
ReDim dArr(0 To 5, 1 To 2) '改變動態數組的尺寸默認把原數據清除。如果保留原來的數據，必須加上參數Preserve。
'使用Preserve參數時只能改變最後一維的大小
If UBound(vTemp) = -1 Then
'判斷數組變量vTemp是否為 空數組
End If
Erase MyArrar, Data 'Erase語句清除數組元素，釋放變量佔用的空間
```

## 常量

日期常量由符号“#”将字符括起来，如#2012-1-1#。

系统定义常量有3个：True、False和Null。

固有常量是编程时引用的对象库定义的常量。所有固有常量都可以在宏或VBA代码中使用。通常，固有常量通过前两个字母来指明定义该常量。来自VB库的常量则以“vb”开头。来自Access的常量以“ac”开头。可以使用对象浏览器来查看所有对象库中的固有常量列表。

可以自行定义常量。如：

```
Global Const 符号常量名称 = 常量值
```

## 调用DLL

例如：

```
Private Declare Function getFrequency Lib "kernel32" _ Alias "QueryPerformanceFrequency" (cyFrequency As Currency) As Long
Private Declare Function getTickCount Lib "kernel32" _ Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long
```

## 控制结构

### if 语句

```
if 條件1 then
   語句1
elseif 條件2 then
   語句2
elseif ...
    ...
else
   語句n
end if
```

### Select Case 语句

```
Select Case 表達式
   Case 表達式列表1
       語句1
   Case 表達式列表2
       語句2
       ...
   Case 表達式列表n
       語句n
End Select 
```

其中的表达式列表可以为：

- 表达式 例： "A"
- 用逗号分隔的一组枚举表达式 例：2,4,6,8
- 表达式1 To 表达式2 例：60 To 100
- Is 关系运算符表达式 例：Is < 60

### Do...Loop 语句

```
Do While或Until 條件
   語句塊1
   Exit Do
   語句塊2
Loop

Do
   語句塊1
   Exit Do
   語句塊2
Loop While或Until 條件
```

### For...Next语句

```
For 循環控制變量=初值To 終值Step 步長
   語句塊 ‘Exit For語句可以跳出循環體
Next
```

### For Each … Next语句

```
For Each 循環控制變量 In 集合變量
   語句塊 
   Exit For語句可以跳出循環體
Next 循環控制變量
```

### 跳出本次循环的continue语句

VBA没有类似C语言的continue语句。通常可如此写程序：

```vb
 For 循環控制變量=初值 To 終值 Step 步長
    Do '用于模拟continue
        語句塊 
        If 条件 Then Exit Do '用于模拟continue
        語句塊 
    Loop While False '用于模拟continue
 Next
```

### With语句

```
With 對象引用
   語句塊
End With
```

### On Error语句

```
On Error Goto 出錯處理語句的label '跳轉到出錯處理語句
```

或

```
On Error Resume Next '遇到錯誤，不管錯誤，繼續往下執行
```

### 具有控制作用的函数

- IIf(条件式,表达式1,表达式2)
- Switch(条件式1,表达式1,条件式2,表达式2,...,条件式n,表达式n)
- Choose(索引式,选项1,选项2,...,选项n) '这是基于1的索引

## 其他语句

### 注释语句

使用REM或者单引号开始的行。

### 语句的连写与续行

如果一行包括多条语句，用冒号分割各个语句。跨多行的语句，在行末用“空格加下划线”表示续行。

## 过程与函数

```
Sub 過程名(參數表)
    語句塊
    Exit Sub
    語句塊
End Sub

Function 函數名(參數表) As Type
   語句塊
   函數名=表達式
   Exit Function
End Function
```

可以是Private、Public、Friend、Static等修饰。

调用函数/过程时，可以加括号或者不加括号。如果调用表达式作为一行的一部分，那么必须用参数，例如函数调用的返回值赋给变量。调用过程时，可以使用/不使用call关键字。使用call语句调用过程，如果无参数，则不加括号；如果有参数，必须加括号。如果调用时用括号包住单个参数，则该参数强行按值传递。需要特别注意，不用call不加括号的调用，形参与实参是传值(passed by value)而不是传引用(passed by reference)，这会导致一些对象的方法调用失败。例如：

```vb
    Dim cn As ADODB.Connection
    Set cn = CurrentProject.Connection
    Dim rs As New ADODB.Recordset    
    rs.Open "SELECT * FROM myTable" , cn

    Dim ExcelApp As New Excel.Application
    Dim ExcelWst As Worksheet
    Set ExcelWst = ExcelApp.Workbooks.Add.Worksheets(1)

    ExcelWst.Range("A2").CopyFromRecordset(rs) '失败，无法执行该行
    ExcelWst.Range("A2").CopyFromRecordset rs  '可成功执行该行
```

## 常用内置函数

VBA的常用内置函数列表参见：

- MsgBox
- InputBox
- 舍入函数：Fix 向0取整,Int向下取整, Round四舍五入
- Rnd 返回0-1内的单精度随机数
- Filter：对字符串的一维数组的过滤
- InStr(Start, ,, Compare)与InStrRev：查找子串
- Len 字符串长度
- Join：连接一维数组中的所有子字符串
- Left,Right,Mid 截取子字符串
- Space(数值) 生成空格字符串
- Ucase,Lcase 大小写转换函数
- Ltrim, Rtrim,Trim 删除首尾空格
- Replace
- Split：分割一个字符串成为一维数组
- StrComp：字符串比较
- StrConv：字符串转换
- String(number, character)：制定字符重复若干次
- StrReverse
- Year, Month, Day, WeekDay,Hour,Minute,Second 截取日期时间分量
- DateAdd 日期/时间增量函数
- DateDiff(,,,W1,W2)日期/时间的距离函数
- DatePart(,,w1,w2)时间分割函数
- DateSerial 合成日期；DateValue(“字符串表达式”)返回日期。
- Date,Time,Now,Timer 返回日期时间
- DateValue
- TimeSerial：由时间序列得到时间对象
- TimeValue：由时间字符串得到时间对象
- Weekday：获得日期的周几
- WeekdayName
- 转换函数：CBool、CByte、CCur、 CDate、 CDbl、CDec、CInt、 CLng、CLngLng、CLngPtr、CSng、CStr、CVar、CVErr、Asc返回第一个字符的Ascii编码值、Chr(ASCII码)返回字符、Hex、Oct、Str返回字符串、Val(string)、Format、FormatCurrency、FormatDateTime、FormatNumber、FormatPercent、MonthName
- Nz(表达式或字段属性值,规定值)如果是空，则返回0或者""或者函数的第二个参数值
- 验证函数：isNumeric、isDate、isNull、isEmpty IsArray、IsError、IsMissing、IsObject
- 数学函数：Abs、Sqr、Tan、Atn（即atan）、Sin、Cos、Exp（e为基的指数）、Log自然对数
- Array:构造一个Array对象
- CallByName: get or set a property, or invoke a method at run time using a string name.
- 控制流：Choose:类似于C语言的select语句、IIf相当于IF-ELSE语句、Switch
- Command：获取命令行参数
- CreateObject：创建ActiveX对象
- CurDir：返回指定驱动器的当前工作路径
- 由基本数学函数导出的函数：Sec、Cosec、Cotangent、Cotan、Arcsin、Arccos、Arcsec、Arccosec、Arccotan、HSin、HCos、HTan、HSec、HCosec、HCotan、HArcsin、HArccos、HArctan、HArcsec、HArccosec、HArccotan、LogN
- DoEvents：暂时把CPU控制权交回给系统。
- Environ：返回环境变量的值
- Dir：返回满足条件的所有文件、目录的名字
- EOF
- FileAttr
- FileDateTime
- FileLen
- FreeFile Function
- GetAttr：返回文件、目录的属性值
- Input：读取文件
- Loc：文件指针位置
- LOF：文件打开时的指针位置
- Seek：文件指针定位
- Spc：使用Print做position output
- Tab：用于Print函数
- Error:错误号对应的错误消息
- Windows Registry中的数据：GetAllSettings、SaveSetting、DeleteSetting、GetSetting
- GetObject：ActiveX组建的引用
- IMEStatus：返回当前Input Method Editor (IME)。
- Macintosh平台：MacID、MacScript
- DDB：使用double-declining balance计算贬值
- FV:计算固定利率的年金
- IPmt：计算利率
- IRR：计算利率
- MIRR：计算利率
- NPer：计算周期数
- NPV：计算net present value
- Pmt：计算支付数
- PPmt：计算本金支付数
- PV：计算present value
- Rate：利息率
- SLN：straight-line depreciation
- SYD：计算sum-of-years' digits depreciation
- Partition：返回字符串，表示一个数值名字落在各个range内。常用于SQL select语句
- QBColor：颜色值
- RGB：颜色值
- TypeName：得到变量的类型名
- VarType：得到变量的类型数

## 表达式

比较特殊的运算符有指数运算^，浮点除法/，整数除法\，取模运算Mod，不等逻辑比较运算<>

## 参考文献

- VBA Language Reference for MS Office 2013
- Office VBA 语言参考中文版for MS Office 2013
- Office VBA 对像库的引用for MS Office 2013
- VBA & Visual Basic Scripting 中文版语言参考

## 外部链接

- Docs - Office Dev Center
- 文档 - Office 开发人员中心

## 基本资料

- 日语原文：Visual Basic for Applications（VBA）
- 编程范型：Multi-paradigm编程语言
- 发行时间：1993年
- 开发者：Microsoft
- 软件版本周期：7.1(Microsoft Office 2021)
- 类型系统：静态/动态混合，强/弱混合
- 受影响于：QuickBASIC, Visual Basic
- 操作系统：Microsoft Windows, Mac OS X
- 许可证：专有EULA