Я работаю над сценарием Visual Basic для коллеги некоторое время, которое проявляет странную ошибку, которую я просто не могу получить до конца. При запуске сценарий иногда работает нормально, но время от времени дает мне ошибку «Subscript out of range», которая быстро приводит к сбою Excel.VBA - ошибка индексации вне диапазона Excel
Первое, что я хотел бы знать, - это то, почему Excel сбой, даже если в скрипте есть код с ошибкой. В начале сценария у меня есть строка:
On Error GoTo ErrorCatch
следующие строки в нижней части:
ErrorCatch:
MsgBox "Error " & Err.Number & " detected - " & Err.Description _
& ". DebugCheckpoint = " & DebugCheckpoint & "."
Err.Clear
DisableSpeedBoosts
DebugCheckpoint является строка символов, которая изменяется в различных точках во время сценария, чтобы помочь узкой вниз, где сбой сценария. Последняя строка относится к паре функций в отдельном модуле той же таблицы. В начале, я запускаю следующую функцию:
Sub EnableSpeedBoosts()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
End Sub
Хотя у меня есть реверс в конце:
Sub DisableSpeedBoosts()
'Restore previous settings
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
End Sub
Однако, сценарий все еще происходит сбой Excel, даже с этой линией закомментированной, так что может не имеют значения.
Может ли кто-нибудь объяснить, почему Excel по-прежнему терпит крах, хотя ошибка была поймана и очищена? Это первое, что не имеет смысла.
Что касается самого скрипта, то, что я пытаюсь сделать, это заполнить таблицу основных данных на первом листе из таблицы с одинаковой структурой в файле импорта, проверяя фактические и потенциальные повторяющиеся строки. Что должен произойти что-то вроде этого:
Пользователь запустить сценарий и выбирает файл импорта через диалоговое окно,
Если действительный файл выбран, скрипт запускает некоторые основные проверяет, соответствует ли таблица на этом листе заданному формату,
Если эта проверка проходит, сценарий затем заполняет массив (ImportArray), используя эту таблицу, и второй массив из основной таблицы (DataArray).
Сценарий также инициализирует два пустых массива: один для элементов, которые будут добавлены в основную таблицу (AddArray), и один для фактического и потенциального дубликатов, которые будут добавлены ко второй таблице в одной и той же электронной таблице (LogArray) ,
Затем скрипт проходит через ImportArray, выполняет ряд проверок фактических и потенциальных дубликатов строк между этим и DataArray и добавляет строку в AddArray или LogArray или и то, и другое в случае потенциального дубликаты.
Наконец, как только он достигнет конца ImportArray, скрипт добавляет AddArray в главную таблицу и LogArray в таблицу дубликатов, печатает дружественное сообщение и завершает работу.
Это может быть не самый лучший или самый эффективный способ сделать это, но я думаю, что логика достаточно прочная, и когда она работает, она работает очень хорошо.Однако в коде есть странная, прерывистая ошибка, которую я не могу объяснить.
Когда я впервые создал это, код работал нормально на моей машине, но быстро разбил компьютер моих коллег. Мы оба используем Excel 2013 на Windows 7 в компании comuters, поэтому нет большого количества возможностей для настроек или вариантов, но сценарий отлично работал на моем компьютере, но разбился на нем. Сообщение об ошибке всегда одно и то же, некоторая форма ошибки «Subscript out the range», но я не смог объяснить, почему, тем более, что тот же самый скрипт смог импортировать тот же самый файл на моем компьютере без проблем ,
Запуск еще нескольких тестов и добавление кода отладки, теперь я смог надежно заново создать ошибку на своем компьютере. Я сузил крушение до одной строки, но теперь он имеет еще меньший смысл, чем раньше. В последней строке в следующем фрагменте кода происходит сбой не только сценарий, но Excel, а также:
If (PopulateArray(ImportArray) = False) Then
MsgBox "Failed to load import file. Aborting."
Exit Sub
End If
DebugCheckpoint = "ImportArray tests"
Debug.Print "ImportArray tests"
Debug.Print "ImportArray = (" & LBound(ImportArray, 1) & " to " & UBound(ImportArray, 1) _
& ", " & LBound(ImportArray, 2) & " to " & UBound(ImportArray, 2) & ")"
' Crashes on the next line
Debug.Print "ImportArray(1, 1) = " & ImportArray(1, 1)
Функция PopulateArray запрашивает у пользователя файл импорта и запускает некоторую проверку на файл. Если файл не выбран или тесты проверки не выдаются, он возвращает false. Вторая строка Debug.Print отображает размеры ImportArray, а тот, который сбой, просто пытается отобразить первый элемент. Вот что Немедленное окно выглядит как с помощью правильного файла импорта:
ImportArray tests
ImportArray = (1 to 143, 1 to 5)
Линия "Debug.Print "ImportArray (1, 1) =" & ImportArray (1, 1)" не отображается на этом окно, так что предположительно это один сбой сценария, но я не понимаю, почему. Мы знаем из предыдущей строки, что массив имеет 143 x 5 записей как с базовым, так и как элемент (1, 1) «вне диапазона»? Я пробовал различные фрагменты кода в разных частях скрипта, чтобы попытаться объяснить, что происходит, но безрезультатно. Кажется, что массив случайно исчезает.
Может кто-нибудь объяснить, что здесь происходит, или, по крайней мере, дать мне несколько указателей, чтобы попытаться исследовать это дальше. Несмотря на то, что я сузил крушение в одну строку, я не вижу абсолютно никакой причины, почему эта линия вызывает крушение. Я также не могу понять, почему он работал нормально, но теперь он сбой, когда все, что я сделал, это добавить код отладки.
Пожалуйста, помогите мне понять, что происходит, если можете.
EDIT:
ОК, я сузил это вниз совсем немного и добавил некоторые проверки ошибок кода функции Populate(), так что должно быть легче увидеть, что происходит сейчас. Вот основной сценарий в полном комплекте:
Sub ImportArrayTest()
Dim ImportArray() As Variant
If (PopulateArrayTest(ImportArray) = False) Then
MsgBox "Failed to load import file. Aborting."
Exit Sub
End If
Debug.Print "ImportArray tests"
Debug.Print "ImportArray = (" & LBound(ImportArray, 1) & " to " & UBound(ImportArray, 1) _
& ", " & LBound(ImportArray, 2) & " to " & UBound(ImportArray, 2) & ")"
Debug.Print ImportArray(3, 3)
End Sub
В то время как это обрезается вниз Populate функция():
Function PopulateArrayTest(ImportTable As Variant) As Boolean
Dim ImportFile As Workbook
Dim ImportFileName As Variant
PopulateArrayTest = False
ImportFileName = Application.GetOpenFilename("Excel (*.xls*),*.xls*", 1, "Please select report")
Set ImportFile = Application.Workbooks.Open(ImportFileName)
With ImportFile.Worksheets(1)
ImportTable = .Range(.Cells(5, 1), .Cells(.Range("a5").End(xlDown).Row, 5))
End With
Debug.Print "ImportTable tests"
Debug.Print "ImportTable = (" & LBound(ImportTable, 1) & " to " & UBound(ImportTable, 1) _
& ", " & LBound(ImportTable, 2) & " to " & UBound(ImportTable, 2) & ")"
Debug.Print "ImportTable (1, 1) = " & ImportTable(1, 1)
PopulateArrayTest = True
ImportFile.Close
End Function
Скрипт падает на линии «Debug.Print ImportTable (1, 1) "в функции PopulateArrayTest и использует Excel. Выход в ближайшем окне выглядит следующим образом:
ImportTable tests
ImportTable = (1 to 143, 1 to 5)
Так ImportTable идет правильно повторно размер в зависимости от размера таблицы в файле импорт, но доступ к ней дает «Подстрочную из ошибок диапазона. " Я действительно не понимаю, в чем проблема. Может ли кто-нибудь увидеть то, что мне не хватает?
к на самом деле сузить его, вы просто удаляете любые операторы «On Error Go To», чтобы макрос не сработал в самой строке, бросая первую ошибку и всплывая диалоговое окно, в котором вы нажмете «Debug», чтобы перейти на строку нарушения – user3598756
Если вызов 'PopulateArray' приводит к сбою Excel то это код, который вам нужно отправить. –
@Tim Williams Вызов 'PopulateArray', кажется, работает нормально. Сбой происходит позже, когда я пытаюсь получить доступ к данным. Тем не менее, я рассмотрю это больше, чтобы узнать, не проблема. – xarxziux