简明Excel VBA
本文集同步于GitHub仓库:# bluetata/concise-excel-vba
1.9 补充
- 在vba中使用
'
进行代码注释 - 在很长的语句中使用
_
来分割成多行 - 在有很多嵌套判断中,代码的可读性会变得很差,一般讲需要返回的内容及时返回,减少嵌套
-
Sub
中默认按引用传递参数,所以注意使用,一般不要对外面的变量进行修改,将封装保留在内部
-
Dim
和Set
的关系及区分
很明显的是 vba中使用Dim设定变量类型,Set将对象引用赋值给变量
' 将Range对象赋值给变量rg
Dim rg As Range ' 声明rg为Range对象
Set rg = Range("A1") ' 设定rg为Range("A1")的引用,之后操作rg和操作Range("A1")一样了
' 如果不使用Set,下面的代码将报错
Dim rg As Range
rg = Range("A1") ' 这段代码将报错
' 在非显示声明rg的前提下,下面的代码将会得到不一样的结果
rg = Range("A1") ' rg将会是Range("A1")的内容,rg的类型将会是一种基本类型,Integer/String等
Set rg = Range("A1") ' 这种情况下,rg将会是Range对象
- VBA中变量用Dim定义和不用Dim定义而直接使用有何区别?
用Dim语句声明变量就是定义该变量应存储的数据类型;
如果不指定数据类型或对象类型,也就是不用Dim定义,且在模块中没有 Deftype
语句,
则该变量按缺省设置是 Variant
类型。
- VBA中用Set赋值和不用Set赋值有什么区别?
给普通变量赋值使用Let
,Let 可以省略。</br>
给对象变量赋值使用Set
,Set 不能 省略。
Sub AssignString()
Dim strA As String
Dim strB As String
strA = "hello" ' 本句也可写成 LET strA = "hello"
Set strB = "hello" ' 错误写法/Compile error
EndSub
<a name="1.10"></a>
1.10 示例
举个排序的例子,要对A1:A20
的单元格区域进行排序,区域内的内容为1-100的随机整数,
规则是大于50的倒序排列,小于50的正序排列。将结果显示在B1:B20
的区域里。
在这个例子中,首先定义一个Sub
过程来随机生成A1:A20
区域的内容。
代码如下:
' 创建随机整数,并赋值
Sub createRandom(times As Integer)
Dim num As Integer
Dim arr() As Integer
ReDim arr(times)
For num = 1 To times
Randomize (1) ' 初始化随机数
arr(num) = Rnd(1) * 10000 \ 100 ' Rnd随机数函数生成0~1的浮点数
' 上面使用了运算符进行取整,也可以根据需求使用vba内部的取整函数达到同样的效果
' arr(num) = Int(Rnd(1) * 100)
' arr(num) = Round(Rnd(1) * 100)
Range("A" & num) = arr(num)
Next num
End Sub
' 自定义排序
Function defSort(rgs) As Variant
Dim arr() As Integer
Dim total As Integer
Dim rg
Dim st As Integer ' 数组开始标记
Dim ed As Integer ' 数组结束标记
Debug.Print "rgs类型:"; TypeName(rgs)
total = UBound(rgs)
ReDim arr(total)
st = 1
ed = total
' 对数组分区
For Each rg In rgs
If rg > 50 Then
arr(ed) = rg
ed = ed - 1
Else
arr(st) = rg
st = st + 1
End If
Next rg
Dim i As Integer
Dim j As Integer
Dim tmp As Integer
' 冒泡排序
For i = 1 To total
For j = i To total
If arr(i) > 50 And arr(j) > 50 Then '大于50的倒序排列
If arr(i) < arr(j) Then
tmp = arr(i)
arr(i) = arr(j)
arr(j) = tmp
Debug.Print "大于50的"; i; j; tmp ' 程序运行过程中在立即窗口显示执行内容,用于调试程序
End If
Else If arr(i) <= 50 And arr(j) <= 50 Then ' 小于50的正序排列
If arr(i) > arr(j) Then
tmp = arr(i)
arr(i) = arr(j)
arr(j) = tmp
Debug.Print "不大于50的"; i; j; tmp
End If
Else
Exit For
End If
Next j
Next i
defSort = arr
End Function
' 程序入口
Sub main()
Const SORT_NUM = 20
Dim rgs
Dim arr
createRandom SORT_NUM ' 初始化待排序区域
rgs = range("A1:A" & SORT_NUM)
arr = defSort(rgs)
' 循环赋值
For i = 1 To SORT_NUM
range("B" & i) = arr(i)
Next i
End Sub