Excel 雷迪姆保护火灾&x27;超出范围';错误

Excel 雷迪姆保护火灾&x27;超出范围';错误,excel,vba,multidimensional-array,Excel,Vba,Multidimensional Array,我想生成一个二维数组,包含2个固定列和动态行。 结果应为(例如): 到目前为止,我有下面的代码,它似乎适用于数组的第一个条目,但一旦我重新分配数组(第二次),就会出现错误9“下标超出范围”: Dim rng As Range: Set rng = Sheet1.UsedRange Dim rws() As String Dim n As Integer, r As Integer, FirstRow As Integer, LastRow As Integer, g As Integer Dim

我想生成一个二维数组,包含2个固定列和动态行。 结果应为(例如):

到目前为止,我有下面的代码,它似乎适用于数组的第一个条目,但一旦我重新分配数组(第二次),就会出现错误9“下标超出范围”:

Dim rng As Range: Set rng = Sheet1.UsedRange
Dim rws() As String
Dim n As Integer, r As Integer, FirstRow As Integer, LastRow As Integer, g As Integer
Dim groupLevel() As Long, i As Long

i = 1: ReDim Preserve groupLevel(1 To 1, 1 To 2)

'get rows to look in for grouped rows
rws = Split(Replace(rng.AddressLocal, ":", ""), "$")
FirstRow = rws(2)
LastRow = rws(4)

With rng.Rows
     For r = FirstRow To LastRow
            For g = 2 To 8
                If .Rows(r).OutlineLevel = g Then
                    groupLevel(i, 1) = r
                    groupLevel(i, 2) = .Rows(r).OutlineLevel
                    i = i + 1
                    ReDim Preserve groupLevel(1 To i, 1 To 2)     '<<<<<<<<<<<<<< error 9
                End If
            Next
     Next r
End With
Dim rng As Range:设置rng=Sheet1.UsedRange
Dim rws()作为字符串
Dim n为整数,r为整数,第一行为整数,最后一行为整数,g为整数
Dim groupLevel()一样长,我一样长
i=1:ReDim保留组级别(1到1,1到2)
'获取要查找分组行的行
rws=Split(替换(rng.AddressLocal,“:”,“),“$”)
第一行=rws(2)
LastRow=rws(4)
带rng.行
对于r=第一行到最后一行
对于g=2到8
如果.Rows(r).OutlineLevel=g,则
组级别(i,1)=r
groupLevel(i,2)=.行(r).大纲视图级别
i=i+1

