Remkomplekty.ru

IT Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Vba 6 ошибка

Ошибки в программе в Visual Basic 6.0

При обнаружении ошибки в программном коде компилятор Visual Basic 6.0выдает стандартное окно сообщения, которое содержит информацию о коде (Run-time error ‘438’) и названии (Object doesn’t support this property or method) ошибки (рис.5). Ошибки, связанные с процедурами и объектами, выделяются желтым «маркером» (рис.6). Ошибки, связанные с методами или свойствами самих объектов, выделяются синим «маркером» (рис.7). Для исправления ошибки следует приостановить работу проекта, ввести верный программный код, а затем снова запустить проект.

Некоторые наиболее часто встречающиеся ошибки:

1. Invalid outside procedure – неверная внешняя процедура;

2. Type mismatch – несоответствие типов;

3. Sub or Function not defined – процедура или функция не определена;

4. Next/For without For/Next – Next/For без For/Next: неправильная организация цикла;

5. If/EndIf without EndIf/If – If/EndIf без EndIf/If : неправильная запись условного оператора;

6. Select Case / (End Select) without End Select / (Select Case) —Select Case/(End Select) без End Select / (Select Case): неверная запись оператора выбора;

7. Object required – требуется объект;

8. Overflow – переполнение;

9. Subscript out of range– значение вне диапазона;

10. Duplicate declaration in current scope– двойное объявление в текущем диапазоне;

11. Division by zero – деление на ноль;

12. Statements and Labels invalid between Select Case and First Case –записи и метки неверны между Select Case и First Case;

13. Method or Data member not found – метод или часть данных не найдена;

14. Variable not defined – переменная не определена;

15. Invalid procedure call or argument – неправильный вызов процедуры или аргумент;

16. User-defined type not defined – пользовательский тип не определен;

17. Object doesn’t support this property or method – объект не поддерживает это свойство ли метод;

18. Ambiguous name detected: nameобъекта_событие – обнаружено неоднозначное имя;

19. Only comments may appear after End Sub, End Function, or End Property– только комментарии могут появляться после End Sub, End Function, или End Property;

20. Statement invalid outside Type Block– неверная запись вне блока.

Ошибки в программе в Visual Basic 6.0

При обнаружении ошибки в программном коде компилятор Visual Basic 6.0выдает стандартное окно сообщения, которое содержит информацию о коде (Run-time error ‘438’) и названии (Object doesn’t support this property or method) ошибки (рис.5). Ошибки, связанные с процедурами и объектами, выделяются желтым «маркером» (рис.6). Ошибки, связанные с методами или свойствами самих объектов, выделяются синим «маркером» (рис.7). Для исправления ошибки следует приостановить работу проекта, ввести верный программный код, а затем снова запустить проект.

Некоторые наиболее часто встречающиеся ошибки:

1. Invalid outside procedure – неверная внешняя процедура;

2. Type mismatch – несоответствие типов;

3. Sub or Function not defined – процедура или функция не определена;

4. Next/For without For/Next – Next/For без For/Next: неправильная организация цикла;

5. If/EndIf without EndIf/If – If/EndIf без EndIf/If : неправильная запись условного оператора;

6. Select Case / (End Select) without End Select / (Select Case) —Select Case/(End Select) без End Select / (Select Case): неверная запись оператора выбора;

7. Object required – требуется объект;

8. Overflow – переполнение;

9. Subscript out of range– значение вне диапазона;

10. Duplicate declaration in current scope– двойное объявление в текущем диапазоне;

11. Division by zero – деление на ноль;

12. Statements and Labels invalid between Select Case and First Case –записи и метки неверны между Select Case и First Case;

13. Method or Data member not found – метод или часть данных не найдена;

14. Variable not defined – переменная не определена;

15. Invalid procedure call or argument – неправильный вызов процедуры или аргумент;

16. User-defined type not defined – пользовательский тип не определен;

17. Object doesn’t support this property or method – объект не поддерживает это свойство ли метод;

18. Ambiguous name detected: nameобъекта_событие – обнаружено неоднозначное имя;

19. Only comments may appear after End Sub, End Function, or End Property– только комментарии могут появляться после End Sub, End Function, или End Property;

20. Statement invalid outside Type Block– неверная запись вне блока.

Vba 6 ошибка

Поискав по рунету материал на тему обработки ошибок в VBA, не увидал на первых двух страницах результатов поиска чего-то, что мне понравилось. Может плохо смотрел, но решил написать на эту тему свою статью.

