VBA UBound返回负值

时间:2013-05-28 10:52:28

标签: vba ms-word word-vba

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

我有一个单词文档打开(在单词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保留aDataAll(nrRecs,nrFields),这是由于“nrFields”设置为负值(-1)......

不知道数组的上限是否为负值...对此的任何帮助都将非常感激。

3 个答案:

答案 0 :(得分:1)

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

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

希望这有助于其他一些新手!

答案 1 :(得分: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

答案 2 :(得分:0)

虽然非常奇怪,但VARIANT SAFEARRAY可能会为任何维度提供负的较低上限值。数组范围是LBound(,维度)到UBound(,维度)。

必须如此,UBound&gt; = LBound。

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

以前使用VBA代码顶部的Option Base语句设置下限是常规,当然,这不会影响第三方库返回的数组。大多数人习惯使用1作为下限。