一、问题导入
问题描述:
文件“DEMO-2-使用数组大幅度提升VBA代码执行效率”中有20万条记录,需要根据区域求汇总金额,用for循环处理(
注意i不能定义为integer,溢出
),耗时较长。
处理过程:
(1)希望准确记录耗时,引入
timer函数
(返回从午夜到现在经过的秒数),运行前
t=timer
,运行后“MsgBox
Timer - t
”
(2)耗时较长的原因在于:
每次循环都要到单元格“n5”中取值
,若每次是取变量值,则速度大幅提高,因此dim str as string,
str=range("n5")
后,
替换循环中的“n5
”
(3)将
for循环中的单元格取数替换成变量取数,能大幅提升速度
,能否将其中每次循环的到Range("g"&i)取数替换成变量?
(4)i从2到200000,Range("g"&i)是一系列数字在一起,因此是数组,引入数组概念。
定义数组
:
Dim arr()
给
数组赋值
:
arr=range("a1:d7")
,
如何取数?
(5)用一小段区域演示数组取值
arr(x,y)
,其中x是数组区域的行数,y是数组区域的列数;
(6)用数组替换原代码,大幅提升速度。
二、进一步认识数组
“”认识数组“文件”:(1)数组分一维、二维、多维,上例是二维数组;
(2)
一维数组
定义时应指定标号范围,如Dim arr(
1 to 5
),否则容易报错;
(3)可一个一个地将一维数组的值赋给
变量
,如
i = arr(2)
,也可一次赋给
区域
,如
Range("a1:e1")=arr
;
(4)
一维数组默认是行方向
数组,因此
只能给行区域一次性赋值
,若给列区域赋值,如Range("a1:a5")=arr,结果是列区域获得的值都是arr(1);
(5)若
用区域给数组初始化
,则无论区域如何,
生成
的是
二维数组
,如
arr=Range("a1:a5")
,虽仅一列,但赋值时需用二维方式:Range("c1")=
arr(2,1)
(6)回顾split函数截取字符,生成的结果是数组,进一步理解该函数的应用。
三、
进一步认识数组
(查找销量冠军)
问题描述:要完成表中“销售额最高的产品“和”该产品的销售额”,传统做法需新建辅助列进行计算后查询填入,较麻烦,有时甚至不方便操作辅助列。
处理过程:(1)引入数组,规避辅助列问题,如下左边代码;
(2)用Application.WorksheetFunction.
Max
(arr)查询到最大的销售额,填入;
(3)需找到其对应产品名称,先找其在数组中位置为:Application.WorksheetFunction.
Match
(Range("h3"), arr, 0) + 1,因此可得产品名称为
Range("a" &Application.WorksheetFunction.
Match
(Range("h3"), arr, 0) + 1)
tips:
Matc
h
(要在表中查找的值, 可能包含所要查找的值的连续单元格区域, 0),其中0代表等于匹配,返回相应位置
(4)上述解决过程的缺陷在于需事先确定数组大小,但往往不易确定。改进:
先定义
为不定
arr()
,再
redim
。(不允许直接以变量dim arr(1 to j))
(5)了解两个函数:
UBound
(arr)
,
LBound
(arr)
,分别返回数组标号的上下限,用其可方便构造数组的循环。