ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 95284|回复: 207

[分享] VBA数组通俗教程(初稿)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2011-10-3 17:54 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:数组集合和字典
本帖最后由 怀英慕者 于 2011-10-3 17:55 编辑





VBA数组通俗教程.rar (13.72 KB, 下载次数: 6071)

评分

14

查看全部评分

TA的精华主题

TA的得分主题

发表于 2011-10-3 18:03 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
感谢楼主    已收藏学习

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-10-3 18:07 | 显示全部楼层

VBA数组通俗教程(初稿)

怀英慕者  编写

序言

关于写作理念

相信很多朋友都有这样的抱怨,微软的帮助文档怎么看都看不明白,乱七八糟的!又或者,某某计算机教程写的跟微软自带帮助一样,看不明白!再或者,计算机根本就没法学,教科书全是专业术语,全是英文!当然,会有另一些朋友站出来辩驳,说学计算机就得硬着头皮,就得掉层皮!或者,你得从基础学起,什么硬件啊、结构啊、算法啊!如此看来,我们想尝尝牛肉的滋味,必须先得宰头牛,还得全咽下去!还有一些朋友提倡多动手去做,做得多了就会了,论据是原始人最开始是没有教科书的。
以上朋友的困惑我也遇到过,抱怨过,那些出主意的朋友说的也不失为一种学习的方法。但是,我始终认为,学习并不一定是件苦差事。我还拿《明朝那些事儿》打比方,很多朋友都读过这本书,没读过的百度一下,是本好书。我自小是喜欢历史的,相反,很多同学却十分的没兴趣。为什么?满页满页的人物、时间、事件、意义。其实则不然,用人大教授毛佩琦的话说“历史是如此生动活泼,丰富多彩!为什么到了史学家手里就变得枯燥无味了呢?历史学家就不能把生动活泼的历史呈现给大众吗?是受制于能力、才力,还是受制于观念?” 《明朝那些事儿》就是“以史料为基础,以年代和具体人物为主线,并加入了小说的笔法和对人物的心理分析,以及对当时政治经济制度的一些评价”,于是我最不喜欢和最不愿读的明史也变得兴趣盎然了!那么以此类推,计算机是如此生动有趣,丰富多彩!为什么到了计算机专家手里就变得枯燥无味了呢?计算机专家就不能把生动有趣的知识呈现给大众吗?是受制于能力、才力,还是受制于观念?
有人就要说了,计算机教科书写的“嬉笑怒骂”、“俗不可耐”就失去了它的严肃性和权威性,就学不到严谨的知识!朋友,语言形式的通俗生动就不能清楚的表达正确内涵了吗?就一定要操着一口标准的普通话说“是谁啊?是我啊!干什么?上厕所。”你才能明白?!如果变成“谁?我!抓?(河南方言:意为干什么)尿。”你就听不懂了?就影响理解了?!我们自问,现实生活中,自己也是这么一本正经的说话吗?
由此看来,知识并非就是晦涩难懂的,难就难在编著者写书的“观念”。
因此,凡是以书面形式的东西就要它“书面”,就要把它包装成“权威”的模样,就要让你望而生畏,就要让你看不懂!不然你这位“学究”就贻笑大方了!
我很敬佩唐代诗人白居易,他的诗向来通俗易懂,传说他每次写完诗总要先念给一位不识字的老婆婆去听,听不懂的他就修改,直到能听懂为止。白居易就是这样做了,难道他的诗人地位受到了挑战?
又有人说,《阳春白雪》(高雅音乐)和《下里巴人》(通俗音乐)都应该受到重视。这点我不否认,但是,你不能把所有的东西都做成《阳春白雪》的标准吧!如果是那样,还有几个人有能力去接受它?很难接受或不能接受的东西,就失去了好的意义,也就失去了存在的价值。
计算机教程的读者并不一定都是科班出身,十成里面有一成系统学过计算机就不错了!面对他们,教程的编写者也要板着脸之乎者也吗?话说回来,真是计算机科班出身的朋友,自问从零开始就是面对那些枯燥无味的教科书,你们没受过煎熬?你们真正掌握了多少?你们中最后学有所成的十成里又有几成?!
我写这篇文章无意质疑教育制度,只想向朋友们交流我的一种理念,教科书要么不写,要么就要写的通俗易懂。不要想当然的把你的读者进行层次划分,如果一定要定位,那么就定位成你的读者都只有一个基本阅读水平。当然,你可以说你的这本书必须有一定计算机水平的人来读,但也完全没必要就又换成了“学究”的嘴脸,须知,任何高深的知识与高深的讲授语言是不成正比的!