ReDim Preserve groupLevel(1到i,1到2)“通过`Application.Index()”解决方法

除了Scott Craner将
Application.Transpose()
应用于行/列维度已更改的数组的有效注释之外,我还演示了一种使用
Application.Index()
的方法

子测试()
尺寸rng As范围:设置rng=Sheet1.UsedRange
Dim rws()作为字符串
Dim n为整数,r为整数,第一行为整数,最后一行为整数,g为整数

Dim groupLevel()作为变量“非常感谢大家的投入!非常感谢!我决定按照Vitaliy Prushak的建议,先得到我的数组维度,然后重新定义一次,这就省去了很多麻烦

Dim rng As Range: Set rng = Sheet1.UsedRange
Dim rws() As String
Dim r As Integer, FirstRow As Integer, LastRow As Integer, g As Integer
Dim groupLevel(), RowsCount As Long, i As Long

'get rows to look in for grouped rows
rws = Split(Replace(rng.AddressLocal, ":", ""), "$")
FirstRow = rws(2)
LastRow = rws(4)

'get dimentions for array first ----------------------------------
With rng.Rows
For r = FirstRow To LastRow
    If .Rows(r).OutlineLevel > 1 Then RowsCount = RowsCount + 1
    Next r '------------------------------------------------------

    'set array----------------------------------------------------
    ReDim groupLevel(1 To RowsCount, 1 To 2)
    '-------------------------------------------------------------

    'populate array with rows using a group-----------------------
    i = 1
    For r = FirstRow To LastRow
           For g = 2 To 8
               If .Rows(r).OutlineLevel = g Then
                   groupLevel(i, 1) = r
                   groupLevel(i, 2) = .Rows(r).OutlineLevel
                   i = i + 1
               End If
           Next
    Next r'-------------------------------------------------------

End With

'for debug
For r = 1 To UBound(groupLevel, 1)
        Debug.Print "Row " & groupLevel(r, 1) & vbTab & " GroupLevel [" & groupLevel(r, 2) & "]"
Next r
Debug.Print " ************ end *************"
但有一件事仍然困扰着我,那就是必须使用相同的
。。。接下来
两次,一次只检查大纲级别是否大于1以确定数组大小,第二次实际填充数组。这是没有办法的,是吗?我这样问是因为行的数量变化很大(在某些情况下是十几行,在其他情况下是数百行或数千行……)

当在大范围内循环时,这不会减慢速度吗?我还需要应用同样的方法来检查分组列


谢谢

您只能
Redim保留
一维数组。多维数据只能在不保留数据的情况下重拨。谢谢!所以基本上,我无法在这里实现我想要的。对吧?”因为我需要在前进的过程中添加行。是否使用一个一维数组来保存一个自定义类型,该类型的属性为row num和group level?这是一个很好的选择?您可以重划保留多维数组,但只能保留最后一个维度。@GYGLK您可以先获取维度,然后重划数组,然后填充数组翻转数组,这样您就填充了
GROUPBLEVEL(1到2,1到i)
然后转置。如果数组相对较小,则可以使用
应用程序。转置
,或者只是迭代数组并填充另一个转置的数组。
Sub test()
    Dim rng As Range: Set rng = Sheet1.UsedRange
    Dim rws() As String
    Dim n As Integer, r As Integer, FirstRow As Integer, LastRow As Integer, g As Integer
    Dim groupLevel() As Variant                                     ' <<<< [0] declare as Variant

    Dim i As Long
    i = 1
    groupLevel = rng                                                ' <<<< [1] assign data to 1-based 2-dim array

    'get rows to look in for grouped rows
    rws = Split(Replace(rng.AddressLocal, ":", ""), "$")
    FirstRow = rws(2)
    LastRow = rws(4)
    With rng.Rows
         For r = FirstRow To LastRow
                For g = 2 To 8
                    If .Rows(r).OutlineLevel = g Then
                        groupLevel(i, 1) = r
                        groupLevel(i, 2) = .Rows(r).OutlineLevel
                        i = i + 1
    ''                    ReDim Preserve groupLevel(1 To i, 1 To 2)  ' [2] delete line <<<<<<<<<<<<<< error 9
                    Else
                        If r = 3 Then
                            groupLevel(i, 1) = r
                            groupLevel(i, 2) = g
                        i = i + 1
                        End If
                    End If
                Next
         Next r
    End With
    '[3] provide for single result or no results
    If i < 2 Then i = 2
    '===================================================
    '[4] use Application.Index for pseudo ReDim Preserve
    '---------------------------------------------------
    groupLevel = Application.Index(groupLevel, Evaluate("row(1:" & i & ")"), Array(1, 2))

'write array to any target
'Sheet2.Range("A2").Resize(UBound(groupLevel), UBound(groupLevel, 2)) = groupLevel

End Sub

Dim rng As Range: Set rng = Sheet1.UsedRange
Dim rws() As String
Dim r As Integer, FirstRow As Integer, LastRow As Integer, g As Integer
Dim groupLevel(), RowsCount As Long, i As Long

'get rows to look in for grouped rows
rws = Split(Replace(rng.AddressLocal, ":", ""), "$")
FirstRow = rws(2)
LastRow = rws(4)

'get dimentions for array first ----------------------------------
With rng.Rows
For r = FirstRow To LastRow
    If .Rows(r).OutlineLevel > 1 Then RowsCount = RowsCount + 1
    Next r '------------------------------------------------------

    'set array----------------------------------------------------
    ReDim groupLevel(1 To RowsCount, 1 To 2)
    '-------------------------------------------------------------

    'populate array with rows using a group-----------------------
    i = 1
    For r = FirstRow To LastRow
           For g = 2 To 8
               If .Rows(r).OutlineLevel = g Then
                   groupLevel(i, 1) = r
                   groupLevel(i, 2) = .Rows(r).OutlineLevel
                   i = i + 1
               End If
           Next
    Next r'-------------------------------------------------------

End With

'for debug
For r = 1 To UBound(groupLevel, 1)
        Debug.Print "Row " & groupLevel(r, 1) & vbTab & " GroupLevel [" & groupLevel(r, 2) & "]"
Next r
Debug.Print " ************ end *************"