ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[转帖] Dim语句和ReDim语句

[复制链接]

TA的精华主题

TA的得分主题

发表于 2012-11-6 14:12 | 显示全部楼层 |阅读模式
Dim 语句
声明变量并分配存储空间。
语法
Dim [WithEvents] varname[([subscripts])] [As [New] type] [, [WithEvents] varname[([subscripts])] [As [New] type]] . . .
Dim 语句的语法包含下面部分:
部分描述
WithEvents可选的。关键字,说明 varname 是一个用来响应由 ActiveX 对象触发的事件的对象变量。只有在类模块中才是合法的。使用 WithEvents,可以声明任意个所需的单变量,但不能使用 WithEvents 创建数组NewWithEvents 不能一起使用。
varname必需的。变量的名称;遵循标准的变量命名约定。
subscripts可选的。数组变量的维数;最多可以定义 60 维的多维数组。subscripts 参数使用下面的语法:
[lower To] upper [, [lower To] upper] . . .
如果不显式指定 lower,则数组的下界由 Option Base 语句控制。如果没有使用 Option Base 语句,则下界为 0。
New可选的。可隐式地创建对象的关键字。如果使用 New 来声明对象变量,则在第一次引用该变量时将新建该对象的实例,因此不必使用 Set 语句来给该对象引用赋值。New 关键字不能声明任何内部数据类型的变量,以及从属对象的实例,也不能与 WithEvents 一起使用。
type可选的。变量的数据类型;可以是 Byte Boolean IntegerLongCurrencySingleDoubleDecimal(目前尚不支持)、DateString(对变长的字符串)、String * length (对定长的字符串)、ObjectVariant用户定义类型、或对象类型。所声明的每个变量都要一个单独的 As type 子句。


说明
模块级别中用 Dim 声明的变量,对该模块中的所有过程都是可用的。在过程级别中声明的变量,只在过程内是可用的。
可以使用 Dim 语句在模块级或过程级中声明变量的数据类型。例如,下面的语句声明了 Integer 类型的变量。
Dim NumberOfEmployees As Integer
也可以使用 Dim 语句来声明变量的对象类型。下面的语句为工作表的新建实例声明了一个变量。
Dim X As New Worksheet
如果定义对象变量时没有使用 New 关键字,则在使用该变量之前,必须使用 Set 语句将该引用对象的变量赋值为一个已有对象。在该变量被赋值之前,所声明的对象变量有一个特定值 Nothing,这个值表示该变量没有指向任一个对象实例。
也可以使用带空圆括号的 Dim 语句来定义动态数组。在定义动态数组后,可以在过程内使用 ReDim 语句来定义该数组的维数和元素。如果试图在 PrivatePublicDim 语句中重新定义一个已显式定义了大小的数组的维数时,就会发生错误。
如果不指定数据类型或对象类型,且在模块中没有 Deftype 语句,则该变量按缺省设置是 Variant 类型。
当初始化变量时,数值变量被初始化为 0,变长的字符串被初始化为一个零长度的字符串 (""),而定长的字符串则用 0 填充。Variant 变量被初始化为 Empty。用户自定义类型的变量的每个元素作为各自独立的变量进行初始化。
注意 当在过程中使用 Dim 语句时,通常将 Dim 语句放在过程的开始处。

Dim 语句示例
该示例演示使用 Dim 语句来声明变量,也演示了用 Dim 语句来声明数组。数组的缺省下界为 0,可以在模块级使用 Option Base 语句来取代数组的缺省下界。
'AnyValue 和 MyValue 按缺省情况被声明为 Variant,'同时值被设为 Empty。Dim AnyValue, MyValue'显式声明一个 Integer 类型的变量。Dim Number As Integer'在一行中声明多个变量。AnotherVar 为 Variant 类型,'因为它的类型被省略了。Dim AnotherVar, Choice As Boolean, BirthDate As Date'DayArray 是一个有 51 个索引(从 0 到 50)元素的 Variant 数组,'假设在当前模块中 Option Base 被设为 0(缺省设置)。Dim DayArray(50)'Matrix 是一个二维 Integer 数组。Dim Matrix(3, 4) As Integer'MyMatrix 是一个显式指定了上下界'的三维 double 数组。Dim MyMatrix(1 To 5,  4 To 9,  3 To 5) As Double'BirthDay 是一个索引从 1 到 10 的 date 数组。Dim BirthDay(1 To 10) As Date        'MyArray 是一个 variant 动态数组。Dim MyArray()

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-6 14:14 | 显示全部楼层
ReDim 语句
过程级别中使用,用于为动态数组变量重新分配存储空间。
语法
ReDim [Preserve] varname(subscripts) [As type] [, varname(subscripts) [As type]] . . .
ReDim 语句的语法包括以下几个部分:
部分描述
Preserve可选的。关键字,当改变原有数组最末维的大小时,使用此关键字可以保持数组中原来的数据。
varname必需的。变量的名称;遵循标准的变量命名约定。
subscripts必需的。数组变量的维数;最多可以定义 60 维的多维数组。subscripts 参数使用下面的语法:
[lower To] upper [,[lower To] upper] . . .
如果不显式指定 lower,则数组的下界由 Option Base 语句控制。如果没有 Option Base 语句则下界为 0。
type可选的。变量的数据类型;可以是 ByteBooleanIntegerLongCurrencySingleDoubleDecimal(目前尚不支持)、DateString(对变长的字符串)、String * length(对定长的字符串)、ObjectVariant用户定义类型对象类型。所声明的每个变量都要有一个单独的 As type 子句。对于包含数组的 Variant 而言,type 描述的是该数组的每个元素的类型,不能将此 Variant 改为其它类型。


