楼主 liuguansky |
[友情提示:如果感觉这里的排版不堪入目,请直接下载附件,上面有DOC的良好排版。] 初识VBA数组: [注:以下言论仅为笔者初学VBA几日的一些看法,如有不对之处,敬请海涵雅正。] 从最开始接触VBA什么都不懂开始,到现在大致可以看懂一般的代码,感觉数组贯穿了笔者学习VBA的始末。 数组以它处理问题的便捷[二维数组与工作表的行列相对应,更具直观性,处理起来能得心应手。]、高效[从内存调用变量,避免频繁调用对象而造成代码的速度迟缓;同时结合循环,可以让问题更快、更灵活的得到解决。]得到了很多高手的亲睐,希望此文能对初学者有所帮助。 [以下说明,仅针对笔者数组学习中所困惑、不易掌握、易忽略的知识点,其他知识点请参考相关数组资料自行学习。] 说在前面: 学习VBA,初期最重要的一点是养成编写代码的好习惯。从学代码的初期就应该严格要求自己,从优化、通用、准确着手来编写代码。 1.定义变量类型; 定义变量类型可能有时初学者不以为然,认为定义不定义都无所谓,为了偷懒往往不愿意花时间去定义类型,这是个很不好的习惯。 因为有时定义一个类型可能会让你的代码的速度提升好几倍。 2.通用可延伸性; 有时对数组源的处理的时候,不喜欢去判断是否为””,或者不去用条件去判断区域,而直接引用一个固定的区域,还有就是喜欢用currentregion等 在数据源增加的时候容易出错的表达形式。 又或者,union的时候不判断RNG IS NOTHING的情况,字典返回的时候不判断DIC.COUNT>0的情况等。 再就是版本通用性的时候,比如我们取某列最后一个非空单元格的行号: ["a65536"].end(3).row 其实这里在07版本就不很适用,可以小改动下就可以了 Cells(rows.count,1).end(3).row 3.循环中尽量在内存中进行取值 有时可能循环时,可以直接引用单元格来进行处理,代码可能会简单一点,但效率却差很多,所以要养成不在循环中引用对象的习惯。 4.区域赋值时,先清空区域,这样效率也会快很多,而且避免多次运行代码出现错误情况。 一、数组的元素。 数组,简单的说就是用一个名称通过下标[或索引]来区分引用多个值。――>为创建循环提供便利。 数组中的元素可以是不同类型的数据,也可以是相同类型的数据。 一般我们可能听说过,就是定义一个变量特定类型,会比不定义特定类型速度要快。对数组而言,如果所赋值元素均为统一类型,可以定义数组元素类型。如: Dim arr as integer '定义一维数组,后面可以不用加(); Dim arr() as integer'定义多维动态数组,后面一定要加(),否则在动态定义redim preserve时会造成“类型不匹配错误”; Dim arr(1 to 3) as long'直接定义静态一维数组; Dim arr(1 to 2,2 to 4) as string'定义静态二维数组; 当未指定类型时,默认数组类型为Variant.数组大肚能容,元素可以是几乎任意东西,当然可以是数组。如果维度不同的元素数据类型不同的话,请定义为Variant类型。 因为一般工作表的源数据会有文本,数值等,所以定义数组用来存放单元格内容的话,一般直接定义为Variant. 二、数组的下上界 我们知道可以用Lbound,ubound来返回数组的下界与上界,也知道可以用option base0 & 1 来调整下界的默认值。这里有几点注意的地方: 1.当我们把单元格区域赋值给一个数组的时候 比如 arr=range(“a1:c10”),抑或 arr=range(“a1:a10”) ,甚至 arr=range(“a1:e1”)。 我们可以在本地窗口中发现,arr总是个二维的数组。行代表第一维,列代表第二维。而且下界总是从1开始的,不受option base 0 的影响。 从而我们也可以知道:一维数组对应工作表单元格区域是一行。那么当我们赋值给单元格时,如何把一维数组赋值给一列呢? 三、赋值单元格区域 当我们把一维数组赋值给一列时,因为维度的不对应性,可以用工作表函数transpose来进行转置后赋值给单元格。如 Dim arr as integer '定义一维数组 Dim I% '定义变量,用于循环给数组元素赋值 ReDim arr(1 To 30000) '定义数组下界,上界 For i=1 to 10 '循环赋值 Arr(i)=i^2 '因为设定数组下界从1开始 Next i Cells(1,1).resize(10,1)=application.worksheetfunction.transpose(arr)'转置赋值给单元格区域 先用循环赋值给变量,再一次性把对象赋值给单元格对象。 这是最简单的一个代码优化思想:在循环中尽量避免引用对象,因为引用对象会浪费很多的时间。 请看下面代码的测试结果:
一般我们要在一个单元格区域返回值,可以定义一个与单元格区域相符合大小的数组来存放结果,再一次性的返回给单元格区域。 主要是避免在循环中引用单元格对象。 下面这里是另外一个优化技巧: 就是在赋值单元格区域时,先清空区域,可以提升速度。同时也可以避免多次运行代码产生错误结果。 四、数组元素赋值与运算相关函数 下面说明一些数组赋值与运算中经常会用到的函数与技巧: 1.判断是否为数组:isarray() 2.返回下界,上界:lbound(数组arr,N维度),ubound(数组arr,N维度) 可以用于循环的初末值设定、返回数组的元素个数等 3.Join函数:返回一个字符串,该字符串是通过连接某个数组中的多个子字符串而创建的。[仅针对一维数组有效][对多维数组的思考:用INDEX返回一维后再JOIN?] 例:
这里只是提供一种思路,有兴趣的朋友可以比较下JOIN这样的连接方式与一次循环的速度。
说明: 1.JOIN只针对一维数组,非一维数组的使用,要进行转换为一维,或用其它思维进行。 2.用于字符串组合生成的时候可以考虑。[优先考虑] 4.Filter函数:返回一个下标从零开始的数组,该数组包含基于指定筛选条件的一个字符串数组的子集。 Filter([, include[, compare]])
免责声明 有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素,
经与ExcelTip.Net站长Apolloh商议并征得其同意,
现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示,
供有需要的人士查询使用,也慰缅曾经的论坛时代。
所示各个帖子的原作者如对版权有异议,
可与本人沟通提出,或于本站点留言,我们会尽快处理。
在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
猜您喜欢
评论列表
搜索
|