简体   繁体   中英

Subscript out of range when looping through array excel VBA

I am trying to split a string in excel and then writing each element of the string into one column of another sheet but i cant seem to finish looping before it gets a subscript out of range error.

Sub S1()

Dim Wb As Workbook
Dim rowValue() As String
Dim i As Variant

For i = 2 To 15500
With Worksheets(1)
    Value2 = Worksheets(1).Cells(i, 1)
    rowValue = Split(Worksheets(1).Cells(i, 1).Value, " ")
    rowValue(11) = rowValue(11) & " " & rowValue(12) & " " & rowValue(13)
    arraySize = UBound(rowValue) - LBound(rowValue) + 1
    If arraySize > 3 Then
        For x = 0 To arraySize
            'Place the split values into 1 column each
        Worksheets("Sheet2").Cells(i, x + 1).Value = rowValue(x)

        Next x
    Else
        'do nothing
    End If
End With
Next i

Above is my code, there are about 15500 rows in the first sheet. Everything works fine from rows 1-29 but after that I got the run-time error 9, subscript out of range.

Anyone knows why the loop stops after 29 rows?

Here is your new code:

Sub S1()
    Dim i As Integer, arr_Split() As String
    For i = 2 To 15500
        arr_Split = Split(Sheets(1).Cells(i, 1), " ")
        Range(Sheets(1).Cells(i, 2), Sheets(1).Cells(i, 2 + UBound(arr_Split))) = arr_Split
    Next i
End Sub

Try in out in place of the entire sub. Excel users often do things the hard way instead of checking if there are built-in features already created for the same task.

Some of the problems with your original subroutine:

  • You declare Wb as a Workbook but do not use it.

  • You don't declare Value2 but you use it.

  • You don't declare arraySize but you use it.

  • You don't declare x but you use it.

  • You use a With / End With Statement for no reason (since you don't refer to . between With and End With ).

  • The With / End With Statement begins & ends 14,998 times . (See below.)

  • You hard code 11,12,13, which can be a problem unless all original values are 9 words long.

  • If (for example) your array has 5 items, arraySize will calculate as 3. (If an array has 5 items, they are numbered 0 to 4, and your formula calculates arraySize as 4 minus 1.

  • Your If arraysize>3 line will be incorrect due to errors above.

  • You're using a Variant ( i ) to count strictly integers.

  • The For / Next loop is using improper values for x .

  • If X=0 then Cells(i, x + 1) is incorrect since it starts writing at column 1 (replacing the source text).

  • Else 'do nothing is unneeded since Else statements are optional.

  • Row numbers are hard coded, meaning that you will always process exactly 14,998 rows.

  • There is no End Sub . (a copy/paste error I assume)

  • You're not using Option Explicit (which is why you didn't notice undeclared variables).

  • There was a couple more things which I am forgetting at the moment. Give me a moment to list all the things wrong with your code... :)


I left out these lines since (without sample data) it's unclear what they do. If I knew what they did, I am positive there's a better way to code the (possibly without hard-coded values).

  • rowValue(11) = rowValue(11) & " " & rowValue(12) & " " & rowValue(13)

  • If arraySize > 3 Then

Add them back in if needed, but make sure the variables are declared and that there is no way the hard-coded values will cause a problems can cause a problem with any possible data you have or will ever have.

This is a problem:

For x = 0 To arraySize

An array of size 10 (and lower bound=0) has an upper bound of 9, so there would be (eg) no rowValue(10)

Reworked with bounds checking:

Sub S1()

    Dim Wb As Workbook, rowValue, i As Long, ub As Long

    For i = 2 To 15500

        rowValue = Split(Worksheets(1).Cells(i, 1).Value, " ")
        ub = UBound(rowValue)

        If ub >= 13 Then
            rowValue(11) = rowValue(11) & " " & rowValue(12) & " " & rowValue(13)
        End If

        If ub > 2 Then
            Worksheets("Sheet2").Cells(i, 1).Resize(1, ub + 1).Value = rowValue
        End If

    Next i

End Sub

use On Error Resume Next

Sub S1()

    Dim Wb As Workbook
    Dim rowValue() As String
    Dim i As Variant

    For i = 2 To 15500
        With Worksheets(1)
            Value2 = Worksheets(1).Cells(i, 1)
            On Error Resume Next ' USE THIS
            rowValue = Split(Worksheets(1).Cells(i, 1).Value, " ")
            rowValue(11) = rowValue(11) & " " & rowValue(12) & " " & rowValue(13)
            arraySize = UBound(rowValue) - LBound(rowValue) + 1
            If arraySize > 3 Then
                For x = 0 To arraySize
                    'Place the split values into 1 column each
                Worksheets("Sheet2").Cells(i, x + 1).Value = rowValue(x)

                Next x
            Else
                'do nothing
            End If
            On Error GoTo 0  ' USE THIS
        End With
    Next i

End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM