VBA中数组(Array)与随机数(Rnd)的使用
作者: 奔跑的犀牛先生
本文链接:https://blog.csdn.net/xuemanqianshan/article/details/88962097
一 数组 array
1.1 数据定义
- 静态数组:长度不变的数组
- 动态数组:长度不定的数组,需要redim
- 数组 arr() 必须先声明后才可以使用!
1.2数组的index下标
- (1)数组的index下标应该是从0开始的,比如split生成的,还有未指定index下标的
- 如 dim arr1(5)
- (2)但是数组的index下标也有从1开始的情况,比如range 赋值的变量,默认下标从1开始
- 如 arr2=range("b1:d5")
- (3)数组的index下标受控制的情况
- 模块最前面 option base -1
- (4)数组index下标最好自己定义好
- 如 dim arr3(1 to 5)
1.3 数组严格定义的重要性
- Dim arr1(3)
- Dim arr1( 1 to 3)
- Option base 1 等等的意义
1.4 创建数组的方法
创建数组的方法
- (1) array()
- (2) split() (对应join)
- (3) 挨个元素赋值,甚至循环
- (4) 变量/对象 = range对象(值)
Sub test101()
rem 测试创建数组的各种方法
Dim arr1
Dim arr2
Dim arr3(0 To 3)
arr1 = Array(1, 2, 3, 4, 5, 6, 7)
arr2 = Split("a,b,c,d,e,f,g", ",")
arr3(0) = 1
arr3(1) = 2
Debug.Print arr1(1)
Debug.Print arr2(1)
Debug.Print arr3(1)
End Sub
二 数组必须声明大小后才可以使用
2.1 测试
- 变量可以不事先定义,也可以不赋初值
- 数组必须实现声明大小后才可以使用
- rem 变量可以赋初值,就可以表达式运算,不同类型的变量,默认初值不同
- rem 数组必须声明大小后才可以使用,包括运算,或者赋值
2.2 语法差别比较
- js 里 变量名 $a 字符串a
- 和其他语言不同的,其他语言标准 字符,字符串为 "", 变量名不用特殊标记
- 而js 标记了变量,本质是一样的
- python里 变量 a 字符串" a” 函数 func() 数组 list=[]
- 函数和数组形式完全不同,没有实现区分的必要性
- VBA里 变量 a 字符串 “a” 函数 func() 数组 array()
- 数组和函数形式很像,所以需要实现定义清楚,否则不好区分
- 但是VB里,index用 () 而不是一般语言的 []
Sub t3()
Dim arr3(3) As Integer
arr4(1) = 1 '直接会报错,arr4未定义!!
End Sub
rem 变量可以赋初值,就可以表达式运算,不同的变量,默认初值不同
Sub t3()
rem 变量可以赋初值,就可以表达式运算,不同的变量,默认初值不同
a = a + 1
Debug.Print a
'arr4(1) = 1 '直接会报错,arr4未定义!!
End Sub
'selection
Sub 删除空格4()
Dim arr1()
ReDim arr1(11) '不redim呢
j = 0 'j=1开始就会越界
For i = 1 To 11 Step 1
If Not IsEmpty(Cells(i, 1)) Then
arr1(j) = Cells(i, 1)
j = j + 1
End If
Next i
For j = 0 To UBound(arr1())
Cells(j + 1, 9) = arr1(j) '单元格得从1开始,arr()得从0开始
Next j
End Sub
三 数组的 声明+ 赋值 不同方法
3.1 声明定义数组有3种方法:
- 直接声明数组
- 数组名为变量
- 数组名为对象名
3.2 数组名(变量名)与数组
- 变量名代表变量
- dim a
- 或者不声明 a 直接使用也默认为变量
- 数组名 与数组
- 如果先声明 dim arr1()
- arr1 就代表 arr1() 否则arr1 一般就被认为是变量名
- 函数名 与函数
- 如果先声明的 function func1()
- func1 就代表 func1()
3.3 数组不能被赋值,只有 数组的元素,变量,对象可以被赋值
- 而数组不能被直接赋值
- 只有数组的元素可以被赋值
- 而变量,对象都是可以被直接赋值的
Sub test001()
Rem VBA里的array是数组
Rem 数组不能被赋值,只能给数组的元素赋值
Rem Excel里的range是对象,2维数组对象 <> 数组,range是对象不是数组!
Rem 对象是可以被赋值的,赋值给了对象的 range.value属性
Dim arr1(3) '如果已经声明为数组名了,arr1就代表arr1(),以后就不能给数组赋值
Dim arr2 As Variant '相当于dim arr2
Dim arr3 As Object
'arr1 = Range("a1:c1") '不能给数组赋值? 只能给数组里的元素赋值?arr1 = Range("a1:c1").value 也不行
arr1(0) = Range("a1") '可以给数组的某个元素赋值
arr2 = Range("a1:c1") '可以给变量赋值,赋予这个变量整个数组
Set arr3 = Range("a1:c3") '可以把EXCEL的range 赋值给变量,或对象。然后默认都成为了2维数组。
Range("b2:c2") = 9999
Debug.Print "arr1(0)=" & arr1(0)
Debug.Print "arr2(1,1)=" & arr2(1, 1)
Debug.Print "arr3(1,1)=" & arr3(1, 1)
End Sub
四 数组定义和赋值
4.1 数组的 声明/定义大小 和赋值 ----数组使用前需要定义数组大小
- Dim Array
- Dim Array()
- Dim array as object
- 无差别??--是不是有点太随便了,反而不好学规律
- 声明数组的时候
- 无论dim arr1 (as variant)
- 还是 dim arr1()
- 但是一旦 dim arr1 as object就有问题,数组不是对象? 报错 缺少数组
- 但是一旦 dim arr1() as object就有问题,数组不是对象? 报错缺少数组
总结:这2种没差别
- dim arr1 或 dim arr1() 都可以
- arr1=range 或 arr1()=range 都可以
Sub 测试1()
Dim arr1 As Variant
arr1 = Range("a1:c4") '这里为什么不 set 为对象呢?
Debug.Print arr1(3, 3)
Debug.Print LBound(arr1)
Debug.Print UBound(arr1)
Debug.Print LBound(arr1, 2) '二维数组,第1维默认是行数,往下数!
Debug.Print UBound(arr1, 2) '二维数组, array(row,column)
Sub 测试2()
Dim arr2()
arr2 = Range("a1:c4")
Debug.Print arr2(3, 3)
Debug.Print LBound(arr2)
Debug.Print UBound(arr2)
Debug.Print LBound(arr2, 2)
Debug.Print UBound(arr2, 2)
End Sub
Sub 测试3()
Dim arr2()
arr2() = Range("a1:c4")
Debug.Print arr2(3, 3)
Debug.Print LBound(arr2)
Debug.Print UBound(arr2)
Debug.Print LBound(arr2, 2)
Debug.Print UBound(arr2, 2)
End Sub
End Sub
4.2 array() 函数的作用----再升高一维数组
Sub 测试1()
Dim arr1 '定义arr1() 其实arr1就代表了数组把 arr1()只是明晰了声明了arr1是数组
arr1 = Array(Range("a1:a4"), Range("b1:b4"), Range("c1:c4"))
Rem array()转的都是1维数组把, no 这里是三维数组
Rem array 只是加一维,并非是转成1维数组了
Debug.Print arr1(0)(1)(1)
For i = 1 To UBound(arr1)
Debug.Print arr1(i)(2)(1) '写成arr(i)会报类型不匹配,因为数组维数不对
Next i
End Sub
4.3 关于dim array() 的index下标
- array 使用前,必须先定义 dim array() 大小
- 无论是静态的数组,或是静态的大小 dim array(10) 或 redim array()
- 首先要记住,cells()等是excel对象,其pos是(row column)组成,所以下标必须从1开始,不能从开始
- 而array() 默认index都是从0开始, 比如这么定义 dim arr1(4,3) 实际上是 arr1(0 to 4, 0 to 3)
- 但是array的index下标可以从1 或者2 等其他开始
- 比如 dim array1(1 to 5) dim array2(2to7)
- 一般为了两者匹配,所以定义数组维度时会这么定义
- arr1(1 to 4, 1 to 3) 完全是为了方便和excel对象的数据匹配
- 所以下面两种写法都可以,如果用array的index从0开始则需要注意,对应匹配好excel对象的 下标+1 和ubound -1
Sub 测试2()
Dim arr1(4, 3)
For i = 0 To 3
For j = 0 To 2
arr1(i, j) = Cells(i + 1, j + 1)
Debug.Print arr1(i, j)
Next j
Next i
Debug.Print vbCrLf ‘测试脚手架,不是一直有
Debug.Print arr1(0, 0)
End Sub
- 下面这么严格和excel对应也是OK的,一般人会这么写,
- 但要明白 array() 不严格声明下标 1 to 4 默认都会是 0 to 4,要明白这个!!
- 但是因为没有arr1(0,0) 所以Debug.Print arr1(0, 0) 会报错!
Sub 测试3()
Dim arr1(1 To 4, 1 To 3)
For i = 1 To 4
For j = 1 To 3
arr1(i, j) = Cells(i, j)
Debug.Print arr1(i, j)
Next j
Next i
Debug.Print vbCrLf
End Sub
- 但是如果含糊写,又不对应,也没问题
- 只是要知道。Arr1(0,0) 这里实际是没被赋值的,只是VBA这里没事。
- Debug.Print arr1(0, 0) 不会打印出东西 none 也不报错
Sub 测试4()
Dim arr1(4, 3)
For i = 1 To 4
For j = 1 To 3
arr1(i, j) = Cells(i, j)
Debug.Print arr1(i, j)
Next j
Next i
End Sub
五 数组分类
5.1 静态数组
- 静态数组定义的语法:
- dim arr1(10) as string 资料说是从1开始,我测试是从0开始
- 但是0~10都不越界,不是有11个数了? 就是0-11?
- dim arr2(5 to 10) as string
- 另外,数组数据类型也并不需要都是 as string, 测试 as integer同样没问题
Sub t3()
Dim arr(10) As String
For i = 1 To 10 Step 1
arr(i) = i
Debug.Print (arr(i))
Next i
Debug.Print arr(5)
Debug.Print arr(0) '不显示下标越界
Debug.Print arr(11) '会显示下标越界
End Sub
Sub t3()
Dim arr(10) As Integer
For i = 1 To 10 Step 1
arr(i) = i
Debug.Print (arr(i))
Next i
Debug.Print arr(5)
Debug.Print arr(0) '不显示下标越界
End Sub
5.2 动态数组
- 动态数组定义
- dim arr3() as string 或 dim arr3()
- 数组重定义:redim
- 只能重定义动态数组! 也必须重定义大小! 不redim前无法使用
- redim时,下标可以是变量
Sub t3()
Dim arr3() As Integer '如果定义dim arr3 as integer 会成为一个变量
Dim arr4() As Integer
For i = 1 To 5 Step 1
ReDim arr3(1 To i) '使用数组的内容之前,必须先redim 否则会显示下标越界
ReDim arr4(1 To i)
arr3(i) = i
arr4(i) = i
Debug.Print (arr3(i))
Debug.Print (arr4(i))
Next i
End Sub
Sub t3()
Dim arr5(1 To 5) As Integer
ReDim arr5(1 To 10) As String '不能对静态数组redim改变大小
End Sub
5.3 定义数组指向EXCEL对象,是二维数组,不能这么使用arr(1)
- 指向excel对象,比如range() 的 默认为2维数组,因为EXCEL表本身就是二维数组!
- 二维数组的下标,需要用excel里的r1c1模式
- 因为是二维数组,不能这么使用,即使只是1行或者1列数,但仍然是二维数据结构!
- arr1()=range("a1:e1") 虽然看起来只是a1 b1 c1 d1 e1 这5个数,但由于是在excel表里的对象,是二维的
Sub t3()
Rem Dim arr6 As Integer
arr6 = Range("a1:a5")
Debug.Print arr6(1, 1)
Debug.Print arr6(2, 1)
Debug.Print arr6(3, 1)
Debug.Print arr6(4, 1)
Debug.Print arr6(5, 1)
End Sub
六 定义二维数组
6.1 定义
- 定义方法
- dim arr1(4,5) as string
- dim arr1 (0 to 4,0 to 5) as integer
Sub t4()
Dim arr1(0 To 4, 0 To 5) As Integer
arr1(0, 0) = 999
Debug.Print arr1(0, 0)
End Sub
6.2 动态数组和静态数据的语法不要混用!
- 静态数组就不要再redim
- 动态数据就一定需要redim
Sub t4()
Dim arr2()
Rem Dim arr2(5, 6) '使用动态数组 redim就不要和 静态数组定义格式混用
For i = 0 To 5 Step 1
For j = 0 To 6 Step 1
ReDim arr2(0 To i, 0 To j) '动态数组,必须在使用前redim
arr2(i, j) = i + j
Debug.Print arr2(i, j)
Next j
Next i
Sub t4()
Dim arr2(5, 6)
For i = 0 To 5 Step 1
For j = 0 To 6 Step 1
Rem ReDim arr2(0 To i, 0 To j) '如果要用静态数组也可以,但不要再redim了!
arr2(i, j) = i + j
Debug.Print arr2(i, j)
Next j
Next i
End Sub
七 定义三维数组
- 下标也是从0开始的
Sub t4()
Dim arr3(3, 4, 5)
arr3(0, 0, 0) = 888
Debug.Print arr3(0, 0, 0)
End Sub
多维数组的问题---3维数组的表达方式???
- 到底哪种指定维度的方法正确?
- arr(1,2)
- arr(1)(2)
- 现在实际测试的结果是
- arr可以定位为变量,赋值为一个range 或 range.value,等价
- 但是没有 array().value 这种用法
- 现在实际测试的结果是
- 2维数组,只能arr(1,2)
- 3维数组,有的arr(1,2,3) 有的arr(1)(2)(3)
三维数组的表示问题,和之前的不同了
Sub test_3d()
Dim arr1(1 To 2)
Dim arr2(1 To 2, 1 To 2)
Dim arr3(1 To 2, 1 To 2, 1 To 2)
Dim arr4
arr1(1) = 1
arr2(1, 1) = 10
arr3(1, 1, 1) = 100
'arr4(1)(1)(1) = 100 为啥现在这么写不行了?莫不是偏移3次?对比之前的
Debug.Print arr1(1)
Debug.Print arr2(1, 1)
Debug.Print arr3(1, 1, 1)
'Debug.Print arr4(1)(1)(1)
End Sub
Sub test1()
Dim arr1
Dim arr2
Dim arr3
Dim arr4
Dim arr5(3, 4, 5)
arr1 = Range("b1:b3")
Debug.Print arr1(3, 1)
'Debug.Print arr1(3)(1)
arr2 = Range("b1:b3").Value
Debug.Print arr2(3, 1)
'Debug.Print arr2(3)(1)
arr3 = Array(Range("a1:a3"), Range("b1:b3"))
'Debug.Print arr3(0, 1, 1)
Debug.Print arr3(1)(1)(3)
'arr4 = Array(Range("a1:a3"), Range("b1:b3")).Value '报错
''Debug.Print arr4(0, 1, 1)
'Debug.Print arr4(1)(1)(3)
arr5(0, 0, 0) = 111
Debug.Print arr5(0, 0, 0)
'Debug.Print arr5(0)(0)(0)
End Sub
https://zhidao.baidu.com/question/504144613.html
要点:
取特定区间的数[a,b)表示为Int((b * Rnd) + a)
rnd本指取[0,1)之间的数
Randomize 语句初始化随机数生成器。 语法 Randomize [number] 可选的 number 参数是 Variant 或任何有效的数值表达式。 说明 Randomize 用 number 将 Rnd 函数的随机数生成器初始化,该随机数生成器给 number 一个新的种子值。如果省略 number,则用系统计时器返回的值作为新的种子值。 如果没有使用 Randomize,则(无参数的)Rnd 函数使用第一次调用 Rnd 函数的种子值)
四舍五入函数Round(x1[,x2]) 四舍五入保留小数x2位,省略表示为取整
代码区
猜数游戏
如果不使用Randomize,则随机数第一次写入内存后就不会更改,下次运行 值不变。Randomize重在可以初始化内存中的随机数值
VBA中数组(Array)与随机数(Rnd)的使用相关推荐
- JS中数组(Array)、Json对象长度(length)获取方法
JS中数组(Array).Json对象长度(length)获取方法 1.数组 var array = []; var length = array.length; 2.JSON对象 1)方法1: va ...
- Java 中数组Array和列表List的转换
主要介绍Java中Java 中数组Array和列表List的转换. 一.数组Array转列表List 1.使用Collections.addAll()方法 使用Collections.addAll() ...
- python/numpy中数组array和矩阵matrix的区别
在numpy中,array(实际上是ndarray,表示多维数组)是可以有多维度的,而matrix只有两个维度,即行和列.所以matrix是array的一种特例,因而它继承了array的所有函数,同时 ...
- JAVA中数组Array与List互转
List<String> list = new ArrayList<String>(); String[] array = new String[10]; Set<Str ...
- JS中数组Array的用法{转载}
js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...
- Js中数组Array的用法
js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...
- VBA中数组72变(随心所欲复制)
西游记中孙悟空最神奇的本领之一就是拔根毫毛,瞬间变出无数个孙猴子.代码中的数组可谓神通广大,如何实现瞬间变身呢?其实也很简单. Private Declare Sub CopyMemory Lib & ...
- VBA的 随机数 rnd 和 randomize 如何配合使用? 伪随机数带来的问题,根据需要产生不同的随机数!
总结前置 如果想永远生成相同的随机数,就用rnd(-1) 但是这么做没意义吧? 如果想每次生成的随机数,本次程序运行结束前都一样,下次计算时不一样.就用 randmize 和 rnd(0) 如果想 ...
- java在数组中放入随机数_如何在Java中随机播放数组
java在数组中放入随机数 There are two ways to shuffle an array in Java. 有两种方法可以在Java中随机播放数组. Collections.shuff ...
最新文章
- 对标Pytorch,清华团队推出自研AI框架“计图”
- Google综述:细数Transformer模型的17大高效变种
- .net采集网页方法大全(5种)
- 理解Underscore中的uniq函数
- 2020秋季学期教学委员会第一次全体会议
- iOS 延迟1.5s 执行方法
- GDCM:gdcm::VM的测试程序
- 剧透LiveVideoStackCon 2020:除了干货,还有更多优惠的年度通票
- 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波2 - 图像反转、对数变换
- 根据变量推断变量类型_Java A的新本地变量类型推断
- CV Code | 计算机视觉开源周报 20190602期
- XML序列之System.Xml.Serialization
- android表格布局占满整行,Android布局之表格布局TableLayout详解
- matlab教程易,Matlab经典教程—从入门到精通 中文PDF
- Linux之奇怪的知识---supervisor超级守护进程的意义和使用方法
- c语言考场排座系统,具才考场座次编排系统
- 如何使用prism进行统计分析(Analysis)?
- 数说热点 | 跟着《长月烬明》起飞,今年各地文旅主打的就是一个听劝
- 学位论文和论文的区别是什么?
- 关于C语言文件的读写