Простите, но — немного словоблудия 🙂

Ошибки в программе

Ошибки времени исполнения программы возникают, когда среда программирования не может выполнить то, что вы хотите. Таких ситуаций может быть много. Например:

Вы обращаетесь к объекту по имени, а объекта с таким именем в коллекции нет

Вы хотите выделить ячеку на одном листе, а этот лист в данный момент не является активным (типичнейшая ошибка новичков в Excel VBA)

Вы хотите удалить отфильтрованные автофильтром строки, а фильтр вообще не вернул записей и удалять нечего

Вы ссылаетесь на элемент массива, который находится за пределами его границ.

Читать еще:  Ошибка 524 на сайте что означает

Вы пытаетесь присвоить переменной значение, которое оно не может хранить. Например, переменной типа Long нельзя присвоить строковую константу или переменной типа Integer присвоить знанчение превышающее число 32767 .

На любую из этих и сотни других ситуаций среда выполнения реагирует стандартно — прерывает ход выполнения программы на том операторе, где возникла ошибка или, как ещё принято говорить, исключение. На экран выводится информация о возникшей ошибке и предлагаются стандартные варианты для продолжения работы:

Continue (продолжить) — этот пункт во время возникновения ошибки всегда не активен. Он активен, когда по ходу выполнения программы вы использовали оператор Stop . Кстати это очень полезный оператор для отладки программы.

End (завершить) — завершение исполнения программы

Debug (отладка) — переход в режим отладки, в котором можно посмотреть, на каком операторе возникла ошибка, что содержат переменные, можно даже перетащить жёлтую полоску, подсвечивающую текущий оператор, назад, и модифицировать знанчение переменных через окно Immediate window (впрочем это экзотика). В общем случае кнопка Debug позволяет посмотреть, где случилась ошибка и попытаться понять почему так случилось.

Если вы — автор программы, в которой случилась ошибка, то вы, должно быть, в начале будете рады увидеть подобное окно, ибо только так вы сможете отловить основные ошибки, скрытые в вашем коде. Однако, если эту ошибку видит пользователь, то для него это, мягко говоря, безрадостное и малопонятное зрелище. Ещё хуже, если за эту программу вам заплатили деньги. Поэтому в среде худо-бедно профессиональных программистов принято предусматривать обработку ошибок в своих программах.

Почему вообще в коде возникают ошибки?

Много ошибок во время написания кода возникает по невнимательности или не совсем адекватного понимания того, что делаешь. Таких ошибок, как правило, очень много, особенно у начинающих программистов, но эти ошибки довольно легко отловить и исправить, так как, пока вы их не исправите, ничего не работает. Ну, например, вы должны извлечь данные из 5-го столбца, а вы извлекаете из 6-го, а их там банально нет. Ясно, что вы это очень быстро заметите.

Вторая группа ошибок — это ошибки оптимиста. Когда программа написана в целом правильно, но алгоритм не готов к ударам судьбы в виде неожиданных действий со стороны пользователя, ошибок ввода-вывода (вы рассчитывали считать данные из файла, а файла с таким именем не оказалось, либо он заблокирован другим приложением), особенностей конфигурации компьютера (разные версии ОС или офиса, которые в некоторых мелочах отличаются).

Тонкие логические ошибки. Чем сложнее программа, тем больше шансов, что модель задачи в вашей голове, ваша программа и реальность не совсем согласованы между собой. Пока вы не достигните достаточного погружения в задачу вы такие ошибки не найдёте и не исправите. Порой на это уходит много времени. Но это характерно для сложных задач.

Ошибки на стыке вашего приложения и сервисов ОС, приводящие к неожиданным крахам приложения. Такого вообще возникать не должно, но как мы понимаем, и ОС и офис содержат ошибки, да и вы (что более вероятно) можете пользоваться системными вызовами не правильно. Подобные ошибки — сущий кошмар, особенно когда они проявляются лишь на некоторых конфигурациях, при определенных условиях, их трудно поймать и надёжно воспроизвести.

Задачи механизмов обработки ошибок

Обеспечить стабильную работу программы . Возникновение ошибки, появление которой вы не предусмотрели, приведёт в большинстве случаев к аварийному завершению всей программы или её части. При определенном уровне подобных ситуаций это ведёт к тому, что программой пользоваться становится невозможно.

