0

我想知道我做错了什么...

我打开了一个包含三个表格的 word 文档(在 word 2010 中)。我想在 VBA 中测试基本表提取并按照http://msdn.microsoft.com/en-us/library/office/aa537149(v=office.11 ​​).aspx 的说明进行操作。

    Sub ExtractTableData()
    Dim doc As Word.Document
    Dim tbl As Word.Table
    Dim rng As Word.Range
    Dim sData As String
    Dim aData1() As String
    Dim aData2() As String
    Dim aDataAll() As String
    Dim nrRecs As Long
    Dim nrFields As Long
    Dim lRecs As Long
    Dim lFields As Long

    Set doc = ActiveDocument
    Set tbl = doc.Tables(1)
    Set rng = tbl.ConvertToText(Separator:=vbTab, _
        NestedTables:=False)
    ' Pick up the delimited text into and put it into a string variable.
    sData = rng.Text
    ' Restore the original table.
    doc.Undo
    ' Strip off last paragraph mark.
    sData = Mid(sData, 1, Len(sData) - 1)
    ' Break up each table row into an array element.
    aData1() = Split(sData, vbCr)
    nrRecs = UBound(aData1())
    ' The messagebox below is for debugging purposes and tells you
    ' how many rows are in the table.  It is commented out but can
    ' be used simply by uncommenting it.
    'MsgBox "The table contained " & nrRecs + 1 & " rows"
    'Process each row to break down the field information
    'into another array.
    For lRecs = LBound(aData1()) To nrRecs
        aData2() = Split(aData1(lRecs), vbTab)
        ' We need to do this only once!
        If lRecs = LBound(aData1()) Then
            nrFields = UBound(aData2())
            ReDim Preserve aDataAll(nrRecs, nrFields)
        End If
        ' Now bring the row and field information together
        ' in a single, two-dimensional array.
        For lFields = LBound(aData2()) To nrFields
            aDataAll(lRecs, lFields) = aData2(j)
        Next
    Next
End Sub

我在这一行遇到错误:ReDim Preserve aDataAll(nrRecs, nrFields),这是由于“nrFields”被设置为负值 (-1)...

不知道数组的上限如何是负值......对此的任何帮助将不胜感激。

4

3 回答 3

1

我想通了 - 我试图提取一个嵌套表。我必须循环浏览所有子表并单独提取。此外,我必须在提取之前搜索并删除^p以保留表结构。

在我弄清楚之后,我注意到 MS 代码示例有一个错误:aData2(j)实际上应该是aData2(lFields).

希望这对其他新手有所帮助!

于 2013-06-12T14:11:53.713 回答
1

如果 UBound 为 -1 且 LBound = 0,则数组为空。您可以按如下方式生成一个空数组:

Dim EmptyArray() As String
Dim s As String
EmptyArray = Split("")
Debug.Print (UBound(EmptyArray)) ' displays -1
Debug.Print (LBound(EmptyArray)) ' displays 0

在您的情况下,我怀疑如果数组为空,您需要跳过处理:

aData1 = Split(...)
If (UBound(aData1) < LBound(aData1) Then
    ' UBound is -1 and LBound is 0, array is empty, nothing to do
Else
    ' Array is non-empty, do your stuff
End If
于 2013-06-12T14:47:53.507 回答
0

虽然很奇怪,但 VARIANT SAFEARRAY 可能对任何维度都有负的下限值上限值。数组范围是 LBound(,dimension) 到 UBound(,dimension)。

必须为真的是 UBound >= LBound。

要获取数组大小,请使用 UBound - LBound + 1。

过去习惯使用Option BaseVBA 代码顶部的语句设置下限,当然,这不会影响第 3 方库返回的数组。大多数人曾经使用 1 作为下限。

于 2013-05-28T11:01:24.207 回答