【问题标题】:Nested dimensions in macro array argument宏数组参数中的嵌套维度
【发布时间】:2018-07-26 22:02:27
【问题描述】:

我正在为 Word 中的宏提供多维数组。每个元素都是一个数组,每个数组元素有 2 个值,一个图像的名称和一个简短的描述。宏是:

For i = LBound(figures, 1) To UBound(figures, 1)
    cgmImage = "C:\path\to\images\" & figures(i, 0) & ".jpeg"
    Selection.InlineShapes.AddPicture FileName:=cgmImage, LinkToFile:=False, SaveWithDocument:=True
    Selection.TypeParagraph
    With Selection
        .Font.Size = 14
        .Font.Bold = True
        .Font.Underline = wdUnderlineSingle
        .TypeText Text:=figures(i, 1)
    End With
Next i

示例输入数组为:

[
    ['123','image 1'],
    ['456','image 2']
]

宏起作用,插入每个图像及其描述。但是我现在想添加第三个元素,这个元素本身就是一个代表表格的二维数组。所以输入看起来像这样:

[
    [ '123','image 1', [['val1','val2'],['val3','val4']] ],
    [ '456','image 2', [['val1','val2'],['val3','val4']] ]
]

在宏中,我将使用第三个元素来创建一个表格。但是,如果我将这样的输入数据提供给我的原始宏,我现在会在这一行得到一个“下标超出范围”错误:

cgmImage = "C:\path\to\images\" & figures(i, 0) & ".jpeg"

我想要迭代的是整个数据结构的第一级(例如,对于我上面提供的示例数据,2 次迭代)。即使我为LBoundUBound 提供了“维度”属性,我仍然会收到错误消息,这不应该发生,因为顶级数组元素的第一个元素始终只是一个字符串(图像文件名)。我怎样才能做到这一点?并且访问代表表格的第三个元素是否会沿着 :figures(i,2,X,X) 的行?

编辑:

数组创建是在 Python 中,只是一个标准的列表类型。宏的调用是使用mhammond pywin32 module 完成的,这是该技术的简化版本:

import win32com.client as win32
word = win32.gencache.EnsureDispatch("Word.Application")
template = word.Documents.Open("\path\to\file.docm")
word.Run("macroName",imagesArray)

然后我保存并关闭它

【问题讨论】:

  • 你是如何创建数组的?通过代码?如果是,那么将其包括在内(以及任何其他相关行)会有所帮助
  • 我从 Python 脚本中的 XML 文件中提取它(只是标准列表数据类型),然后使用 pywin32 模块使用该数组作为参数运行宏。我已经添加了上面的代码。
  • figures(i)(0) 有效吗? VBA 中的数组索引与 Python 不同。
  • 如果您查看 Watches 窗口中的数组,它看起来是否符合预期?
  • 是的,阵列看起来与预期的一样。好的,使用 figures(i)(0) 前 2 个元素现在可以再次工作,并且该错误消失了。很奇怪,因为我在另一个宏中使用另一个表示法作为 2D 数组参数,它工作正常......无论如何,我仍然无法访问第三个 2D 数组元素,无论是 figures(i)(2)(0)(0) 还是 figures(i)(2)(0, 0),现在这些语句给出下标范围错误。

标签: vba for-loop indexing ms-word


【解决方案1】:

如果最里面的数组是数组的数组,那么像figures(i)(j)(k)(l) 这样的方法应该是要走的路

您可以使用UBound(array,index)LBound(array,index) 函数来获取其index 维度的实际上下数组边界

例如,根据您显示的数据行,您可以考虑以下代码:

Option Explicit

Sub main()
    Dim figures(1) As Variant

    figures(0) = Array("123", "image 1", Array(Array("val1", "val2"), Array("val3", "val4"))) ' see how the innermost array is an array of arrays, too
    figures(1) = Array("456", "image 2", Array(Array("val5", "val6"), Array("val7", "val8"))) ' see how the innermost array is an array of arrays, too

    Dim i As Long, j As Long, k As Long, l As Long
    For i = LBound(figures) To UBound(figures)
        For j = LBound(figures(i)) To UBound(figures(i))
            If IsArray(figures(i)(j)) Then
                For k = LBound(figures(i)(j)) To UBound(figures(i)(j))
                    For l = LBound(figures(i)(j)(k)) To UBound(figures(i)(j)(k))
                        Debug.Print figures(i)(j)(k)(l)
                    Next
                Next
            Else
                Debug.Print figures(i)(j)
            End If
        Next
    Next
End Sub

【讨论】:

  • 好吧,我不能检查我的家庭电脑,我会在星期一检查一下,看看情况如何。谢谢!
  • 我在 lin For l = LBound(figures(i)(j)(k)) To UBound(figures(i)(j)(k)) 上收到“下标超出范围”错误。
  • 必须处理不同于普通数组的输入 Python 数组。虽然它对于更高级别的数组工作得非常好......
  • Oooooookay 所以我查看了 VBA 监视窗口中输入数据的每个元素。结果是二维表格元素,第一个索引如下:figures(1)(2)(0)(0),但其他索引如下:figures(2)(2)(0,0)。它们都是在 Python 脚本中以完全相同的方式创建的,所以我不知道为什么它们在 VBA 中的索引不同。
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 2018-01-25
相关资源
最近更新 更多