关于这篇教程

为什么要写这篇关于数组的教程,我没有什么太多要说的。只是感觉数组在Excel VBA中作用很大!在读了一些老师们的教程之后,有这么个冲动想用更通俗的语言描述出来。关于数组的学习我只是刚起步,甚至还谈不上入门!但我还是要写,用我的语言写出我对数组的理解,里面肯定有很多东西没有讲述到,有些是我自己还没搞清楚,有些则是觉得实际意义不大。但是,随着进一步的学习,我会对这篇文章进行再加工,最后拿出个成品献给大家,帮助那些曾经和一直困惑着的朋友们!如果我精力有余,我也会再次系统地学习Excel的其他知识,写出一本真正通俗易懂的Excel教科书,让朋友们从此逃出枯燥学习的梦魇!

正文

一、什么是数组?

数组就是对单元格区域的另一种操作方式。
我们知道,VBA是这样做的:
例如我们要对区域B2:D6进行赋值,简单点都填充成1吧。
  1. Sub VBA的方式()
  2.     Range("B2:D6") = 1
  3. End Sub
复制代码
的确很简单,我们常用这种形式对单元格或单元格区域进行赋值或者取值。
可是,数组又是怎么做的呢?

二、数组是这么做的。

还是上面的任务,
  1. Sub 数组的方式()
  2.     Dim arr(1 To 5, 1 To 3) As Integer '声明一个数组
  3.     '---------------------------------------
  4.     arr(1, 1) = 1
  5.     arr(1, 2) = 1
  6.     arr(1, 3) = 1
  7.     arr(2, 1) = 1
  8.     arr(2, 2) = 1
  9.     arr(2, 3) = 1
  10.     arr(3, 1) = 1
  11.     arr(3, 2) = 1
  12.     arr(3, 3) = 1
  13.     arr(4, 1) = 1
  14.     arr(4, 2) = 1
  15.     arr(4, 3) = 1
  16.     arr(5, 1) = 1
  17.     arr(5, 2) = 1
  18.     arr(5, 3) = 1
  19.     '---------------------------------------
  20.     '给数组的每个元素赋值
  21.     Range("B2:D6") = arr  '将数组赋值给单元格区域
  22. End Sub
复制代码
我的天!这不是吃饱了撑的吗?!

三、数组还有用吗?

能用。
原来上面关于数组的代码我们犯了一个常识性错误,就是忘记了循环语句这个利器。怪不得这样编起来比在单元格里直接输入还麻烦!那么修改一下代码:
  1. Sub 数组的方式2()
  2.     Dim arr(1 To 5, 1 To 3) As Integer  '声明一个数组
  3.     '---------------------------------------
  4.     For x = 1 To 5
  5.         For y = 1 To 3
  6.             arr(x, y) = 1
  7.         Next y
  8.     Next x
  9.     '---------------------------------------
  10.     '使用循环语句,给数组的每个元素赋值
  11.     Range("B2:D6") = arr  '将数组赋值给单元格区域
  12. End Sub
复制代码
嗯,这就好多了!原来数组也可以使用循环语句呀,太好了,起码它不是个废品了!
可是比起VBA常用方式,这还是麻烦了啊!

四、黑匣子的秘密。

你知道VBA的运算原理吗?
VBA的运算原理涉及到计算机的运算原理,这是计算机系专业学生要知道的,我们不需要知道,此处略去N本书。但为了让你明白数组的真正有用之处,我又略去N句话,最后用一句话来说明。
原来,VBA中的数据运算最终是在计算机的内存中进行的,假定数据已经存放在内存中,那么就直接进行运算,但如果数据是存放在单元格里的,那就先得把第一个数据从单元格里调入到内存中,然后再在内存中对这个数据进行运算,接下来是第二个一直到第N个。
看出端倪了吧!如果你处理的数据量越来越大的话,VBA执行速度就越来越慢,怪不得有些朋友编的代码能运行几十分钟甚至几个小时!
而数组就好像是一个黑匣子,VBA执行时,先把要处理的所有单元格数据全部放在这个匣子里,再把匣子放进内存,从而避免了反复操作单元格的麻烦。
现在,你还说数组没用吗?不仅能用,而且作用无法估量!
五、我们平时操作单元格数据一般有三种情况:

1、操作一行数据,比如A1:D1填写列标题;
2、操作一列数据,比如A1:A6填写行标题;
3、操作多行多列数据,比如B2:D6填写一个块。
VBA常用的操作方式我们都会,也都很简单,不分情况,常用格式都一样,比如Range("A1:D1")、Range("A1:A6")或Range("B2:D6")。
六、用数组操作却是要分情况的。

我们还是用最简单的例子,就是填充区域为1,看看不同情况,数组的格式有什么不同。
1、操作一行数据,比如A1:D1填写列标题;
  1. Sub 操作一行数据()
  2.     Dim arr(1 To 4) As Integer  '声明一个数组
  3.     '---------------------------------------
  4.     For x = 1 To 4
  5.             arr(x) = 1
  6.     Next x
  7.     '---------------------------------------
  8.     '使用循环语句,给数组的每个元素赋值
  9.     Range("A1:D1") = arr  '将数组赋值给单元格区域
  10. End Sub
复制代码
2、操作一列数据,比如A1:A6填写行标题;
  1. Sub 操作一列数据()
  2.     Dim arr(1 To 6) As Integer  '声明一个数组
  3.     '---------------------------------------
  4.     For x = 1 To 6
  5.             arr(x) = 1
  6.     Next x
  7.     '---------------------------------------
  8.     '使用循环语句,给数组的每个元素赋值
  9.     Range("A1:A6") = WorksheetFunction.Transpose(arr)  '将数组赋值给单元格区域
  10. End Sub
复制代码
3、操作多行多列数据,比如B2:D6填写一个块。
  1. Sub 操作多行多列数据()
  2.     Dim arr(1 To 5, 1 To 3) As Integer  '声明一个数组
  3.     '---------------------------------------
  4.     For x = 1 To 5
  5.         For y = 1 To 3
  6.             arr(x, y) = 1
  7.         Next y
  8.     Next x
  9.     '---------------------------------------
  10.     '使用循环语句,给数组的每个元素赋值
  11.     Range("B2:D6") = arr  '将数组赋值给单元格区域
  12. End Sub
复制代码
三者的不同之处我已经用红色字体标识出来了。
我们发现,前两者的不同在于最后一句多了一个“WorksheetFunction.Transpose()”函数,熟悉函数的朋友都知道,这是一个行列转置函数。那为什么一定要用到转置呢?因为,数组不能直接操作一列的数据,或者说数组只能直接操作一行的数据。不要太纠结,你硬记下来好了,凡是打算操作一列数据时,记着使用WorksheetFunction.Transpose()就可以了!
如果把前两种情况归成一类的话,那么他们和第三种情况的主要区别在于第一句话。前两者是arr(1 To x)这种格式,而第三者是arr(1 To x, 1 To y)这种格式。我们把第一种格式的数组称之为一维数组,而后一种称之为二维数组。

七、数组的维??

我们看动画玩游戏,都喜欢3D动画的,为什么?因为人物场景都是立体的,也就是说人物不像纸片一样贴在屏幕上而是具有纵深感。相反,以前的动画、游戏都是2D的,就是一个平面。3D、2D其实是一种英语简称,全称分别是Three Dimensions和Two Dimensions,翻译成中文就是三维、三个维度、三个坐标或者二维、二个维度、二个坐标。这样就明白了,原来几维就代表几个坐标,终于和我们初中学过的数学联系上了!三维就是x、y、z三个坐标表示一个立体的点,二维就是x、y两个坐标表示一个平面的点,同理,一维就是x或者y表示水平方向或者垂直方向的一个点。我们学习Excel,知道每张工作表都是由行和列做成的,因此,如果我们单独操作某行或某列数据,就是面对一维的数据;操作多行多列就是面对二维的数据。你见过Excel能表示三维的数据吗?起码我没见过。所以,我们只用记住数组分成两类:一维数组和二维数组就可以了。

八、数组维数的声明。

既然我们知道了数组分为一维的和二维的,那么就要清楚他们二者的声明格式具体有什么不同。我们还看前面的例子:
  
目的
  
类型
声明格式
  
操作某行或某列
  
一维数组
arr(1  To x)
  
操作多行多列
  
二维数组
arr(1  To x, 1 To y)
我们马上产生疑问:1 To x和1 To y分别表示什么?为了让大家看的更明白些,我举例说明。
  
目的
  
例子
类型
声明格式
  
操作某行
  
或某列
  
A1:D1
  
或A1:A6
第一行的1至4单元格
  
或第一列的1至6单元格
一维数组
arr(1 To 4)
  
或arr(1 To 6)
  
操作多行多列
  