说明
ReDim 语句用来定义或重定义原来已经用带空圆括号(没有维数下标)的 Private、PublicDim 语句声明过的动态数组的大小。
可以使用 ReDim 语句反复地改变数组的元素以及维数的数目,但是不能在将一个数组定义为某种数据类型之后,再使用 ReDim 将该数组改为其它数据类型,除非是 Variant 所包含的数组。如果该数组确实是包含在某个 Variant 中,且没有使用 Preserve 关键字,则可以使用 As type 子句来改变其元素的类型,但在使用了此关键字的情况下,是不允许改变任何数据类型的。
如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目。例如,如果数组就是一维的,则可以重定义该维的大小,因为它是最末维,也是仅有的一维。不过,如果数组是二维或更多维时,则只有改变其最末维才能同时仍保留数组中的内容。下面的示例介绍了如何在为已有的动态数组增加其最末维大小的同时而不清除其中所含的任何数据。
ReDim X(10, 10, 10). . .ReDim Preserve X(10, 10, 15)
同样地,在使用 Preserve 时,只能通过改变上界来改变数组的大小;改变下界则会导致错误。
如果将数组改小,则被删除的元素中的数据就会丢失。如果按地址将数组传递给某个过程,那么不要在该过程内重定义该数组的各维的大小。
在初始化变量时,数值变量被初始化为 0,变长的字符串被初始化为一个零长度的字符串 (""),而定长的字符串则用 0 填充。Variant 变量被初始化为 Empty。用户自定义类型的变量的每个元素作为各自独立的变量进行初始化。在使用引用对象的变量之前,必须使用 Set 语句将一个已有的对象赋给该变量。在被赋值之前,所声明的对象变量有一个特定值 Nothing,这个值表示该变量没有指向任何对象的实例。
小心 如果 ReDim 语句所使用的变量在模块级别过程级别不存在,则该语句就相当于一个声明语句。如果此后在一个更广的范围内又创建了同名的变量,即使使用了 Option ExplicitReDim 也将使用后声明的这个变量,且不会导致编译错误。为了避免这种冲突,就不应把 ReDim 作为声明语句使用,而只应作为重定义数组大小的语句。
注意 要改变 Variant 所包含的数组的大小,必须在试图改变其数组大小之前显式声明该 Variant 变量。


ReDim 语句示例
该示例使用 ReDim 语句为动态数组变量分配和重分配存储空间。假设 Option Base 1
Dim MyArray() As Integer    '声明动态数组。Redim MyArray(5)    '分配 5 个元素。For I = 1 To 5    '循环 5 次。    MyArray(I) = I    '初始化数组。Next I
下一条语句重定义该数组的大小,并清除其中的元素。
Redim MyArray(10)    '大小重定为 10 个元素。For I = 1 To 10    '循环 10 次。    MyArray(I) = I    '初始化数组。Next I
下面的语句重定义该数组的大小,但没有清除其中的元素。
Redim Preserve MyArray(15)    '大小重定为 15 个元素。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-11-6 14:15 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-11-14 12:12 | 显示全部楼层
支持一下楼主,有个地方好像有问题:
即“同样地,在使用 Preserve 时,只能通过改变上界来改变数组的大小;改变下界则会导致错误”。
数组最后一维的上下界应该都可以改变,如果元素减少,则从后面砍掉一部分,如果增加也是后面增加一部分(空值),第一个元素会一直被保留,位置也总是在排在第一个。
请验证!

TA的精华主题

TA的得分主题

发表于 2015-9-1 15:36 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Dim arr, i, x, n, j, brr()                                                   
    arr = Range("a1").CurrentRegion                                                  
    ReDim brr(1 To 12, 1 To Application.RoundUp(UBound(arr) / 4, 0))                 
    For i = 1 To UBound(arr)                                                                                                            
        j = j + 1                                                                  
        For x = 1 To 12                                                        
            If n > 2 Then
            n = 0
            i = i + 1
            End If
            If i > UBound(arr) Then                                                
             GoTo 100
             End If
            n = n + 1                                                     
            brr(x, j) = arr(i, n)
            Debug.Print arr(i, n)
        Next
        i = i - 1
    Next
100
    [e9].Resize(UBound(brr, 2), 12) = Application.Transpose(brr)                  
End Sub                                                                              
对于这样的一个过程,如果我不想用redim,可以怎么定义brr

TA的精华主题

TA的得分主题

发表于 2017-3-12 17:47 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-3-8 21:24 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
备查的东东,收藏一下。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-5-10 17:23 , Processed in 0.038720 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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