分享

【20180907】-VBA中数组、集合和字典(二)——对数组变量的赋值

 L罗乐 2019-08-18

本文转载自公众号:SUT事务所,作者:党药中。本文著作权归原创作者所有,本人收藏此文仅作为学习之用,不作其他目的,如有侵权请联系我删除。

大家好,我是中药党。

上次我们对比学习了一下ExcelVBA中数组、集合和字典的概念和声明语法,我个人觉得在声明部分,三者的区别还是挺大的。下面我们一块学习一下赋值方面的知识点,因为内容较多,我们今天就先学习一下给数组变量赋值的内容。

数组赋值

不管是数组、集合还是字典,都有向变量赋值的操作,赋值也是这几个概念的核心和关键,操作也有很大不同。

1.向数组变量赋值

对数组来说,数组中的每个元素数据类型必须相同,从数组声明就可以看出,这是数组与集合和字典的明显不同。这就要求向数组变量赋值时的数据规范必须严格。

a.向数组中单个数组元素的赋值

当数组已经确定了长度,我们就可以对数组内的元素进行赋值。可以对数组中某一具体索引位置的数组元素进行写入的,如下图:

当数组长度还不确定,在代码运行过程中发现有满足条件的值时,才扩大数组长度,再将值赋给单个数组元素。这样的需求该怎么办呢?

例如有个题目,求100以内自然数中,第7个数字2和数字3的公倍数。

有的小伙伴很快就想到了思路,首先定义一个动态数组arr,然后从1到100开始循环遍历,当数字循环到2和3的公倍数时,ReDim该数组的长度为y,并把当前数字添加进数组,y自增加1,再循环到符合条件的数字时,再ReDim该数组的长度为y,再把当前数字添加进数组,依次循环到100,循环结束后,通过arr(索引)就得到了结果。我们按照这个思路写下代码,如下图:

在逐行运行时,我们观察一下本地窗口中,各个参数的值,如下图:

我们发现,在循环到第一个满足条件的数字6时,将6添加到数组中,这时是正常的,但是当循环到第二个满足条件的数字12时,在运行Redim arr(y)这行代码时,会将数组置空,之后才会将满图条件的数字放入到数组的第二个位置,像这样循环到最后,数组中只会存着最后一个满足条件的值,前边的都会被置空。这种情况是我们不想要的,我们只想扩大一下数组,之前填充到数组中的内容是不想改变的。

于是,我们在循环中重定义数组的代码中加上ReDim的参数Preserve,它的意思就是当arr是一个动态数组,用ReDim Preserve重定义arr修改长度时,不清空之前数组中的元素(Redim 不能重定义静态数组的长度)。我们再试一下,如下图:

如果在ReDim中使用了Preserve可选参数,只能调整数组最后维的大小,并且不能改变数组的维数。例如,如果数组只有一维,就可以修改该数组的大小,因为该维是最后的也是仅有的一维。但是,如果数组有两个或者更多维,就只能改变末维的大小并保留数组内容。

ReDim Preserve重定义数组长度时,该数组在声明时必须是动态数组,即Dim arr(),不能声明成Variant类型(即不能Dim arr或者Dim arr as Variant),否则都会报错。

b.向数组变量整体赋值

整体赋值的意思就是把一个数组直接赋值给数组变量,而不是通过对单个数组元素的赋值。整体赋值要求数组变量在声明时必须声明为动态数组或者Variant类型,不能向声明为静态数组的变量赋值,如果声明成静态数组的变量被整体赋值,即使数组长度一致,也会报错。

整体赋值数组经常将以下几种数组赋给数组变量的情况:

1)常量数组就是常数组成的数组

我们常用花括号括起来的一组用逗号或分号隔开的值来表达常量数组,使用花括号表达的常量数组进行整体赋值时,必须给花括号两边加方括号。将一维横向数组赋给变量,如下图:

一维纵向数组赋给数组变量arr,如下图:

关于常量数组中逗号和分号的区别,其实很简单,逗号隔开的是列数据,分号隔开的是行数据,如下图:

