ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] VBA数组嵌套的问题

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-2-12 13:00 | 显示全部楼层 |阅读模式
我现在需要生成200个3*4的数组,我知道可以通过dim arr(1 to 3, 1 to 4, 1 to 200)来实现,但这样的话有一个问题就是我将单独的一个数组(比如说第34个3*4s数组)拿出来赋值到单元格就会很麻烦(VBA似乎没有方便截取子数组的方法,如果有请告诉我哈)。因此我想到是否可以用数组嵌套的方法,比如说arr=array(array(1,2,3),array("a","b","c")),由于我要生成200个同维数组,且需要用到循环,所以用array的方法行不通。我也尝试用dim arr(1 to 200)(),但这样会报错,请问有没有什么好的方法可以帮我实现哈?做毕业论文所用,万分感谢!

TA的精华主题

TA的得分主题

发表于 2014-2-12 13:33 | 显示全部楼层
本帖最后由 香川群子 于 2014-2-12 13:41 编辑

十分简单,就按你说的用嵌套数组即可:

  1. Sub test()
  2.     Dim arr(1 To 200) '定义嵌套父数组arr
  3.     Dim x(1 To 3, 1 To 4) '定义子数组x
  4.     For i = 1 To 200
  5.         arr(i) = x '生成所需大小的嵌套数组
  6.     Next
  7.    
  8.     For i = 1 To 200
  9.         For j = 1 To 3
  10.             For k = 1 To 4
  11.                 cnt = cnt + 1
  12.                 arr(i)(j, k) = i & "_" & j & "_" & k
  13.                 '给嵌套数组中每个位置赋值 注意数组i,j,k参数位置引用方法
  14.             Next
  15.         Next
  16.     Next
  17.    
  18.     For i = 1 To 200
  19.         trr = arr(i) '输出每一个子嵌套数组时,可以先提取到临时变量trr中
  20.                 '结果是一个大小和你最初定义的子数组x一样的二维数组
  21.         Cells(i * 3 - 2, 1).Resize(3, 4) = trr '然后把这个二维数组trr输出到工作表中即可

  22.         Cells(i * 3 - 2, 5).Resize(3, 4) = arr(i) '当然事实上你不用费力转换直接输出就可以了。
  23.     Next
  24. End Sub
复制代码
呵呵,请参考!

评分

5

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-2-12 13:45 | 显示全部楼层
香川群子 发表于 2014-2-12 13:33
十分简单,就按你说的用嵌套数组即可: 呵呵,请参考!

万分感谢,而且解释很详细哈

TA的精华主题

TA的得分主题

发表于 2014-2-12 13:54 | 显示全部楼层
本帖最后由 香川群子 于 2014-2-12 13:55 编辑

补充,嵌套数组中,每一个子数组的大小也可以不同:
  1. Sub test2()
  2.     Dim arr(1 To 200)
  3.    
  4.     Dim x(2)
  5.     Dim y1(1 To 1, 1 To 2)
  6.     Dim y2(1 To 2, 1 To 3)
  7.     Dim y3(1 To 3, 1 To 4)
  8.     x(0) = y1
  9.     x(1) = y2
  10.     x(2) = y3
  11.    
  12.     For i = 0 To 200 - 1
  13.         arr(i + 1) = x(i Mod 3)
  14.     Next
  15.    
  16.     For i = 1 To UBound(arr)
  17.         For j = 1 To UBound(arr(i), 1)
  18.             For k = 1 To UBound(arr(i), 2)
  19.                 cnt = cnt + 1
  20.                 arr(i)(j, k) = i & "_" & j & "_" & k
  21.             Next
  22.         Next
  23.     Next
  24.     MsgBox cnt
  25.    
  26.     [a1].CurrentRegion = ""
  27.     cnt = 1
  28.     For i = 1 To 200
  29.         Cells(cnt, 1).Resize(UBound(arr(i), 1), UBound(arr(i), 2)) = arr(i)
  30.         cnt = cnt + UBound(arr(i), 1)
  31.     Next
  32.    
  33. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-2-12 14:11 | 显示全部楼层
香川群子 发表于 2014-2-12 13:54
补充,嵌套数组中,每一个子数组的大小也可以不同:

高手啊,学习了,呵呵

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-2-12 14:37 | 显示全部楼层
香川群子 发表于 2014-2-12 13:54
补充,嵌套数组中,每一个子数组的大小也可以不同:

感觉您数组运用的非常好哈,正好请教您一个困扰我很久的问题。就是VBA是否有简单提取子数组的方法,比如我现在有100*100的二维数组,如果我提取某一行或者某一列,可以用worksheetfunction.index方法,那么如果我要提取后50行后50列的数据生成一个新数组,有没有方法或属性可以简单实现呢?(当然用循环的方法单个赋值是可以,但这样感觉很麻烦)

