【问题标题】:Jagged Arrays in VBAVBA 中的锯齿状数组
【发布时间】:2013-04-21 12:52:26
【问题描述】:

所以我想创建一个数组数组,根据我收集到的数据,我需要一个锯齿状数组。

我有一个数组 x(i,j),它定义了一个 nxn 整数矩阵。对于 k 的每次迭代,该数组中的两个整数值被交换以尝试改进矩阵 x(i,j)。我需要在每次 k 迭代后创建一个数组来存储这个矩阵 x(i,j)。

为了澄清,说我有没有

1  2  3
4  5  6
7  8  9

然后我执行了一次迭代,交换了数组中的两个元素:

7  2  3
4  5  6
1  8  9

我希望能够将这些数组存储在一个数组中,以便随时调用。我在这里尝试了一个解决方案:

Dim y() As Variant 'Declare as a variant to contain arrays
ReDim y(1 To IterationLimit) 'This will be the jagged array

For k = 1 To IterationLimit
'Some code goes here for the swap
    y(k) = x(i,j)
next k

现在说我想要第 85 次迭代。我希望能够输入 y(85) [或类似的] 来提取特定时间的矩阵 x(i,j)。

希望我已经解释得足够好。任何帮助表示赞赏,我真的坚持这一点。

编辑:删除的代码

【问题讨论】:

  • 当你说你有数组 x(i,j) 时,ij 代表这个数组的边界吗?还是x 是一个数组数组,其中一个子数组由索引(i,j) 标识?
  • i 和 j 确实代表边界是的。所以对于上面的例子,我认为是 x(1 to 3, 1 to 3)
  • 为了给您更多信息,如果我要从上面的矩阵中引用 x(2,2),这将采用第二行和第二列中的值,即 5。不是确定这是否有帮助。
  • 好的,所以当您执行 y(k) = x(i,j) 时发生的情况是您y(k) 存储为单个值(由 i/ 表示的 itme x 数组中的 j 个坐标)。
  • 如果您希望能够通过y(k) 提取整个 数组,那么您只需在迭代期间执行y(k) = x

标签: vba excel jagged-arrays


【解决方案1】:

好的。我认为您可能根本没有正确地将数组分配给y。正如我在 cmets 中提到的:

y(k) = x(i,j) 将 i/j 坐标表示的值存储在 x 数组中。

为了让y(k)当时能引用整个数组x,你可以这样做:

y(k) = x

如果仍然无法正常工作,那么可能还有其他问题不正确。这是一个示例,其中我有一个名为 baseArray 的 2x2(基数为 0)数组,我明确地填充了一些值。我从i = 0 to itLimit 迭代,在每次迭代中,我迭代数组中的项目,将值乘以2,然后存储在数组变量tmpArray 中。值转换后,我将它们存储在arrContainer 中,然后继续进行下一次For i = 0 to itLimit 迭代。

Sub FunWithArrays()
Dim itLimit As Integer  '## Iteration limit.'
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim baseArray(2, 2) As Variant '## an example array.'

    '## Put some dummy data in this array.'
    baseArray(0, 0) = 1
    baseArray(0, 1) = 65
    baseArray(0, 2) = 13
    baseArray(1, 0) = 14
    baseArray(1, 1) = 29
    baseArray(1, 2) = 44
    baseArray(2, 0) = 9
    baseArray(2, 1) = 16
    baseArray(2, 2) = 33

Dim tmpArray(2, 2) As Variant '## This will temporarily hold values as we transform them.'
Dim arrContainer() As Variant '## an array of arrays, to store the iteration arrays.'

    itLimit = 2  '## set a max iteration.'

    For i = 0 To itLimit
        '## Transform the base array somehow'
        For j = LBound(baseArray, 1) To UBound(baseArray, 1)
            For k = LBound(baseArray, 2) To UBound(baseArray, 2)
                tmpArray(j, k) = baseArray(j, k) * 2
            Next
        Next
        ReDim Preserve arrContainer(i)
        arrContainer(i) = tmpArray
    Next

    Dim y As Variant
    '## Now, refer to a single iteration stored in the arrContainer variable:

    y = arrContainer(2)

End Sub

在第一个屏幕截图中,我使用Locals 窗口查看变量及其包含的内容。在第一次迭代之后,您可以看到tmpArray 已经被填充,并且与baseArray 的尺寸相同,但其中的值已乘以2。

检查arrContainer 变量,我们看到它只有1 个项目,并且该项目是一个数组,等于我们在上面的迭代中创建的tmpArray

在最后一次迭代之后,我们可以查看 arrContainer 并看到它包含 3 个项目(0 到 2,根据我们的 For i to itLimit 循环)。 arrContainer 中的每个数组都等于上面迭代中创建的数组之一。

我们现在可以参考这些项目,例如:

Dim y as Variant y = arrContainer(2) '# or any in bounds index could be used instead of "2"'

最后使用 VBE Locals 窗口查看y

【讨论】:

  • @David Zemens 哦,这太棒了,它正在工作! locals 窗口是我以前从未想过使用的东西,但事实证明它非常有用!为了输出到单元格,我使用了 Cells(20 + i, 20 + j).Value = ArrContainer(80)(i, j) [在 i 和 j For 循环内]。就一个问题! ReDim Preserve 的目的是什么?保护区是做什么的?
  • @Matt ReDim 允许您重新声明和/或调整数组大小。 Preserve 保留现有值。 ReDim arrContainer(3)ReDim Preserve arrContainer(3) 之间的区别在于,第一个语句以上限 = 3 调整数组大小,但擦除其内容,而后者以上限 = 3 调整数组大小,同时保留其内容。
  • @Matt 进一步:我们最初对arrContainer as Variant 进行了无边界标注,因此像arrContainer(0) = "blah" 这样的语句会出错。每次迭代,ReDim Preserve 使数组更大(以容纳新值),并保留现有内容。你可以在设置itLimit 之后ReDim arrContainer(itLimit-1),这将创建一个正确大小的数组。但是在使用循环时,通常事先不知道大小,所以我更喜欢在循环内使用ReDim Preserve
猜你喜欢
  • 2015-05-06
  • 2021-05-04
  • 2017-05-06
  • 1970-01-01
  • 2013-04-04
  • 2016-08-24
  • 2012-03-15
  • 2015-09-23
  • 2020-04-02
相关资源
最近更新 更多