Ошибка “Subscript out of range” (Индекс вне диапазона) в VBA Excel (Visual Basic for Applications) — это одна из наиболее распространенных ошибок, которую вы можете получить. Она возникает, когда ваш код пытается обратиться к элементу массива, коллекции или диапазона, используя Индекс (номер), который выходит за пределы допустимого размера этого объекта.
Причины возникновения ошибки “Subscript out of range”
Ошибка 9 (как она регистрируется в коде VBA) возникает по следующим причинам:
1. Неправильный индекс массива
Если у вас есть массив, объявленный с определенным размером, вы пытаетесь обратиться к элементу, который не существует.
Пример:
Dim MyArray(1 To 5) As String ‘ Массив размером 5 элементов (индексы 1, 2, 3, 4, 5)
MyArray(6) = "Test" ‘ <— ОШИБКА: Индекс 6 выходит за пределы (1-5)
2. Неправильное обращение к коллекции
Это касается объектов, которые являются коллекциями, например, Worksheets, Charts, или Shapes.
Пример:
‘ В книге только 3 листа (Лист1, Лист2, Лист3)
ThisWorkbook. Worksheets(4).Activate ‘ <— ОШИБКА: Листа с индексом 4 нет
3. Неправильное обращение к диапазону (Range)
Хотя в большинстве случаев обращение к ячейке Range("A10") не вызывает эту ошибку, она может появиться при работе с Именованными диапазонами, если вы пытаетесь получить доступ к несуществующему именованному диапазону, или при некорректном использовании методов, возвращающих массив.
4. Проблемы С Циклами (Off-by-One Error)
Частая причина — ошибка “на единицу” в циклах For…Next, когда цикл выходит за пределы массива.
Пример: Если массив имеет 10 элементов (с индексом 0 до 9), а цикл идет до 10:
For i = 0 To 10 ‘ <— Если массив заканчивается на 9, то i=10 вызовет ошибку
‘ … код
Next i
Как Исправить Ошибку “Subscript out of range”
Исправление всегда заключается в том, чтобы убедиться, что индекс, который вы используете, находится Внутри допустимого диапазона объекта.
1. Использование UBound и LBound (Для массивов)
Для динамически изменяющихся массивов используйте встроенные функции VBA, чтобы всегда знать границы массива:
Dim MyArray() As Variant
‘ … (Массив заполняется данными)
Dim LastIndex As Long
LastIndex = UBound(MyArray) ‘ Получаем верхнюю границу
For i = LBound(MyArray) To LastIndex ‘ Используем границы, а не фиксированные числа
‘ Ваш код
Next i
2. Проверка коллекции перед обращением
Если вы работаете с листами, окнами или другими коллекциями, сначала проверьте их количество.
If ThisWorkbook. Worksheets. Count >= 4 Then
ThisWorkbook. Worksheets(4).Activate
Else
MsgBox "В книге недостаточно листов!"
End If
3. Использование On Error Resume Next (Осторожно!)
Иногда эту ошибку можно временно игнорировать, чтобы проверить, существует ли что-то, прежде чем обращаться к этому. Используйте это только в крайних случаях, так как это подавляет другие, более серьезные ошибки.
On Error Resume Next ‘ Игнорировать следующую ошибку
ThisWorkbook. Worksheets("Sheet4").Activate
If Err. Number <> 0 Then
MsgBox "Листа Sheet4 не существует!"
Err. Clear
End If
On Error GoTo 0 ‘ Возвращаем нормальную обработку ошибок
4. Проверка логики циклов
Если ошибка возникает в цикле, убедитесь, что верхняя граница цикла (To N) на единицу меньше, чем предполагаемая граница, если массив начинается с индекса 0.