TA的精华主题

TA的得分主题

发表于 2014-2-12 15:47 | 显示全部楼层
chj3751 发表于 2014-2-12 14:37
感觉您数组运用的非常好哈,正好请教您一个困扰我很久的问题。就是VBA是否有简单提取子数组的方法,比如我 ...

给你一个靠谱的答复:

一般人总是误以为:一句简单的VBA命令语句,会比一大堆循环语句命令效率更高……

事实上结论是相反的:【VBA中的For……Next、For Each……Next语句,才是效率最高的。】



你这样理解就对了:
任何简单语句命令,事实上都不是直接完成工作,而是一个集成代码的引用而已。

比如,sum(A1:A10)
它的本质还是sum里面有一个循环:
   For Each cel In Range("A1:A10")
        Sum = Sum + cel.Value
    Next

不可能有一蹴而就的好事。


呵呵。

所以,为了提取子数组而使用循环,本来就是非常正常不过的思维,没什么不好。
完全不用感觉痛苦而想要避免写循环代码。

→ 即,你应该习惯于为了需要而自己写循环代码……这往往是更高效的做法。







评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-2-12 16:03 | 显示全部楼层
chj3751 发表于 2014-2-12 14:37
感觉您数组运用的非常好哈,正好请教您一个困扰我很久的问题。就是VBA是否有简单提取子数组的方法,比如我 ...

当然,如果你就是喜欢看上去简洁的代码而不用理会实际代码运行效率,那么以下方法可行:
  1. Sub test2()
  2.     Dim arr(1 To 100, 1 To 20)
  3.     For i = 1 To 100
  4.         For j = 1 To 20
  5.             arr(i, j) = i & "_" & j
  6.         Next
  7.     Next
  8.     '以上定义二维数组arr并赋值   

  9.     '以下用投机的方法截取二维数组中的一部分(仍按二维数组形式)
  10.     With Sheets.Add '新增一个临时的工作表sheet
  11.         [a1].Resize(UBound(arr), UBound(arr, 2)) = arr  '输出二维数组arr的全部结果
  12.         brr = [a1].Offset(50, 10).Resize(50, 10)           '按指定要求提取对应部分数据存入二维数组brr
  13.         Application.DisplayAlerts = False '关闭Excel提醒功能
  14.         .Delete '删除此临时工作表sheet
  15.     End With
  16.    
  17.     Stop '停下来观察结果  brr数组
  18. End Sub
复制代码
当然,你也可以在本工作表中寻找一块可靠的空白区域进行同样的处理……不过有风险。
因此还是新增临时工作表处理比较好。


…………
显然,以上代码可能看上去比较容易,但速度效率肯定是更低而不是效率高……因此不是聪明人的选择。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-2-12 16:09 | 显示全部楼层
其实直接用For 循环提取结果,代码也很简单,并没有那么夸张地被认为是很繁琐。
  1. Sub test1()
  2.     Dim arr(1 To 100, 1 To 20)
  3.     For i = 1 To 100
  4.         For j = 1 To 20
  5.             arr(i, j) = i & "_" & j
  6.         Next
  7.     Next
  8.     '以上生成二维数组arr并赋值   

  9.     ReDim brr(51 To 100, 11 To 20) '定义一个和原来arr数组同样行列位置的新数组brr
  10.     For i = 51 To 100
  11.         For j = 11 To 20
  12.             brr(i, j) = arr(i, j) '因此新数组brr的行列位置可以和源数组arr的行列位置保持一致
  13.         Next
  14.     Next
  15.     Stop
  16.    
  17.     ReDim brr(1 To 50, 1 To 10) '定义一个新数组brr (下标从1开始)
  18.     For i = 1 To 50
  19.         For j = 1 To 10
  20.             brr(i, j) = arr(50 + i, 10 + j) '因此从源数组arr中提取数据时,必须考虑位置偏移的量。
  21.         Next
  22.     Next
  23.     Stop   

  24.     ReDim brr(1 To 50, 1 To 10) '定义一个新数组brr (下标从1开始)
  25.     For i = 51 To 100
  26.         For j = 11 To 20
  27.             brr(i - 50, j - 10) = arr(i, j) '因此从源数组arr中提取数据时,必须考虑位置偏移的量。
  28.         Next
  29.     Next
  30.     Stop
  31.    
  32. End Sub
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-2-13 00:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
香川群子 发表于 2014-2-12 16:09
其实直接用For 循环提取结果,代码也很简单,并没有那么夸张地被认为是很繁琐。

恩 学到很多东西哈,非常感谢
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 07:36 , Processed in 0.043859 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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