苏宁集团简介:第8章 数组

来源:百度文库 编辑:九乡新闻网 时间:2024/07/14 08:34:06
 第8章 数组  本书前面介绍的都是通过简单变量名来访问数据。在VBA中,除了使用这些简单变量名外,对于在批量的数据还可使用数组来访问。本章介绍数组的定义和使用方法。  8.1 数组简介  在程序中,如果要处理大量的数据,为每个数据定义一个变量将使程序变得很难阅读,并且代码很烦琐。  对于大量有序的数据,可以使用数组对其进行存储和处理。在其他程序设计语言中,数组中的所有元素都必须为同样的数据类型。在VBA中,数组中各元素可以是相同的数据类型,也可以是不同的数据类型。数组用来保存一组有序的数据,如图8-1所示的数据共有5项,可使用数组来保存这些数据。                            如图8-1所示的数据又称为列表数据,可使用前面的项目名称加上数据元素在列表中的序号来表示每一个数据元素。这类数据只具有行或列,称为一维数组。  如果将由行和列组成的数据表定义为一个数组,那么这个数组就是二维数组。Excel的工作表就可用一个二维数组表示,表中每个元素的位置由它的行号和列号决定,如图8-2所示。                                                       如果需要处理的数据除了在行和列上进行排列之外,还具有深度(即多个二维表格),类似于Excel工作簿中的多个工作表,如图8-3所示。保存这种结构数据的数组称为三维数组。                                                              尽管VBA数组最大可以达到六十维,但是超过三维的数组是非常难于理解的,所以常用的也就是一维、二维和三维数组。  8.2 声明数组  计算机中数组占用一片连续的内存空间。在使用之前,必须先对数组进行定义,让系统为其分配一片连续的内存空间。  8.2.1 定义一维数组  数组的声明方式和其他的变量是一样的,可以使用Dim,Static,Private或Public语句来声明。声明标量变量(非数组)与数组变量的不同在于必须为数组指定大小。若数组的大小被指定的话,则它是个大小固定的数组;若程序运行时数组的大小可以被改变,则它是个动态数组。  可使用两种方法定义大小固定的一维数组。第一种的语法格式如下:  Dim 数组名(上界) As 数据类型  该格式与其他程序设计语言定义数组的格式相同,只给出数组下标的上界(即可以使用的最大下标值)而流程图下标的下界,这时默认值为0,即数组的下标从0开始至定义的上界。例如,     Dim MyArray(10) As String  定义了一个名为MyArray的数组,共有11个元素,分别为MyArray(0),MyArray(1)……MyArray(10)。  如果希望数组下标从1开始,可以通过Option Base语句来设置。其语法格式如下:  Option Base 1  使用该语句指定的数组下标的默认下界只能为0或1。该语句只能出现在用户窗体或模块的声明部分,不能出现在过程中,且必须放在数组定义之前。  定义数组的第二种语法格式如下:  Dim 数组名(下界 To 上界) As 数据类型  这种格式可定义数组的下标下界为任意值,例如,  Dim MyArray(-1 To 10) AsString  定义了一个数组MyArray,共有12个元素,分别为MyArray(-1),MyArray(0),……MyArray(10)。  以上介绍了两种定义数组的方法。定义数组时需要注意以下几点:  ★与变量名相同,数组名的命名也需要符合标识符的规则,并尽可能有一定意义。  ★在同一过程中,数组名不能与变量名相同,否则会出错。  ★在VBA中定义数组时,要求其下标必须为常数,不能是变量或表达式。例如以下代码在执行时将会报错,如图8-4所示。  Dim i As Integer,jAs Integer  i=5  Dim a(i)  For j = 1  To 5        a(j) = j  Next                                                        8.2.2 定义二维数组  二维数组的定义方式与一维数组类似,不同的是需要设置两个下标变量。其语法格式如下:  Dim 数组名(第1维上界,第2维上界) As 数据类型  或者是:Dim 数组名(第1维下界 To 第1维上界,第2维下界 To 第2维上界) As 数据类型  例如,定义以下数组用来保存如图8-2所示的数据表。  Dim MyArray(1 To 3,1 To 5)  其中MyArray(1,1)保存值为“朱元军”,MyArray(1,2)保存值为“男”,各元素与值的对应关系如图8-5所示。                定义多维数组的格式与二维数组类似,每一维都使用逗号隔开即可。要注意的是,定义大数据量的数组将占用很大的内存空间,特别是定义多维数组时要考虑这一点。例如:  Dim MyArray(1 To 10000) As Integer  定义一个数组,具有10000个元素,相当于定义10000个变量。  Dim MyArray(1 To 10,1 To 10000) As Integer  定义一个二维数组,具有10×10000=10万个元素,而  Dim MyArray(1 To 10,1 To 10,1 To 10000) As Integer  定义一个三维数组,具有10×10×10000=100万个元素。  8.2.3 默认数组  在VBA中,允许定义默认数组,即数据类型为Variant(默认类型)的数组。一般情况下,定义数组时都要设置其数据类型,例如:  Dim MyArray(10) As String  表示定义一个名为MyArrayr数组,该数组为字符串类型(即每个元素都为一个字符串型的变量)。  若将其定义改为:  Dim MyArray(10)  则表示定义一个名为MyArray的默认数组,与以下语句相同:  Dim MyArray(10) As Variant  使用默认数组的好处是可以让每个数组元素保存一个不同类型的值,得到一种混合状态的数组。例如:  Dim MyArray(1 To 5)  MyArray(1)="朱元军"  MyArray(2)="男"  MyArray(3)="30"  MyArray(4)="大专"  MyArray(5)="北京市"  在以上数组中,第3个元素保存的是一个整型数,其余元素保存的是字符串。  8.3 动态数组  动态数组是指在程序运行时大小可以改变的数组。大小不可改变的数组称为静态数组。定义静态数组时,其下标的下界和上界只能由常量来进行设置,而动态数组可使用变量来设置下标。定义动态数组一般分两个步骤:首先在用户窗体、模块或过程中使用Dim或Public声明一个没有下标的数组(不能省略括号),然后在过程中用ReDim语句重新定义该数组的大小。  ReDim语句在过程级别中使用,用于为动态数组变量重新分配在存储空间。其语法格式如下:  ReDim [Preserve]数组名(下标) [As 数据类型]  可以使用ReDim语句反复改变数组的元素及维数的数目,但是不能在将一个数组定义为某种数据类型之后,再使用ReDim将该数组改为其他数据类型,除非是Variant所包含的数组。  如果使用了Preserve关键字,那么只能重定义数组最后一维的大小,并且不能改变维数的数目。例如,以下代码中,首先由用户输入一个数值,设置数组下标的上界;然后要求用户输入每个元素的值,并将用户输入的值输出到“立即窗口”中。  Dim i As Integer, j As Integer  i = Val(InputBox("请输入数组的上界","定义动态数组",5))  ReDim DArray(i)  For j = 1 To i   DArray(j) = InputBox("请输入数组的第" & j & "个元素的值")  Next  For j = 1 To i             Debug.Print DArray(j)   Next   End Sub  以上代码在模块的声明部分定义了一个动态数组DArray,然后在“动态数组”过程中使用变量i重新定义该动态数组的大小(i的值由用户输入)。执行以上代码时,将首先打开如图8-6所示的对话框,让用户设置数组的上界。                                             按用户输入的值对数组重设大小后,将打开如图8-7所示对话框,要求用户输入每一个元素的值,最后在“立即窗口”中输出数组中每个元素的值。  8.4 数组的基本操作  声明一个数组后,就可以对数组或数组中的元素进行操作了。操作通常包括数组的初始化、数组元素的复制及删除等。  8.4.1数组的初始化  在VBA中,创建数组后将自动初始化数组中的每个元素:对于数值型的数组,每个元素都将清零件如果是字符串型的数组,每个元素将初始化为空字符串。  注意:如果是重定义动态数组,并且使用了Preserve关键字,则不会对已有元素进行初始化,而只对新增加的元素进行初始化。  在对数组中的元素进行处理之前,仍可能需要对数组元素进行初始化。一般使用循环语句来进行操作,可让用户逐个输入数组的初始值;也可按一定的规则读取工作表单元格中的值来对数组赋初始值。例如,以下代码要求用户集资输入10个数组元素的初始值。  For i=1 To 10   MyArray(i) = InputBox("请输入数组的第" & i & "个元素的值")  Next   执行以上代码,将反复显示输入框,让用户输入值,并保存到对应的数组元素中。  注意:InputBox函数返回的是字符串类型。如果数组定义为数值型,还需要使用相关的函数将用户输入的内容进行转换,如用Val函数将字符串转换为数值,也可以使用如Ccur,Cdate,CDbl,Cint等相关函数进行转换。  以下代码使用工作表单元格中的数据来为数组元素赋初始值。  Sub ArrayInit()                                                          '使用工作表单元格中的数据来为数组元素赋初始值    Dim MyArray(5,5)    Dim i As Integer, j As Integer    For i = 1 To 5     For j = 1 To 5       MyArray(i,j) = Worksheets("sheet2").Cells(i,j)     Next j    Next i  End Sub  工作表就相当于一个二维数组,每个单元格就是二维数组中的一个元素。使用工作表中某部分单元格为数组赋初值时,通过两个循环的嵌套就可完成。  通过InputBox函数初始化数组时,需要用户逐个输入,速度很慢。在VBA中,还可使用Array函数来为数组元素赋值,把一个数据集读入数组中。其语法格式如下:  数组变量名 = Array(数据集)其中“数组变量名”是预先定义的数组名,后面不跟括号;函数中的“数据集”是由一些常数构成的数据集合,各值之间用逗号分开。例如:  Sub ArrayInitl()                                         '使用Array函数初始化数组   Dim MyArray, i As Integer   MyArray = Array("星期日","星期二","星期三","星期四","星期五","星期六")   For i = 0 To 6    Debug.Print MyArray(i)   Next  End Sub  字符串“星期日”、“星期一”、“星期三”、“星期四”、“星期五”和“星期六”分别赋给数组MyArray中的各对应元素,即MyArray(0)=“星期日”、MyArray(2)=“星期一”……MyArray(6)=“星期六”。  注意:因为Array函数的返回值为Variant类型,所以在使用Array函数给数组变量赋初值之前,定义数组时只能将其定义为Variant类型,且不能设置其下标,否则将显示“不能给数组赋值”错误提示。  8.4.2 数组元素的复制  单个的数组元素可像普通变量一样进行访问和赋值。因此,要将一个数组中的值复制到另一个数组时,使用For循环语句将数组元素逐个复制即可。例如:  Sub 数组元素的复制()    Dim MyArray1(5) As Integer,MyArray2(5) As Integer    Dim i As Integer    For i = 1 to 5      MyArray1(i) = i    Next     For i = 1 To 5                      MyArray2(i) = MyArray1(i)    Next  End Sub   在以上代码中,如果将数组MyArray2声明为一个Variant变量,那么通过一条语句就能将MyArray1中的所有元素复制到MyArray2中。  Sub 数组元素的复制()    Dim MyArray1(5) As Integer,MyArray2 As Variant      Dim i= 1 To 5      MyArray1(i)= i    Next     MyArray2 = MyArray1                                   '将数组元素保存到Variant变量中  End Sub  通过MyArray2=MyArray1语句赋值后,变量MyArray2将保存一个数组变量。可使用MyArray2(1),MyArrqy2(2)的形式访问数组中每个元素的值。  8.4.3 数组的清除  对于静态数组,当创建完成后,其内存空间也分配完成,数组的大小将不能再改变。有时可能需要清除数组的内容或对数组重新定义,可使用Erase语句来完成。其语法格式如下:  Erase 数组名1,数组名2,……  使用Erase语句可重新初始化大小固定的数组的元素,以及释放动态数组的存储空间。  注意:在Erase语句中,只给出数组名即可,不能带括号和下标。  Erase语句根据参数是静态数组还是动态数组而采取完全不同的行为。  如果参数为静态数组,Erase按表8-1所示的规则来设置固定数组的元素。             如果参数为动态数组,将删除整个数组结构并释放却动态数组所使用的内存。在下次引用该动态数组之前,程序必须使用ReDim语句来重新定义该数组变量的维数。  也就是说,静态数组在使用Erase语句后仍然存在,只是其内容被清空;而动态数组使用Erase语句后即不存在了。例如:  Sub 删除数组()    Dim MyArray() As Integer          '动态数组    Dim MyArray1(5)  As Integer           '静态数组    Dim i As Integer    i=5    ReDim MyArray(i)    For i=1 To 5      MyArray1(i) = i      MyArray(i)= i    Next    Erase MyArray,MyArray1    Debug.Print MyArray1(1)           '静态数组被初始化,其元素值为0    Debug.Print MyArray(1)           '动态数组被删除,将出错  End Sub  程序中首先定义了一个动态数组MyArray和一个静态数组MyArray1,然后使用循环语句对两个数组的元素赋初始值,再使用Erase语句删除这两个数组,最后再访问两个数组中的一个元素。对于静态数组,使用Erase语句只是将其初始化,所以MyArray1(1)的值为0;对于动态数组,使用Erase语句后该数组就不存在了,所以将显示错误提示。  8.4.4 数组函数  在程序中,有时需要判断某个变量是否为数组,或数组的下标范围等。VBA提供了相应的函数来进行这些操作。  VBA中操作数组的主要有5个函数:Array,IsArray,Erase,Lbound和Ubound。其中Array和Erase已在前面进行了介绍,下面介绍另三个函数的使用方法。  1. 检测变量是否为数组  IsArray函数可检查指定的变量是否为一个数组:如果指定变量是一个数组,返回值为True,否则返回False。对于包含数组的Variant表达式来说,IsArray尤为有用。例如:  Dim MyArray(1 To 5) As Integer,YourArray,MyCheck       '声明数组变量  YourArray = Array(1,2,3)                    '使用数组函数  MyCheck = IsArray(MyArray)                    '返回True  MyCheck = IsArray(YourArray)                   '返回True  2. 获得数组下标的范围  LBound函数和UBound函数可获得数组下标的下界和上界。其语法格式为:  LBound(数组名[,维数])  UBound(数组名[,维数])  其中“维数”为“1”表示一维,“2”表示二维,如此类推。如果省略该参数,表示返回一维的下标下界或上界。例如,定义以下数组  Dim A(1 To 100,0 To 3,-3 To 4)  则使用LBound函数的返回值分别为:  LBound(A,1)              '返回值为1  LBound(A,2)              '返回值为0  LBound(A,3)              '返回值为-3 ★★