2)区域数组,实际上是单元格区域,数据存储在单元格中。使用Range表达的数组赋值给数组变量时,将是一个二维数组,如下图:

即使Range是一行或者一列,赋值后也是一个二维数组,如下图:

3)内存数组,实际上包含常量数组,但它主要指某个函数的计算结果是数组。

使用Array函数创建数组。使用Array函数一般只能写入横向的一维数组,如下图:

细心的小伙伴已经发现了不同,在默认情况下, Array表达的一维横向数组整体赋值时,数组的最小下标是从0开始的,而之前介绍其他的整体赋值,下标都是从1开始的,在使用时也要多加留意哦。关于下标开始,有兴趣的小伙伴可以研究一下设置Option Base ,这里就不多说了。

如果用Array表达的一维横向数组变成纵向的数组,就不能在Array函数中用分号分隔元素了,就要用到Transpose函数,如下图:

介绍一下Transpose函数

该函数为工作表函数,这类函数可以通过Application.Transpose、Application.WorksheetFunction.Transpose或者WorksheetFunction.Transpose三种方式调用,不同的是通过WorksheetFunction调用的,在VBE中可以看到工作表函数的代码提示。

Transpose能返回转置后的数组,将数组的第一行作为新数组的第一列,将数组的第二行作为新数组的第二列,依此类推。上图是将一维横向数组转置为一维纵向数组,下图则是将一个二维数组进行转置,如下图:

有的小伙伴就要问了,Array能不能表达多维数组?答案当然是肯定的,利用Array函数嵌套就可以,例如Array(Array(1,2,3),Array(4,5,6),Array(7,8,9)),就是一个三行三列的二维数组,这里我们就不再赘述了,有兴趣的小伙伴可以研究下。

使用Split函数创建数组

Split函数我们已经在很多地方都使用到了,该函数就是通过分隔符将一个字符串分成若干个元素,返回一个由分隔出的元素组成的一维数组,如下图:

这里使用Split就有一个隐藏知识点,就是接收Split函数返回的数组变量,要么是Variant类型的,要么就是确定数据类型的动态数组。这个解释太拗口了,以上图为例,要么声明数组用Dim arr as Variant或Dim arr,要么用Dim arr() as String,是不能用数据类型不确定的的动态数组(如Dim arr() 或者Dim arr() as Variant)接收Split返回值的,否则会报错。

小结一下今天的知识点:

①数组元素中的数据类型必须一致,而集合和字典没有强制要求。

②当数组已经确定了长度,我们就可以对数组内的单个数组元素进行赋值,从而完成对数组的赋值。

③可以使用ReDim的Preserve参数重新定义动态数组长度而不清空之前数组中内容。在需要扩大动态数组,而不修改原先数组内的元素时,就要用到Preserve关键字,用ReDim Preserve重定义数组长度时,该数组在声明时必须是动态数组,即Dim arr(),不能声明成Variant类型,(不能Dim arr或者Dim arr as Variant),否则都会报错。

④数组的整体赋值时,数组变量必须是动态数组或者是Variant变量。可以用常量数组、区域数组和内存数组向变量整体赋值。

常量数组用花括号表示“{ }”,在VBA中使用时还需给两边加方括号“[ ]”,数组元素中逗号分隔列,分号分隔行。

区域数组用Range表示,将区域数组赋值给数组变量时,将会是一个二维数组,即使Range只有一行或者一列。

内存数组中,我们介绍了两个常用的函数返回数组,一个是Array,一个是Split,这两个函数都是返回一个一维横向数组,默认返回数组下标都从0开始。Split函数返回的数组赋给变量时,变量必须是确定数据类型的动态数组或者Variant类型

⑤对数组转置时,可以用WorksheetFunction.Transpose。

本来一开始这次是想把数组、集合和字典的赋值操作都写完的,但是因为边写边加,发现数组赋值的相关内容就有很多,知识点还是有点纷杂,篇幅的原因就先写到这。希望小伙伴们也能对基础数组知识进行查缺补漏,完善这块学习内容。

猜您喜欢

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多