B2:D6
每行有1至3个单元格,每列有1至5个单元格的区域,也即5行3列的区域。
二维数组
arr(1 To 5, 1 To3)
这下看明白了,原来在一维数组中,1 To x的x表示你要操作的行或列中有x个单元格;二维数组中,1 To x和1 To y表示你要操作的数据区域有x行,y列。两者完全是不同的概念,因此大家一定要记清楚,一定要分情况声明!

九、数组声明还应该注意一点。

如果大家留心会发现,我前面的所有例子代码中声明数组时都在后面加了句“As Integer”,加这句话有两层意思:
1、说明数组也和VBA中其它变量一样是可以自由定义数据类型的,所不同的是,数组定义数据类型后,数组里面的所有单元格数据都被定义成了同一种类型。
2、我们要养成良好的代码编写习惯,你使用一个变量时一定要先声明数据类型,要根据自己的需要声明合适的数据类型。前面的例子如果把As Integer这句全去掉的话,完全可以正确运行,可是每个数组就被系统默认定义为Variant类型,Integer和Variant区别很大,消耗的内存也大不相同,我们既然使用数组目的就是要使代码运行的快一点,可是图省事不定义数据类型反而会使代码达不到快的运行效果。这一点也需要大家谨记!

十、另一种创建数组的方法

刚才所有的例子都是先创建一个数组,再利用数组对单元格区域进行赋值。实际应用中,我们还可以利用单元格区域直接创建数组,这样做可以省去上面声明数组的麻烦,而且也能更方便、直观地使用数组进行复杂的运算。
下面的例子我们假定A1:B3区域是有数据的,用C1:C3存放前两列的乘积。
  1. Sub 直接创建数组()
  2.     arr = Range("A1:C3")  '直接用单元格区域创建了一个3行3列的数组arr
  3.     For x = 1 To 3
  4.             arr(x, 3) = arr(x, 1) * arr(x, 2)  '把数组前两列相乘的结果赋值给第三列
  5.     Next x
  6.     Range("A1:C3") = arr '将新的数组结果赋值给原单元格区域
  7. End Sub
复制代码
你看,蓝色代码是不是很像传统VBA那样简洁的操作?

十一、工具是死的,人是活的。

截至目前,相信你已经对数组有了大致的认识,也能使用它进行日常的工作了。可是遇到复杂的工作,也还是觉得无从下手,你又会求助高手帮忙,他们也会用到数组。可当看到人家那密密麻麻的代码时你傻眼了!你看到里面确实用了数组,可就是弄不明白你眼前的数组和你学的数组怎么就联系不上!我告诉你原因,并非你学了《九阴假经》,你的和他的一样,所不同的是人家运用了巧妙的算法在里面,工具是一样的,人家把工具用活了!

十二、最后的话。

其实计算机编程里面有门很重要的学科就是算法,我没学过算法,但我的理解就是解决问题的办法,打个比方就好像你打算去公园,可以骑自行车去,也可以坐公交或者打的,甚至你也可以步行,交通工具就如同函数、VBA、数组等等,但只有交通工具也并不能很好地解决问题,南辕北辙的故事就说明了一切,所以,除了要有合适的工具,恰当的路线也是至关重要的,路线就是方法,就是算法。我们首先要努力熟练掌握各种工具的特性,然后根据实际问题认真分析制定出合适的算法,这样才能达到事半功倍的效果。算法的提高我觉得一要多动脑筋自己思考,二要多参考经典问题的经典解决办法,学会融会贯通。

评分

13

查看全部评分

TA的精华主题

TA的得分主题

发表于 2011-10-3 18:30 | 显示全部楼层
楼主现在应该切身体会到,写好教程是一件很难的事情了吧。。。

TA的精华主题

TA的得分主题

发表于 2011-10-3 18:35 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-10-3 18:36 | 显示全部楼层
灰袍法师 发表于 2011-10-3 18:30
楼主现在应该切身体会到,写好教程是一件很难的事情了吧。。。

是挺难!欢迎批评指正!

TA的精华主题

TA的得分主题

发表于 2011-10-3 18:42 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-10-3 18:47 | 显示全部楼层
guzhen9315 发表于 2011-10-3 18:42
感谢楼主!
谢谢!
学习。

谢谢灰袍老师的鼓励和支持!!
也感谢各位朋友的热情关注!希望大家多提意见!!

TA的精华主题

TA的得分主题

发表于 2011-10-3 18:58 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2011-10-3 19:56 | 显示全部楼层
谢楼主分享,节日里辛苦了!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 17:35 , Processed in 0.044418 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表