专门为你准备的 VBA 教程 · 从录制第一个宏到自己写代码 · 带模拟代码块和实战
VBA(Visual Basic for Applications)是 Excel 内置的编程语言。你可以把它理解为——
「让你能写代码控制 Excel 做任何事」的工具。
你把"设置字体颜色、加粗、加边框"做一遍,Excel 录下来,以后一键重放。
录完宏后按 Alt+F11 就能看到自动生成的 VBA 代码,你也可以自己改。
重复工作自动化(合并报表、批量处理)、创造 Excel 没有的功能、跟数据库/邮件等外部程序交互。
基础操作很简单——录制宏→改改代码就能用。不需要编程基础,跟着学就行。
文件 → 选项自定义功能区 → 右侧勾选 「开发工具」 → 确定Visual Basic 和 录制宏 按钮Alt + F11 打开 VBA 编辑器看看——以后写代码都在这里。?Range(\"A1\").Value 然后回车,立刻显示A1的值——不用写完整代码就能测试。
开发工具 → 录制宏 → 宏名输入 "设置标题样式"Ctrl+Shift+H → 确定 → 开始录制停止录制Alt+F8 → 选"设置标题样式" → 执行 ✅ 自动变样式了!Sub ... End Sub — 一段宏(过程)的开头和结尾Selection — 当前选中的单元格.Interior.Color — 单元格背景颜色.Font.Bold — 字体粗体' 绿色文字 — 注释,不参与运行,写给看的
题目:录一个宏,把选中单元格设为"蓝色底 + 白色字体 + 居中"。然后看看生成的代码。
| A | B | |
|---|---|---|
| 1 | 100 | 张三 |
| 2 | 113 |
Integer 整数(-32768~32767) | Long 大整数 | Double 小数String 文本 | Boolean True/False | Date 日期Dim x As Variant(万能类型,但慢一点)
| A | B(运行后) | |
|---|---|---|
| 1 | 85 | 及格 |
| 2 | 95 | 优秀 |
| A | |
|---|---|
| 1 | 1 |
| 2 | 2 |
| … | … |
| 10 | 10 |
For i = 1 To 100 → 知道要循环多少次For Each x In 集合 → 遍历所有对象Do While 条件 → 不知道多少次,条件满足就停
题目:写一段 VBA,把 B1 到 B10 分别填上 10、20、30……100。
Excel VBA 里一切都是对象——单元格是对象、工作表是对象、工作簿也是对象。
你可以对对象做两件事:读/写属性(如 .Value, .Name)和 调用方法(如 .Copy, .Delete)。
| 操作 | VBA 代码 | 说明 |
|---|---|---|
| 读写单元格 | Range("A1").Value = 100 | 写值 |
| 读取单元格 | x = Range("A1").Value | 读值到变量 |
| 合并单元格 | Range("A1:C1").Merge | 合并A1到C1 |
| 取消合并 | Range("A1:C1").UnMerge | 拆分 |
| 设置字体颜色 | Range("A1").Font.Color = RGB(255,0,0) | 红色 |
| 设置底色 | Range("A1").Interior.Color = 65535 | 黄色 |
| 加边框 | Range("A1").Borders.LineStyle = xlContinuous | 实线边框 |
| 复制 | Range("A1").Copy Range("B1") | 复制粘贴 |
| 删除行 | Rows(3).Delete | 删除第3行 |
| 插入行 | Rows(3).Insert | 在第3行上方插入 |
| 删除列 | Columns("C").Delete | 删除C列 |
| 选中 | Range("A1").Select | 选中 |
| 清空内容 | Range("A1:A10").ClearContents | 只清值,保留格式 |
| 清空全部 | Range("A1:A10").Clear | 清值和格式 |
| 找最后一行 | Cells(Rows.Count, 1).End(xlUp).Row | A列最后有数据的行号 |
题目:写代码把 Sheet1 的 A1 到 D10 区域设为:字体蓝色、底色浅灰、加实线边框。
事件就是「当XX发生时,自动运行的代码」——
你修改了单元格 → 自动检查数据是否合法
你打开了工作簿 → 自动显示欢迎信息
你选择了工作表 → 自动刷新数据
Sheet1Worksheet,右选 ChangeWorksheet_Change 框架,在里面写代码↓ThisWorkbookWorkbook,右选 Open| 事件名 | 写在 | 触发时机 |
|---|---|---|
| Worksheet_Change | Sheet 代码页 | 单元格内容被修改 |
| Worksheet_SelectionChange | Sheet 代码页 | 选中不同的单元格 |
| Worksheet_BeforeDoubleClick | Sheet 代码页 | 双击单元格(可取消默认行为) |
| Workbook_Open | ThisWorkbook | 打开工作簿时 |
| Workbook_BeforeClose | ThisWorkbook | 关闭工作簿前 |
| Workbook_SheetActivate | ThisWorkbook | 切换到任一工作表时 |
.xlsm 格式,否则事件不会运行。
题目:让 Excel 在关闭时自动保存,并弹窗提示"已保存,再见!"
| 姓名 | 基本工资 | 奖金 | 扣款 | 实发 |
|---|---|---|---|---|
| 张三 | 5,000 | 2,000 | 500 | 6,500 |
| 李四 | 6,000 | 1,500 | 600 | 6,900 |
| 王五 | 4,500 | 3,000 | 400 | 7,100 |
VBA 有强大的调试工具,不用猜哪里错了,直接看代码一步步执行。
按一下执行一行,可以看到每行代码的效果,找到哪一行出问题。
在某行点一下(或按F9),运行到这一行会自动暂停。
输入 ?变量名 查看变量当前值,输入 变量名=新值 修改变量。
调试暂停时,把鼠标放在变量上,会显示当前值。
在代码里写 Debug.Print 变量名,运行后在立即窗口看输出。
遇到错误跳过继续执行(谨慎使用,最好配合错误判断)。
?变量名 查看/ 分隔了数据(如 A列="张三/李四",B列="技术部/工程部"),想拆成一一对应的多行。
| A 姓名 | B 部门 | C 职位 |
|---|---|---|
| 张三/李四 | 技术部/工程部 | 工程师 |
| 赵六/钱七 | 市场部 | 经理/主管 |
| A 姓名 | B 部门 | C 职位 |
|---|---|---|
| 张三 | 技术部 | 工程师 |
| 李四 | 工程部 | 工程师 |
| 赵六 | 市场部 | 经理 |
| 钱七 | 市场部 | 主管 |
Array(文本) 把单值也做成数组,统一处理逻辑
题目:如果分隔符不是 / 而是顿号(、),代码要怎么改?
Trim() 去掉| 写法 | 说明 |
|---|---|
Dim x As Integer | 整数(-32768~32767) |
Dim x As Long | 长整数(-21亿~21亿) |
Dim x As Double | 小数 |
Dim x As String | 文本 |
Dim x As Boolean | True / False |
Dim x As Date | 日期 |
Dim x As Range | 单元格区域(必须用 Set) |
Dim x As Worksheet | 工作表(必须用 Set) |
| 想做什么 | 代码 |
|---|---|
| A列的最后一个有数据的行号 | Cells(Rows.Count, 1).End(xlUp).Row |
| 当前区域的行数 | Range("A1").CurrentRegion.Rows.Count |
| 弹消息框 | MsgBox "你好" |
| 弹输入框 | x = InputBox("请输入年龄") |
| 让Excel暂时不刷新 | Application.ScreenUpdating = False |
| 让Excel重新刷新 | Application.ScreenUpdating = True |
| 关闭警报(删表时) | Application.DisplayAlerts = False |
| 打开警报 | Application.DisplayAlerts = True |
| 等待2秒 | Application.Wait Now + TimeValue("00:00:02") |
| 当前时间 | Now() |
| 当前日期 | Date() |
| 快捷键 | 作用 |
|---|---|
| Alt + F11 | 打开/关闭 VBA 编辑器 |
| Alt + F8 | 查看/运行宏 |
| F5 | 运行宏 / 继续运行 |
| F8 | 逐行执行(调试) |
| F9 | 设置/取消断点 |
| Ctrl + G | 打开立即窗口 |
| Ctrl + Break | 强制停止正在运行的宏 |