🎯 本章目标:掌握 VBA 基础语法,理解变量声明、数据类型选择、运算符使用,为编写高质量代码打下坚实基础。
一、变量基础
1.1 什么是变量?
变量是程序中用于存储数据的容器。想象它是一个贴有标签的盒子,你可以往里面放东西,也可以随时取出查看或修改。
┌─────────────────────────────────────────┐
│ 变量名: userName │
│ 数据类型: String │
│ 值: "张三" │
│ │
│ ┌─────────────────────────────────┐ │
│ │ │ │
│ │ "张三" │ │
│ │ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
1.2 变量命名规则
必须遵守的规则:
| 规则 | 正确示例 | 错误示例 |
|---|---|---|
| 必须以字母开头 | userName, age |
1stName, 2count |
| 只能包含字母、数字、下划线 | first_name, item2 |
first-name, item@2 |
| 不能包含空格 | userName |
user name |
| 不能使用保留字 | - | Sub, Function, If |
推荐命名规范:
| 规范 | 说明 | 示例 |
|---|---|---|
| 驼峰命名法 | 首单词小写,后续单词首字母大写 | userName, totalAmount |
| 匈牙利命名法 | 前缀+描述 | strName, intCount |
| 见名知意 | 名称能表达变量用途 | salesData 优于 sd |
常见保留字(不能用做变量名):
And As Boolean ByRef Byte
ByVal Call Case Catch CBool
CByte CCur CDate CDbl CDec
Const Date Dim Do Double
Else ElseIf End Enum Erase
Error Exit False For Function
GoTo If In Integer Long
Loop Me Mod New Next
Not Object On Option Or
Private Public ReDim Resume Return
Select Set Single Static Stop
Sub Then To True Type
Until Variant Wend While With
二、变量声明
2.1 Dim 语句
使用 Dim 关键字声明变量:
Dim 变量名 As 数据类型
示例:
Sub VariableDemo()
' 声明不同类型的变量
Dim userName As String ' 字符串
Dim age As Integer ' 整数
Dim salary As Double ' 双精度小数
Dim isActive As Boolean ' 布尔值
Dim birthDate As Date ' 日期
' 赋值
userName = "张三"
age = 28
salary = 15000.50
isActive = True
birthDate = #1995-3-15#
' 输出
MsgBox "姓名: " & userName & vbCrLf & _
"年龄: " & age & vbCrLf & _
"薪资: " & salary
End Sub
2.2 强制声明(Option Explicit)
强烈建议在每个模块顶部添加:
Option Explicit
Sub Demo()
Dim x As Integer
x = 10 ' ✓ 正确
y = 20 ' ✗ 编译错误!y 未声明
End Sub
开启自动添加 Option Explicit:
工具 → 选项 → 编辑器 → 勾选 要求变量声明
┌─────────────────────────────────────┐
│ 选项 │
├─────────────────────────────────────┤
│ 编辑器 │
│ │
│ ☑ 自动语法检查 │
│ ☑ 要求变量声明 ← 勾选此项 │
│ ☑ 自动列出成员 │
│ ☑ 自动显示快速信息 │
│ │
└─────────────────────────────────────┘
为什么要用 Option Explicit?
| 问题 | 示例 |
|---|---|
| 避免拼写错误 | userName 误写为 userNmae,未声明会创建新变量 |
| 提高性能 | 显式声明的变量类型确定,运行更快 |
| 便于维护 | 代码更清晰,易于理解 |
2.3 同时声明多个变量
' 正确:每个变量都有类型
Dim x As Integer, y As Integer, z As Integer
' 错误:只有 z 是 Integer,x 和 y 是 Variant
Dim x, y, z As Integer
' 推荐写法(更清晰)
Dim x As Integer
Dim y As Integer
Dim z As Integer
2.4 变量的作用域
' 模块级变量(模块顶部,所有过程可访问)
Dim moduleVar As String
Sub Procedure1()
' 过程级变量(仅本过程可访问)
Dim localVar As Integer
moduleVar = "可在其他过程访问"
localVar = 100
End Sub
Sub Procedure2()
MsgBox moduleVar ' ✓ 可以访问
' MsgBox localVar ' ✗ 编译错误!localVar 未定义
End Sub
作用域关键字对比:
| 关键字 | 作用域 | 生命周期 |
|---|---|---|
Dim |
过程/模块 | 过程结束/模块卸载 |
Private |
模块 | 模块卸载 |
Public |
整个工程 | Excel 关闭 |
Static |
过程 | 程序结束 |
三、数据类型详解
3.1 常用数据类型
┌─────────────────────────────────────────────────────────┐
│ VBA 数据类型 │
├──────────────┬─────────────┬────────────────────────────┤
│ 类型 │ 占用空间 │ 取值范围 │
├──────────────┼─────────────┼────────────────────────────┤
│ Byte │ 1 字节 │ 0 ~ 255 │
│ Boolean │ 2 字节 │ True / False │
│ Integer │ 2 字节 │ -32,768 ~ 32,767 │
│ Long │ 4 字节 │ -2,147,483,648 ~ │
│ │ │ 2,147,483,647 │
│ Single │ 4 字节 │ 约 -3.4E38 ~ 3.4E38 │
│ Double │ 8 字节 │ 约 -1.8E308 ~ 1.8E308 │
│ Currency │ 8 字节 │ -922,337,203,685,477.5808 ~ │
│ │ │ 922,337,203,685,477.5807 │
│ Date │ 8 字节 │ 100年1月1日 ~ 9999年12月31日 │
│ String │ 变长 │ 约 20 亿字符 │
│ Variant │ 变长 │ 任意类型 │
│ Object │ 4 字节 │ 对象引用 │
└──────────────┴─────────────┴────────────────────────────┘
3.2 数值类型选择指南
| 场景 | 推荐类型 | 原因 |
|---|---|---|
| 年龄、数量(小整数) | Integer |
节省内存 |
| 大整数(如身份证号) | Long |
避免溢出 |
| 财务计算 | Currency |
精确到小数点后4位 |
| 科学计算 | Double |
高精度浮点 |
| 百分比、比率 | Single |
精度足够,节省空间 |
示例:
Sub NumberTypes()
Dim count As Integer ' 计数器
Dim totalRows As Long ' 大表行数
Dim price As Currency ' 价格
Dim rate As Double ' 利率/比率
count = 100
totalRows = 1000000
price = 1999.99
rate = 0.0356
Debug.Print "Count: " & count
Debug.Print "Total Rows: " & totalRows
Debug.Print "Price: " & Format(price, "Currency")
Debug.Print "Rate: " & Format(rate, "Percent")
End Sub
3.3 字符串类型
Sub StringDemo()
Dim firstName As String
Dim lastName As String
Dim fullName As String
firstName = "三"
lastName = "张"
' 字符串连接
fullName = lastName & firstName ' 结果: 张三
fullName = lastName + firstName ' 结果: 张三(不推荐)
' 字符串函数
Dim text As String
text = " Hello World "
Debug.Print Trim(text) ' "Hello World"
Debug.Print Left(text, 5) ' " Hel"
Debug.Print Right(text, 5) ' "rld "
Debug.Print Mid(text, 3, 5) ' "Hello"
Debug.Print Len(text) ' 15
Debug.Print UCase(text) ' " HELLO WORLD "
Debug.Print LCase(text) ' " hello world "
End Sub
常用字符串函数:
| 函数 | 功能 | 示例 |
|---|---|---|
Len(s) |
返回字符串长度 | Len("ABC") → 3 |
Left(s, n) |
取左边 n 个字符 | Left("ABC", 2) → "AB" |
Right(s, n) |
取右边 n 个字符 | Right("ABC", 2) → "BC" |
Mid(s, start, len) |
从 start 取 len 个字符 | Mid("ABC", 2, 1) → "B" |
Trim(s) |
去除首尾空格 | Trim(" ABC ") → "ABC" |
UCase(s) |
转大写 | UCase("abc") → "ABC" |
LCase(s) |
转小写 | LCase("ABC") → "abc" |
InStr(s1, s2) |
查找子串位置 | InStr("ABC", "B") → 2 |
Replace(s, f, r) |
替换子串 | Replace("ABC", "B", "X") → "AXC" |
3.4 日期时间类型
Sub DateTimeDemo()
Dim today As Date
Dim meetingTime As Date
' 日期赋值(使用 # 包围)
today = #2024-1-15#
meetingTime = #3:30:00 PM#
' 获取当前日期时间
Dim nowTime As Date
nowTime = Now ' 当前日期和时间
' 日期函数
Debug.Print Date ' 当前日期
Debug.Print Time ' 当前时间
Debug.Print Now ' 当前日期时间
Debug.Print Year(Date) ' 年
Debug.Print Month(Date) ' 月
Debug.Print Day(Date) ' 日
Debug.Print Weekday(Date) ' 星期(1=周日)
' 日期计算
Dim future As Date
future = Date + 7 ' 7天后
Debug.Print "一周后: " & future
' 日期差
Dim daysDiff As Long
daysDiff = #2024-12-31# - Date
Debug.Print "距离年底还有 " & daysDiff & " 天"
End Sub
常用日期函数:
| 函数 | 功能 | 示例 |
|---|---|---|
Date |
当前日期 | 2024/1/15 |
Time |
当前时间 | 14:30:15 |
Now |
当前日期时间 | 2024/1/15 14:30:15 |
Year(d) |
提取年份 | Year(#2024-1-15#) → 2024 |
Month(d) |
提取月份 | Month(#2024-1-15#) → 1 |
Day(d) |
提取日期 | Day(#2024-1-15#) → 15 |
Weekday(d) |
星期几 | Weekday(Date) → 1-7 |
DateAdd(interval, n, d) |
日期加减 | DateAdd("d", 7, Date) |
DateDiff(interval, d1, d2) |
日期差 | DateDiff("d", Date1, Date2) |
Format(d, "format") |
格式化日期 | Format(Date, "yyyy-mm-dd") |
日期格式字符串:
| 格式 | 结果示例 |
|---|---|
"yyyy-mm-dd" |
2024-01-15 |
"yyyy年m月d日" |
2024年1月15日 |
"mm/dd/yyyy" |
01/15/2024 |
"dddd" |
Monday |
"mmm" |
Jan |
3.5 Variant 类型
Variant 是 VBA 的万能类型,可以存储任何数据:
Sub VariantDemo()
Dim v As Variant
v = 100 ' 存储整数
v = "Hello" ' 存储字符串
v = 3.14 ' 存储小数
v = True ' 存储布尔值
v = #2024-1-15# ' 存储日期
' 可以存储数组
v = Array(1, 2, 3, 4, 5)
' 可以存储对象
Set v = Range("A1")
End Sub
⚠️ 注意:虽然 Variant 灵活,但会:
- 占用更多内存
- 运行速度较慢
- 可能引发类型错误
建议:明确指定数据类型,只在必要时使用 Variant。
四、常量
4.1 声明常量
使用 Const 声明常量:
Sub ConstantsDemo()
' 声明常量
Const PI As Double = 3.14159265359
Const COMPANY_NAME As String = "ABC科技有限公司"
Const MAX_USERS As Integer = 100
Const TAX_RATE As Currency = 0.13
' 使用常量
Dim radius As Double
Dim area As Double
radius = 5
area = PI * radius * radius
MsgBox "圆面积: " & area & vbCrLf & _
"公司名称: " & COMPANY_NAME
End Sub
4.2 常量命名规范
-
全部大写
-
单词间用下划线分隔
-
见名知意
Const MAX_ROW_COUNT As Long = 1048576
Const DEFAULT_SHEET_NAME As String = "Sheet1"
Const VERSION_NUMBER As String = "1.0.0"
4.3 内置常量
VBA 提供了大量预定义常量:
MsgBox 常量:
' 按钮类型
vbOKOnly ' 只显示确定按钮
vbOKCancel ' 确定和取消
vbYesNo ' 是和否
vbYesNoCancel ' 是、否、取消
' 图标类型
vbCritical ' 错误图标 (X)
vbQuestion ' 问号图标 (?)
vbExclamation ' 警告图标 (!)
vbInformation ' 信息图标 (i)
' 返回值
vbOK = 1
vbCancel = 2
vbYes = 6
vbNo = 7
颜色常量:
vbBlack = 0
vbRed = 255
vbGreen = 65280
vbYellow = 65535
vbBlue = 16711680
vbMagenta = 16711935
vbCyan = 16776960
vbWhite = 16777215
使用示例:
Sub MsgBoxDemo()
Dim result As VbMsgBoxResult
result = MsgBox("确定要删除吗?", vbYesNo + vbQuestion, "确认")
If result = vbYes Then
MsgBox "已删除", vbInformation
Else
MsgBox "已取消", vbInformation
End If
End Sub
五、运算符
5.1 算术运算符
Sub ArithmeticOperators()
Dim a As Integer: a = 10
Dim b As Integer: b = 3
Debug.Print a + b ' 13 (加法)
Debug.Print a - b ' 7 (减法)
Debug.Print a * b ' 30 (乘法)
Debug.Print a / b ' 3.333... (除法)
Debug.Print a \ b ' 3 (整除)
Debug.Print a Mod b ' 1 (取余)
Debug.Print a ^ b ' 1000 (幂运算)
End Sub
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | 5 + 3 |
8 |
- |
减法 | 5 - 3 |
2 |
* |
乘法 | 5 * 3 |
15 |
/ |
除法 | 5 / 2 |
2.5 |
\ |
整除 | 5 \ 2 |
2 |
Mod |
取模 | 5 Mod 2 |
1 |
^ |
幂运算 | 2 ^ 3 |
8 |
5.2 比较运算符
Sub ComparisonOperators()
Dim x As Integer: x = 10
Dim y As Integer: y = 20
Debug.Print x = y ' False (等于)
Debug.Print x <> y ' True (不等于)
Debug.Print x < y ' True (小于)
Debug.Print x > y ' False (大于)
Debug.Print x <= y ' True (小于等于)
Debug.Print x >= y ' False (大于等于)
End Sub
5.3 逻辑运算符
Sub LogicalOperators()
Dim a As Boolean: a = True
Dim b As Boolean: b = False
Debug.Print a And b ' False (逻辑与)
Debug.Print a Or b ' True (逻辑或)
Debug.Print Not a ' False (逻辑非)
Debug.Print a Xor b ' True (逻辑异或)
End Sub
真值表:
| A | B | A And B | A Or B | Not A | A Xor B |
|---|---|---|---|---|---|
| T | T | T | T | F | F |
| T | F | F | T | F | T |
| F | T | F | T | T | T |
| F | F | F | F | T | F |
5.4 字符串运算符
Sub StringOperators()
Dim firstName As String: firstName = "张"
Dim lastName As String: lastName = "三"
' 连接运算符 &
Debug.Print firstName & lastName ' "张三"
Debug.Print "姓名: " & firstName & lastName
' + 也可以连接,但不推荐
Debug.Print firstName + lastName ' "张三"
' 区别:& 会强制转换为字符串
Debug.Print "编号: " & 100 ' "编号: 100"
' Debug.Print "编号: " + 100 ' 类型不匹配错误!
End Sub
5.5 运算符优先级
优先级(高 → 低):
1. ^ (幂运算)
2. - (负号)
3. *, / (乘除)
4. \ (整除)
5. Mod (取模)
6. +, - (加减)
7. & (字符串连接)
8. =, <>, <, >, <=, >= (比较)
9. Not (逻辑非)
10. And (逻辑与)
11. Or (逻辑或)
12. Xor (逻辑异或)
使用括号明确优先级:
Sub OperatorPriority()
Dim result As Double
' ambiguous
result = 10 + 20 * 2 ' 50 (先乘后加)
' clear
result = (10 + 20) * 2 ' 60
' complex expression
result = (100 - 20) / (5 + 3) * 2
' 80 / 8 * 2 = 20
End Sub
六、类型转换
6.1 隐式转换
VBA 会自动进行某些类型转换:
Sub ImplicitConversion()
Dim i As Integer
Dim d As Double
i = 10
d = i ' Integer → Double,自动转换
Dim s As String
s = 100 ' Integer → String,自动转换
Debug.Print s ' "100"
End Sub
6.2 显式转换函数
Sub ExplicitConversion()
Dim numStr As String: numStr = "123"
Dim num As Integer
' 字符串转数字
num = CInt(numStr) ' 123
num = CLng(numStr) ' 123 (Long)
num = CByte(numStr) ' 123 (Byte)
' 数字转字符串
Dim str As String
str = CStr(123) ' "123"
' 转日期
Dim d As Date
d = CDate("2024-1-15") ' #2024-1-15#
' 转货币
Dim c As Currency
c = CCur(123.456) ' 123.456
' 转布尔
Dim b As Boolean
b = CBool(1) ' True
b = CBool(0) ' False
End Sub
类型转换函数表:
| 函数 | 转换目标类型 | 示例 |
|---|---|---|
CBool(x) |
Boolean | CBool(1) → True |
CByte(x) |
Byte | CByte(100) → 100 |
CInt(x) |
Integer | CInt(3.7) → 4 |
CLng(x) |
Long | CLng(3.7) → 4 |
CSng(x) |
Single | CSng(3.14159) |
CDbl(x) |
Double | CDbl(3.141592653) |
CCur(x) |
Currency | CCur(123.456789) → 123.4568 |
CDate(x) |
Date | CDate("2024-1-15") |
CStr(x) |
String | CStr(123) → "123" |
CVar(x) |
Variant | CVar(123) |
Val(x) |
数字 | Val("123abc") → 123 |
6.3 安全转换
使用 IsNumeric 检查后再转换:
Sub SafeConversion()
Dim userInput As String
userInput = InputBox("请输入数字:")
If IsNumeric(userInput) Then
Dim num As Double
num = CDbl(userInput)
MsgBox "输入的数字是: " & num
Else
MsgBox "输入无效,请输入数字!", vbExclamation
End If
End Sub
七、本章小结
核心知识点
| 知识点 | 关键内容 |
|---|---|
| 变量声明 | Dim 变量名 As 类型,使用 Option Explicit |
| 命名规范 | 驼峰命名、见名知意、避免保留字 |
| 数据类型 | 根据场景选择合适类型,节省内存 |
| 字符串操作 | & 连接、常用字符串函数 |
| 日期处理 | #日期# 格式、日期函数 |
| 常量 | Const 声明,全大写下划线分隔 |
| 运算符 | 算术、比较、逻辑、字符串运算符 |
| 类型转换 | 隐式/显式转换,使用 IsNumeric 安全检查 |
下章预告
下一章将学习 程序流程控制:
- If...Then...Else 条件判断
- Select Case 多分支选择
- For...Next 循环
- Do...Loop 循环
- 嵌套结构与流程控制语句
练习作业
基础练习
-
声明变量存储以下信息:员工姓名(String)、年龄(Integer)、入职日期(Date)、是否在职(Boolean)、月薪(Currency)
-
编写代码计算圆的面积和周长,使用常量定义 PI
-
将字符串
"12345"转换为数字,并计算其平方
进阶练习
-
编写一个程序,接收用户输入的两个数字和一个运算符(+、-、*、/),输出计算结果
-
计算从当前日期到年底还剩多少天、多少小时
挑战练习
- 编写一个函数,判断输入的年份是否为闰年(闰年规则:能被4整除但不能被100整除,或能被400整除)
💡 学习建议:数据类型是编程的基础,务必理解每种类型的适用场景。多练习类型转换,这是实际开发中经常遇到的问题。
本文是《Excel VBA 从入门到精通》系列第二篇文章,持续更新中...
如果觉得有帮助,欢迎点赞、收藏、评论!有任何问题可以在评论区留言交流。