Информирование . Мало обработать ошибку и предотвратить завершение программы. Надо ещё и адекватно проинформировать пользователя о причинах нестандартного поведения программы. Частно причиной ошибок в программе являются некорректные действия пользователя, поэтому важно сообщать ему о них.

Защита данных от повреждения . Программа обязана защищать от непреднамеренных повреждений результаты своей или пользовательской работы. Деструктивные действия должны быть снабжены соответствующими предупредительными диалоговыми окнами. Часто ошибка, не обработанная должным образом может повредить нужные данные.

Файл примера

Скачать

Код без обработки ошибок

Вот простой пример с потолка. Если вызвать Example_00 , то она прекрасно отработает без ошибок и вернёт это:

В функцию GetCalories передаётся строка с блюдом, а она должна вернуть его калорийность, сверившись с таблицей в A1:B7 .

Давайте поищем слабые места в этом коде. Первое, что должно прийти в голову — если мы ищем, то, что произойдёт, если мы не найдём? А произойдёт, конечно же, ошибка. Её инициирует метод Match .

Ещё одно слабое место этой подпрограммы: функция возвращает вещественный тип Double , и даже, если поиск оказался удачным, то в Cells(intRow, 2) может случайно находиться текстовая строка, а потому, когда вы числовому типу попытаетесь присвоить строковый тип, также произойдёт ошибка. И, если вы второй ошибки сможете избежать за счёт дополнительного оператора if с проверкой через IsNumber (), то избежать первой ошибки таким способом нельзя. Что же делать? А вот тут на сцену выходят операторы обработки ошибок.

Есть 2 подхода к обработке ошибок: автономный подход и выносной . Эти термины я придумал только что, чтобы проще было их обсуждать.

Автономный подход

Смысл автономного подхода в том, чтобы не выносить сор из избы. Если в подпрограмме возникла ошибка, то мы должны предположить, на каком месте она возникнет и поджидать её там с дубиной. С ошибкой, в этом случае, разбираются обычно в операторе, идущем сразу после потенциально опасного места. Давайте смотреть, как это может выглядеть:

Читать еще:  Ошибка соединения 10061

Итак, что тут сделано:

Сразу после объявления функции GetCalories_v1 идёт оператор on error resume next , который в случае возникновения в каком-либо месте ошибки, предписывает VBA просто передавать управление на следующий оператор, идущий после ошибочного.

Мы объявили переменные. Необъявленные переменные получают тип Variant и значение по умолчанию Empty . Объявленные переменные числовых типов инициируются нулём, строковые — пустой строкой, то есть я наперёд знаю, что они содержат, а это хорошо для обработки ошибок.

На вызове метода WorksheetFunction.Match у нас возникает ошибка, так как искомого значения в таблице нет. А это, между прочим, был оператор присваивания ( = ). Прежде, чем левой части оператора присваивания ( intRow ) что-то будет присвоено, необходимо вычислить правую часть оператора присваивания ( WorksheetFunction.Match . ), а поскольку в процессе этого вычисления возникает ошибка, то переменная intRow остаётся такой, какой была! А, как я уже сказал, VBA автоматически её инициализирует нулём до начала исполнения подпрограммы. Получается, что, если в этом операторе возникнет ошибка, то в intRow будет ноль. Если ошибки во время поиска не возникнет, то ноля там не будет ни при каких раскладах, так как строки на листе нумеруются с единицы.

И вот этот ноль мы и контролируем, добавляя оператор If . Если intRow больше нуля, то WorksheetFunction.Match отработала штатно, а если нет — то работу подпрограммы надо прерывать, но об этом чуть позже.

Далее мы помним, что Cells(intRow, 2) может теоретически вернуть строковое значение, которое вызовет ошибку Type missmatch при присвоении переменной типа Double ( GetCalories_v1 ), поэтому мы вставляем дополнительную проверку промежуточной переменной varTemp тому, что она числовая. И если это так, то присваиваем GetCalories_v1 значение из varTemp .

В случае возникновения любой ошибки внутри GetCalories_v1 она просто вернёт ноль. Почему ноль? Потому что переменная GetCalories_v1 тоже инициализируется нулём и об этом не надо заботиться, а в случае ошибки она останется в неприкосновенности.

Соответственно родительский код (в нашем случае его роль играет процедура Example_01 ) должен проверить, а не вернёт ли GetCalories_v1 ноль, и быть готовым к этой ситуации.

