VBA 为什么你redim() 动态二维数组总出错?因为 redim 动态数组不太适合和循环搭配
1总结
1.1 如何避免出错
- 如果是想生成一个二维数组,最后用静态声明,或则二次声明redim 一个足够大的动态数组
1.2 出错的原因是什么?
- redim时只有最后1维可变化,redim不太适合和循环搭配,即使用 redim preserve也不行!
- 你装数据时一般都会有一个充当计数器的变量,这个变量最后的值就是数组中装入值的数量
- 一般是声明一个足够大的静态数组,或二次声明一个足够大的动态数组,
- 动态的二维数组用redim 修改大小,切记第一维在第一次扩容的时候就定死了,以后只能修改第二维。
- 再次扩容第二维的时候,记得加 preserve关键字,否则数组中的原有数据就会丢失。
- 但是用 redim preserve 扩容的时候,又要注意,维度的数只能增加不能减少,所以不适合 for i=1 to 3 for j=1 to 3 这种循环套循环,因为j这个最后一维总是在循环从小变大,也会有变小重置的时候,就会出问题
1.3 下面是详细的试错过程
2 如果二维数组定义为静态数组,生成数组和生成后打印数组内容,都很方便
Sub test901()
'如果二维数组,定义为静态数组,生成数组 和 生成后打印数组内容,都很方便
Dim arr1(3, 3)For I = 0 To 3For J = 0 To 3arr1(I, J) = I * JDebug.Print "arr1(" & I & "," & J & ")= " & arr1(I, J) & " ";NextDebug.Print
Next
Debug.PrintFor I = LBound(arr1) To UBound(arr1)For J = LBound(arr1, 2) To UBound(arr1, 2)Debug.Print "arr1(" & I & "," & J & ")= " & arr1(I, J) & " ";NextDebug.Print
Next
Debug.PrintEnd Sub
3 如果定义二维数组,是动态数组,但redim时,一次定位到足够大/或准确大小
Sub test902()
'如果定义二维数组,是动态数组,但redim时,一次定位到足够大/或准确大小,也没问题,比较清晰Dim arr2()
ReDim arr2(3, 3)
For I = 0 To 3For J = 0 To 3arr2(I, J) = I * JDebug.Print "arr2(" & I & "," & J & ")= " & arr2(I, J) & " ";NextDebug.Print
Next
Debug.PrintFor I = LBound(arr2) To UBound(arr2)For J = LBound(arr2, 2) To UBound(arr2, 2)Debug.Print "arr2(" & I & "," & J & ")= " & arr2(I, J) & " ";NextDebug.Print
Next
Debug.PrintEnd Sub
4 如果定义一个二维数组为动态数组,但又在循环时赋值,redim不适合这么动态变量 redim,容易出现下面的问题
- 动态数组用redim,比如redim arr4(i,j)
- 因为 i ,j 都在循环就会各种出问题
- 用 redim arr4(i,j) 必出现越界问题, 因为非最后一维,i 这一维在redim 时是不能变得
- 用 redim preserve 也容易出现越界问题,(因为 redim preserve 需要后面得数组空间比之前的大,而循环时很容易出现变小不匹配)
Sub test903()
'如果定义一个二维数组为动态数组,但又在循环时赋值,redim不适合这么动态变量 redim,容易出现下面的问题Dim arr4()
For I = 0 To 3For J = 0 To 3
' ReDim Preserve arr4(I, J)ReDim arr4(I, J)arr4(I, J) = I * JDebug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";Next JDebug.Print
Next I
Debug.PrintFor I = LBound(arr4) To UBound(arr4)For J = LBound(arr4, 2) To UBound(arr4, 2)Debug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";NextDebug.Print
NextEnd Sub
5 为什么 动态redim 二维数组会有问题?原因是
- 需要理解arr4(1 To 3, 1 To J)中arr(1 to 4, ) 其实是固定数组,一次性一步!把维度展开了,而不是逐步展开
- 动态数组,redim时,数组的非最后1维不能变化,变了直接报错越界
- 动态数组,redim时,数组的最后1维也只能从小变大,如循环后又从大变小会出问题,会把之前内容redim后抹掉
- --------所以循环不太适合redim
- 但这时候preserve也不行,还是因为如果最后一维因为循环从大到小后,会导致preserve出错(因为preserve必须后面得包含前面的,不能变小)
- 本质在于 redim 和循环 不匹配的问题!
- 对比
- 为什么生成数组,同时debug.print 数组内容没问题,但是数组生成完成后,显示数组内容反而有错?
- 就是因为 for j = 1 to 3 这个二维数组的第2维的循环,redim从1到3,再次从1到3。导致之前的数组的元素被抹掉!
Sub test603()
'二维数组,动态redim
'需要理解arr4(1 To 3, 1 To J)中arr(1 to 4, ) 其实是固定数组,一次性一步!把维度展开了,而不是逐步展开Dim arr4()
For I = 1 To 3For J = 1 To 3
' ReDim Preserve arr4(I, J) '错在没注意起始下标应该从1开始
' ReDim Preserve arr4(1 To I, 1 To J) '越界错误,因为preserve了,但是j又减小这种循环不适合
' ReDim arr4(1 To I, 1 To J) '虽然不pre不会越界,但之前的值会被抹去ReDim Preserve arr4(1 To 3, 1 To J) 'vba的二维数组,只支持最后1维变大小,其他维不能变否则显示越界,j作为维度之一,只能单向变大,不应该变小的'arr4(I, J) = I * J '可在这里设置断点,添加监视变量,监视arr4Next J
Next IFor I = LBound(arr4) To UBound(arr4)For J = LBound(arr4, 2) To UBound(arr4, 2)Debug.Print "arr4(" & I & "," & J & ")= " & arr4(I, J) & " ";NextDebug.Print
Next
Debug.Print'总结
'数组的非最后1维不能变化,变了直接报错越界
'数组的最后1维也只能从小变大,如循环后,又从大变小会出问题,会把之前内容redim后抹掉
'但preserve也不行,还是因为如果最后一维因为循环从大到小后,会导致preserve出错(因为preserve必须后面得包含前面的,不能变小)End Sub
VBA 为什么你redim() 动态二维数组总出错?因为 redim 动态数组不太适合和循环搭配相关推荐
- C++动态二维数组演示的代码
将代码过程中经常用到的代码珍藏起来,下边资料是关于C++动态二维数组演示的代码. #include <iostream> #include <string>using name ...
- C++建立动态二维数组
C++建立动态二维数组主要有两种方法: 1.使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组 int **b=new int*[row ...
- 动态二维数组赋值及for循环遍历和toString遍历
package com.Summer_0421.cn;import java.util.Arrays;/*** @author Summer* 动态二维数组赋值及for循环遍历和toString遍历* ...
- C语言实现动态二维数组及相乘
一.二维数组的概念 1.二维数组本质上是以数组作为数组元素的数组,即数组的数组. 2.二维数组就是一个有行和列的矩阵,每一行代表一个数组,即数组的数组. 3.每一行数组内元素所在的位置可以用行和列号 ...
- C++之定义动态二维数组
C++之定义动态二维数组 直接上代码 #include"stdio.h" #include<iostream> using namespace std; int mai ...
- java创建动态二维数组
java创建动态二维数组 //声明Scanner对象,获取键盘输入值Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = s ...
- 二维动态数组空间分配 c语言,科学网—C语言中动态二维数组的使用和分配 - 王一哲的博文...
好多年不用C语言了,最后一次使用还是读研的时候写矩量法的时候了,看见VS的界面总能想起当年读书的时候的各种错误,往事随风.本程序应人之约,首先得到一个随机的矩阵,之后通过将矩阵分解为几个小矩阵统计小矩 ...
- C++——C++创建动态二维数组+memset()函数初始化
C++开辟动态二维数组的几种方法总结 原文链接:https://blog.csdn.net/xiang_shao344/article/details/99684395 一.用 new 来动态开辟一个 ...
- pb 创建动态二维数组
pb中二维数组定义:array[10,10] 定义出来的二维数组是固定长度的:无法像一维数组一样动态长度:那PB中如何创建动态二维数组,请看接下来的内容. 1.先创建结构体structure 2.结构 ...
最新文章
- 超燃!Apache Flink 全球顶级盛会强势来袭
- 《从问题到程序:用Python学编程和计算》——第3章 基本编程技术 3.1 循环程序设计...
- linux epoll事件模型详解
- 利用Git Bash 远程访问服务器
- JDBC的开发流程是什么?
- jquery ajax调用服务器端指定的函数的三种方式
- Java线程池 - 问题驱动学习
- 皮卡丘为什么不进化_神奇宝贝:为什么皮卡丘一直不愿意进化?原因竟然是这个!...
- BrightHouse存储引擎
- java赋值两个对象数组 clone_有关java对象数组的clone问题
- 飞思卡尔单片机c语言编程详解,主流16位单片机学习详解:飞思卡尔MC9S12G系列...
- 屏幕取色软件ColorPix
- Windows10重新安装软件商店
- 怎么把汉字转换成URL编码
- python中class什么意思_python中的class是什么意思
- FastAdmin下拉显示
- mysql 12点_MySQL 查询昨天中午12点到今天中午12点的数据
- 深度学习笔记:01快速构建一个手写数字识别系统以及张量的概念
- 微商卖货怎么引流?微商怎么找客源?
- OpenStack社区周报:Neutron网络之负载均衡,设计OpenStack云时需要避开的十个误区...