(一) 启动VBA
打开excel ,选项-自定义功能区-开发工具, 在界面的开发工具下选择 宏安全: 勾选 启用所有
excel保存xlsm后缀的格式才可以用宏!
若启动VBA编辑器(以下简称VBE)出现内存溢出, 自行百度, 更改一个programs 下的一个文件即可.
点击上述第一个 visual basic 打开编辑器界面如下, 或者Alt+F11快捷键.
这个是工程资源管理器, 不同类型的代码要写在不同的地方,
microsoft excel对象存放事件编程代码; 窗体存放程序代码; 模块存放标准代码; 类模块存放类代码.
一开始在界面中并没有看到模块, 窗体? 右击sheet1, 插入模块; 右击模块 ,可插入模块2...
(二)VBA 基础知识
(1)单击 宏 可以查看当下所有的宏代码, 并进行编辑
(2)VBE 中可以调出一个立即窗口, 输入命令后 按enter即可运行 (视图--立即窗口)
(3)在excel 世界里, 数据只有5种类型: 文本 数值 日期 逻辑值 错误值 (事实上,日期型也是数值)
VBA 的数据分类更细, 有 布尔型 字节型 integer long(长整数) single(单精度浮点) double currency decimal(小数) date string(定长/变长) 对象object
(4)声明变量的语法
dim 变量名 as 数据类型
dim i as integer
还可以用指定的符号表示数据类型: integer-->%, long-->& , single-->!, double-->#, currency--> @, string-->$
dim s$ 等价于 dim s as string
也可以不指定变量类型, 直接 dim s, 还有三种类型:
private i as string , public i as integer
static i as string 静态变量 保持原值不动
dim , static 声明的都是本地变量,作用于就是本过程,
如何定义可以在多个过程中都使用的变量? 此时变量定义需要放在sub (过程)之前..
Option Explicit Dim a Dim b Sub demo1() a = MsgBox a End Sub Sub demo2() b = MsgBox b End Sub
上述 a b被定义为模块级变量, 在这个模块中的任意过程都可以使用它们, 什么变量在不同模块也可以用呢? 公共变量 public s as string
(5)变量赋值
一般变量就直接 i=100, 对象变量需要用到 set
dim w as worksheet 先声明
set w=activesheet 再赋值, 赋值为当前活动sheet
(6) 排版问题
如果一行代码太长了 需要换行, 用空格+下划线 _ 再 enter 换行即可
多行代码显示为一行, 特别是在dim 声明中可以直接赋值了, % 表示integer
dim a %,b%:a=1:b=2
事实上, VBA看到冒号 : 认为这是两行代码分开的地方
如何注释块?
选择多行之后 会自动弹出一个编辑栏. 有注释块 选项, 如果没有自动出现, 则在视图-->工具栏-->编辑 即可调出来!!
(三)设计一个口算器-简答加法( 按钮 ,写在标准代码中)
在不同单元格 输入式子, 插入(第一个图案就是按钮)-- 用鼠标拖一个按钮出来
接着, 在 指定宏 窗口 修改宏名(改为做加法)--> 新建
在模块1中输入: (cells(m,n)表示单元格, m,n 分别表示行 列, 跟矩阵一样)
Sub 做加法() Cells(, ) = Cells(, ) + Cells(, ) End Sub
关闭编辑器后,就实现了!
按钮太丑了? -->右击按钮, 可以编辑文字, 调节大小..
进一步, 增加减法, 现在换一种方法制作一个按钮: 插入一个按钮, 拖出按钮方块后,不新建 , 而是取消.
右击原来的按钮1, 指定宏-->编辑. 输入下面的代码,VBE其实自动会帮你写 很多东西..你写完sub 自动会增加end
保存关闭后, 点击按钮3 没反应?why? 因为还没有关联一个宏, 右击该按钮--指定宏-- 选择做减法就行了!!
但是有个小问题, 做减法的时候符号未变, 还是原来的+ , 怎么处理? 设置如下
注意, 要用双引号,不能用单引号!
进一步, 现在有很多行计算题, 输入所在行的行号, 显示答案
引入一个变量x 表示行号
Sub 做加法() x = Cells(, ) Cells(x, ) = "+" Cells(x, ) = Cells(x, ) + Cells(x, ) End Sub
输入不同的行号, 点击查看按钮, 即可看到该行的答案!
(四) 变量的应用-圆的计算
变量可以用英文 中文, 数字 下划线, 虽然VBA可以用中文做变量名,但是不建议采用!变量开头不能以数字开头, 也不能和系统的保留字一样, 对大小写不敏感(你敲小写的会自动给你改成大写开头的! ), xx =XX
Sub 圆的计算()
x = Cells(, ) y = 3.14 * x * x Z = / * 3.14 * x * x * x Cells(, ) = y Cells(, ) = Z End Sub
如果上述出错了, 某个变量不小心写成了x1, 结果如何??
Sub 圆的计算() x = Cells(, ) y = 3.14 * x * x Z = / * 3.14 * x * x * x1 Cells(, ) = y Cells(, ) = Z End Sub
可以看到体积=0 , 但是没有报错, 计算机自动认为这个x1=0;
因为对于一个新来的变量,VBA 会自动创建这一变量, 并且赋默认初值=0;
可是如何让程序报错呢?? 在sub外面增加Option Explicit
sub里面Dim x, y, z 声明本宏需要用到的变量..
此时再运行就会报错!!
Option Explicit 叫做强制声明, 这个非常重要!!
补充: 定义一个常量, 它不能被修改 , 声明赋值方法 Const pi = 3.1416 即可
(五)for循环
实现美元人民币的转换, 做两个按钮, 一个显示美元的收入, 另一个显示人民币的收入
上述代码如下:
Sub 美元价格() Dim rate, i , ) Cells(i, ) = Cells(i, ) / rate Next i Cells(, ) = "USD" End Sub Sub 按钮6_Click() Dim rate, i , ) Cells(i, ) = Cells(i, ) * rate Next i Cells(, ) = "CHN" End Sub
注意: 其中next i 的 i 可以省略, step 1 是默认的也可以省略
但是step 2, step -1... 等不可以省略
(六)if 使用
实现成绩判定
Sub 成绩评定() Dim avg avg = (Cells(, ) + Cells(, ) + Cells(, )) / Cells(, ) = avg Then Cells(, ) = "fail" Else Cells(, ) = "pass" End If End Sub
若成绩分为ABCDF 五个等级, 则要运用 elseif,
Sub 成绩评定() Dim avg avg = (Cells(, ) + Cells(, ) + Cells(, )) / Cells(, ) = avg Then Cells(, ) = "A" Then Cells(, ) = "B" Then Cells(, ) = "C" Then Cells(, ) = "D" Else Cells(, ) = "F" End If End Sub
注意: then 不要漏写
如果if 的条件太多了,为了减少程序判断次数, 用 select case... end select 更好
Sub test() Select Case Range("A1").Value Range("A2").Value = "A" Range("A2").Value = "B" Range("A2").Value = "C" Range("A2").Value = "D" Case Else Range("A2").Value = "F" End Select End Sub
(七) 程序调试
程序有三种模式: 设计 中断 运行
程序如下, 但是上述有点问题, 如何调试呢?
设置断点, 变为红色, 点击按钮, 程序运行
断点就像是高速公路的检查站, 到了必须停下来检查, 程序会在断点处进行检查, 进入程序的中断模式.
除了设置断点, 也可以写 stop 语句的形式中断代码
在立即窗口中查看变量x: debug.print x
但是到了断点行变为黄色, 程序停止, 这时需要逐步运行 F8
想要知道某个变量的值, 鼠标移动过去, 自动会显示的
当然一直用鼠标点也不好用, 可以增加监视变量: 调试--添加监视, 输入变量名即可!! ,那么在下部会出现这些变量的值
也可以选中某个变量, 快速监视
想要停止程序 则单击以下工具:
注意: 上述在调试的过程中, sheet 中的结果也在变化了, 已经在运行了!!
出现错误是, 可能用得到的语句
1. on error goto a
a: msgbox " 出错了"
养成好习惯, 提高代码运行效率
1. 声明变量为合适的数据类型
2. 少用variant 类型的变量, 它的存储空间较大
3. 不要让变量一直呆在内存中, 少用public !
如果一个变量不用了, 记得释放他们
Sub test() Dim r As Range Set r = Range("A1:B3") r = Set r = Nothing ' 释放变量 End Sub
4. 不要让代码执行多余的操作, 很多录制宏得到的代码非常冗余 , 需要删减下
5.合理使用数组
例: 将1-1000写入到工作表的A1 列
可以借助循环语句
Sub test1() Dim t0 As Double t0 = Timer Dim i As Long Cells(i, "A").Value = i Next i MsgBox "运行时间是" & Format(Timer - t0, "0.00") & "秒" End Sub
换一种方法, 写入数组在将数组一次性写到单元格中
Sub test2() Dim t0 As Double t0 = Timer ) As Long arr(i) = i Next i Range("A1:A1000").Value = Application.WorksheetFunction.Transpose(arr) MsgBox "运行时间是" & Format(Timer - t0, "0.00") & "秒" End Sub
运行时间只有0.01秒, 注意需要写成range("A1:A1000"), 就要精确写区域的范围, 不能写成range("A").
.