А вот теперь тонкий момент, который не все понимают. Почему я использовал промежуточные переменные intRow и varTemp ? Вроде бы есть очевидный ответ — чтобы не вычислять значение выражений с Match и Cells 2 раза. Отчасти это, конечно, так. Но это, в данном случае, не главная причина. Главная причина в том, что такой код

вызовет неправильное поведение программы. Если у нас Match вызовет исключение, то VBA передаст управление на СЛЕДУЮЩИЙ оператор, а следующий оператор в данном случае это то, что идёт после Then — присваивание переменной varTemp значения. Таким образом наша проверка на наличие ошибки сработает с точностью до наоборот, передав управление в ту часть кода, которая должна быть защищена от ситуации, когда Match не нашла строку в таблице. Вот почему важно в операторе If не иметь ничего такого, что могло бы вызвать ошибку.

Как видите, в этом подходе мне зачастую даже нет необходимости проверять объект Err , чтобы понять, что произошла ошибка, так как я ориентируюсь на то, что промежуточные переменные остаются неинициализированными, что является показателем наличия ошибки.

Выносной подход

Данный метод основан на том, что, когда возникает ошибка, то VBA передаёт управление на специальный участок кода — обработчик ошибок, который обычно размещают в конце подпрограммы. Это может выглядеть так:

Обратите внимание, что:

Оператор on error теперь в случае ошибки предписывает передавать управление на метку ErrorHandler , которая объявлена в конце кода процедуры GetCalories_v2

В коде мы никак не заботимся о каких-либо проверках. Возникла ошибка? Иди на метку — там разберутся.

Если ошибки не случилось, то, чтобы программа не стала исполнять строчки, предназначенные для обработки ошибок, перед меткой ErrorHandler обычно ставят оператор Exit Sub или Exit Function (в зависимости от типа подпрограммы).

Принципиальный момент — наличие оператора On Error Resume Next сразу после метки ErrorHandler . Дело в том, что после того, как вы перешли на метку ErrorHandler , очень опасно иметь действующим оператор On Error GoTo ErrorHandler , так как, если у вас в обработчике ошибки случится любая ошибка, то управление будет передано опять на метку и, как нетрудно понять, образуется бесконечный цикл. Поэтому сразу после метки мы возможность возникновения цикла ликвидируем оператором On Error Resume Next .

Что лучше?

Какой метод лучше применять зависит от ваших предпочтений и конкретных ситуаций. Грамотную обработку ошибок можно сделать и так и эдак. Вот несколько соображений по преимуществам и недостакам данных подходов:

Типы ошибок в VBA

При выполнении макросов Excel могут возникнуть ошибки, которые в VBA делят на три категории:

Далее мы поговорим о каждом из трёх типов ошибок VBA подробно.

Ошибки компиляции

Компилятор VBA рассматривает ошибки компиляции как недопустимые и выделяет их в коде ещё до того, как дело дойдёт до запуска макроса.

Если при написании кода допущена синтаксическая ошибка, то редактор VBA сигнализирует об этом немедленно: либо при помощи окна с сообщением, либо выделяя ошибку красным цветом, в зависимости от статуса режима Auto Syntax Check.

Читать еще:  Инвалид клиент в контакте ошибка

Примечание: При включённом режиме Auto Syntax Check каждый раз, при появлении в редакторе Visual Basic во введённом коде синтаксической ошибки, будет показано соответствующее сообщение. Если же этот режим выключен, то редактор VBA продолжит сообщать о синтаксических ошибках, просто выделяя их красным цветом. Опцию Auto Syntax Check можно включить/выключить в меню Tools > Options редактора Visual Basic.

В некоторых случаях ошибка компиляции может быть обнаружена при выполнении компиляции кода, непосредственно перед тем, как макрос будет выполнен. Обычно ошибку компиляции несложно обнаружить и исправить, потому что компилятор VBA даёт информацию о характере и причине ошибки.

Например, сообщение “Compile error: Variable not defined” при попытке запустить выполнение кода VBA говорит о том, что происходит попытка использовать или обратиться к переменной, которая не была объявлена для текущей области (такая ошибка может возникнуть только если используется Option Explicit).

Ошибки выполнения

Ошибки выполнения возникают в процессе выполнения кода и приводят к остановке выполнения программы. Этот тип ошибок VBA, как правило, также не сложно обнаружить и исправить, так как сообщается информация о характере ошибки и место в коде, где произошла остановка.

Примером такой ошибки может служить попытка выполнить деление на ноль. В результате будет показано сообщение “Run-time error ’11’: Division by zero“.

В зависимости от структуры проекта VBA, может быть предложено выполнить отладку кода (как показано на рисунке ниже). В этом случае при нажатии на кнопку Debug (в окне сообщения о необходимости отладки) будет выделена цветом строка кода, которая стала причиной ошибки VBA.

Получив такое сообщение и видя выделенную строку кода, как в приведённом выше примере, обнаружить причину ошибки будет совсем не сложно.

В случае если код сложнее, чем в нашем примере, то, чтобы получить больше информации о причине возникновения ошибки VBA, можно проверить значения используемых переменных. В редакторе VBA для этого достаточно навести указатель мыши на имя переменной, или можно открыть окно отслеживания локальных переменных (в меню редактора View > Locals Window).

Коды различных ошибок выполнения расшифрованы на сайте Microsoft Support (на английском). Наиболее часто встречающиеся ошибки VBA перечислены в этой таблице:

Vba 6 ошибка

Ошибками пользуются в любой нормально написанной программе,
вне зависимости от объема ее кода.

Это помогает проанализировать, правильно ли работает программа.
И если нет, минимальными усилиями узнать причину проблемы.

Для этого в идеале, в каждой из функций следует использовать обработчик ошибок ( On Error Goto ).
А там, где используются API-функции, каждую из них проверять на предмет возвращаемого значения, а также кода ошибки API-функции ( Err.LastDllError ).
Это позволит минимизировать затраты на отладку программы
и еще на этапе проектирования исключить некоторые наиболее вероятные ошибки в вызове функций.

Внутреннюю ошибку VB можно также симмитировать вручную с помощью вызова процедуры Err.Raise [Номер ошибки]
Это спровоцирует переход к метке обработчика ошибок, указанной в директиве On Error Goto Имя_Метки
Это иногда полезно, если Вы хотите ввести в программу собственные ошибки (выход из функции при возникновении, на Ваш взгляд, критической ситуации).

Номер внутренней ошибки также можно очистить методом Err.Clear
Обработчик ошибок в любой момент можно отключить, вернув стандартное поведение программы, с помощью директивы On Error Goto 0
В этом случае, если произойдет ошибка, программа прекратит свое выполнение и выведет ошибку и краткое описание в стандартном диалоговом окне (msgbox)*
* Кроме случаев, когда обработчик ошибок установлен в родительской функции (вниз по стеку вызовов), т.е. функции, которая вызвала эту функцию. В этом случае будет вызван именно её обработчик, а программа продолжит свое выполнение.

При возникновении внутренней ошибки, ее номер и описание можно получить через свойства Number и Description объекта Err .
Стандартный обработчик ошибок VB имеет такой вид:

Function foo ()
On Error Goto ErrorHandler

if < что - то можем проверить >then
‘ здесь, если нам нужно, можем вызвать ошибку самостоятельно
err .Raise 51 ‘Internal error
end if

Exit function
ErrorHandler:
‘обработчик
‘выводим номер внутренней ошибки, краткое описание, номер ошибки API-функции
Debug .? «Error: » & Err .Number & «. » & Err .Description & «. LastDllErr: » & Err .LastDllError
End function

Описание ошибки API-функции (или COM-объекта) можем получить с помощью такой функции:

Private Declare Function FormatMessage Lib «kernel32.dll» Alias «FormatMessageA» ( ByVal dwFlags As Long , lpSource As Long , ByVal dwMessageId As Long , ByVal dwLanguageId As Long , ByVal lpBuffer As String , ByVal nSize As Long , Arguments As Any ) As Long

Const MAX_PATH As Long = 260 &

Public Function MessageText ( lCode As Long ) As String
On Error goto ErrorHandler
Const FORMAT_MESSAGE_FROM_SYSTEM As Long = & H1000 &
Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = & H200

Dim sRtrnCode As String
Dim lRet As Long

sRtrnCode = Space$ ( MAX_PATH )
lRet = FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0 & , lCode, ByVal 0 & , sRtrnCode, MAX_PATH, ByVal 0 &)
If lRet > 0 Then
MessageText = Left$ ( sRtrnCode, lRet )
MessageText = Replace$ ( MessageText, vbCrLf, vbNullString )
End If
Exit function
ErrorHandler:
Debug .? «Error: » & Err .Number & «. » & Err .Description & «. LastDllErr: » & Err .LastDllError
End Function

Ссылка на основную публикацию
Adblock
detector