Поискав по рунету материал на тему обработки ошибок в VBA, не увидал на первых двух страницах результатов поиска чего-то, что мне понравилось. Может плохо смотрел, но решил написать на эту тему свою статью. Простите, но — немного словоблудия 🙂 Ошибки в программеОшибки времени исполнения программы возникают, когда среда программирования не может выполнить то, что вы хотите. Таких ситуаций может быть много. Например:
На любую из этих и сотни других ситуаций среда выполнения реагирует стандартно — прерывает ход выполнения программы на том операторе, где возникла ошибка или, как ещё принято говорить, исключение. На экран выводится информация о возникшей ошибке и предлагаются стандартные варианты для продолжения работы:
Если вы — автор программы, в которой случилась ошибка, то вы, должно быть, в начале будете рады увидеть подобное окно, ибо только так вы сможете отловить основные ошибки, скрытые в вашем коде. Однако, если эту ошибку видит пользователь, то для него это, мягко говоря, безрадостное и малопонятное зрелище. Ещё хуже, если за эту программу вам заплатили деньги. Поэтому в среде худо-бедно профессиональных программистов принято предусматривать обработку ошибок в своих программах. Почему вообще в коде возникают ошибки?
Задачи механизмов обработки ошибок
Файл примераСкачатьКод без обработки ошибокВот простой пример с потолка. Если вызвать Example_00, то она прекрасно отработает без ошибок и вернёт это: В функцию GetCalories передаётся строка с блюдом, а она должна вернуть его калорийность, сверившись с таблицей в A1:B7. Давайте поищем слабые места в этом коде. Первое, что должно прийти в голову — если мы ищем, то, что произойдёт, если мы не найдём? А произойдёт, конечно же, ошибка. Её инициирует метод Match.Ещё одно слабое место этой подпрограммы: функция возвращает вещественный тип Double, и даже, если поиск оказался удачным, то в Cells(intRow, 2) может случайно находиться текстовая строка, а потому, когда вы числовому типу попытаетесь присвоить строковый тип, также произойдёт ошибка. И, если вы второй ошибки сможете избежать за счёт дополнительного оператора if с проверкой через IsNumber(), то избежать первой ошибки таким способом нельзя. Что же делать? А вот тут на сцену выходят операторы обработки ошибок. Есть 2 подхода к обработке ошибок: автономный подход и выносной. Эти термины я придумал только что, чтобы проще было их обсуждать. Автономный подходСмысл автономного подхода в том, чтобы не выносить сор из избы. Если в подпрограмме возникла ошибка, то мы должны предположить, на каком месте она возникнет и поджидать её там с дубиной. С ошибкой, в этом случае, разбираются обычно в операторе, идущем сразу после потенциально опасного места. Давайте смотреть, как это может выглядеть: Итак, что тут сделано:
Выносной подходОбратите внимание, что:
Что лучше?Какой метод лучше применять зависит от ваших предпочтений и конкретных ситуаций. Грамотную обработку ошибок можно сделать и так и эдак. Вот несколько соображений по преимуществам и недостакам данных подходов: Автономный подход
Выносной подход
Средства VBA для обработки ошибокКратко пробежимся по операторам, функциям и объектам VBA, которые предназначены для обработки ошибок времени исполнения программы. ОператорыOn Error { GoTo label | Resume Next | GoTo 0 }Оператор on error управляет тем, на какой участок вашего кода будет передано управление в случае возникновения ошибки. Данный оператор можно вставить в любое место вашей программы или подпрограммы. Есть 3 варианта:
Resume { label | Next | [0] }Данный оператор возобновляет выполнение программы. Применяется в выносном методе обработки ошибок.
Goto labelПереход на метку. Может пригодиться, однако, использование меток в коде для чего-то большего, чем обработка ошибок, считается страшным моветоном. Exit { Do | For | Function | Sub }Досрочный выход из циклов (Do или For) и досрочный выход из подпрограмм (функции или процедуры). Могут пригодиться при обработке ошибок, но вообще это операторы и без того чрезвычайно полезны. Объект Err
P.S.Лично я привык в своих программах использовать автономный подход и, возможно, поэтому я не совсем осознаю все преимущества выносного подхода. Буду рад прочесть в комментариях ваше мнение на этот счёт. Тема обработки ошибок данной статьёй, конечно, быть исчерпана не может, но она послужит вам хорошей стартовой точкой в этом важном деле. Читайте также: |
VBA Excel. Метод Application.InputBox (синтаксис, параметры)
Использование метода Application.InputBox в VBA Excel, его синтаксис и параметры. Значения, возвращаемые диалогом Application.InputBox. Примеры использования.
Метод Application.InputBox предназначен в VBA Excel для вывода диалогового окна с более расширенными возможностями, чем диалоговое окно, отображаемое функцией InputBox. Главным преимуществом метода Application.InputBox является возможность автоматической записи в поле ввода диапазона ячеек (в том числе одной ячейки) путем его выделения на рабочем листе книги Excel и возвращения различных данных, связанных с ним, а также проверка соответствия возвращаемого значения заданному типу данных.
Синтаксис метода
Application. InputBox ( Prompt , Title , Default , Left , Top , HelpFile , HelpContextID , Type )
Обязательным параметром метода Application.InputBox является Prompt, если значения остальных параметров явно не указаны, используются их значения по умолчанию.
Обратите внимание на то, что
- оператор InputBox вызывает функцию InputBox, а
- оператор Application.InputBox вызывает метод InputBox.
Чтобы не было путаницы, метод InputBox пишут как метод Application.InputBox, в том числе и в справке разработчика.
Параметры метода
Параметр | Описание | Значение по умолчанию |
Prompt | Обязательный параметр. Выражение типа String, отображаемое в диалоговом окне в виде сообщения, приглашающего ввести данные в поле. Разделить на строки сообщение можно с помощью константы vbNewLine. | Нет |
Title | Необязательный параметр. Выражение типа Variant, отображаемое в заголовке диалогового окна. | Слово «Ввод» |
Default | Необязательный параметр. Выражение типа Variant, отображаемое в поле ввода при открытии диалога. | Пустая строка |
Left | Необязательный параметр. Выражение типа Variant, определяющее в пунктах расстояние от левого края экрана до левого края диалогового окна (координата X).* | Горизонтальное выравнивание по центру** |
Top | Необязательный параметр. Выражение типа Variant, определяющее в пунктах расстояние от верхнего края экрана до верхнего края диалогового окна (координата Y).* | Приблизительно равно 1/3 высоты экрана*** |
HelpFile | Необязательный параметр. Выражение типа Variant, указывающее имя файла справки для этого поля ввода. | Нет**** |
HelpContextID | Необязательный параметр. Выражение типа Variant, указывающее идентификатор контекста в справочном разделе файла справки. | Нет**** |
Type | Необязательный параметр. Выражение типа Variant, указывающее тип возвращаемых данных. | 2 (текст) |
* Параметры Left и Top учитываются при отображении диалогового окна методом Application.InputBox в Excel 2003, а в последующих версиях Excel 2007-2016 уже не работают.
**При первом запуске горизонтальное выравнивание устанавливается по центру, при последующих – форма отобразиться в том месте, где ее последний раз закрыли.
***При первом запуске вертикальное расположение приблизительно равно 1/3 высоты экрана, при последующих – форма отобразиться в том месте, где ее последний раз закрыли.
**** Если будут указаны параметры HelpFile и HelpContextID, в диалоговом окне появится кнопка справки.
Возвращаемые значения
Диалоговое окно, созданное методом Application. InputBox, возвращает значение типа Variant и проверяет соответствие возвращаемого значения типу данных, заданному параметром Type. Напомню, что тип значений Variant является универсальным контейнером для значений других типов, а в нашем случае для возвращаемых в зависимости от значения параметра Type.
Аргументы параметра Type и соответствующие им типы возвращаемых значений:
Type | Возвращаемое значение |
0 | Формула |
1 | Число |
2 | Текст (string) |
4 | Логическое значение (True или False) |
8 | Ссылки на ячейки в виде объекта Range |
16 | Значение ошибки (например, #н/д) |
64 | Массив значений |
Примеры
В отличие от других встроенных диалоговых окон VBA Excel, Application. InputBox при запуске процедуры непосредственно из редактора, открывается прямо в редакторе, и, чтобы выбрать диапазон ячеек на рабочем листе, нужно по вкладке браузера перейти в книгу Excel. Поэтому для тестирования диалога Application.InputBox удобнее создать кнопку, перетащив ее на вкладке «Разработчик» из «Элементов управления формы» (не из «Элементов ActiveX») и в окошке «Назначить макрос объекту» выбрать имя тестируемой процедуры. Чтобы можно было выбрать процедуру сразу при создании кнопки, она должна быть уже вставлена в стандартный программный модуль. Можно назначить процедуру кнопке позже, кликнув по ней правой кнопкой мыши и выбрав в контекстном меню «Назначить макрос…».
Пример 1 – параметры по умолчанию
Тестируем метод Application.InputBox с необязательными параметрами по умолчанию. Аргумент параметра Type по умолчанию равен 2.
Sub Test1() Dim a As Variant a = Application. InputBox(«Выберите ячейку:») MsgBox a End Sub |
Скопируйте код и вставьте в стандартный модуль, для удобства создайте на рабочем листе кнопку из панели «Элементы управления формы» и назначьте ей макрос «Test1». На рабочем листе заполните некоторые ячейки разными данными, нажимайте кнопку, выбирайте ячейки и смотрите возвращаемые значения.
Клик по кнопке «OK» диалога Application.InputBox в этом примере возвращает содержимое выбранной ячейки (или левой верхней ячейки выбранного диапазона), преобразованное в текстовый формат. У дат в текстовый формат преобразуется их числовое представление.
Клик по кнопке «Отмена» или по закрывающему крестику возвращает строку «False».
Пример 2 – возвращение объекта Range
В этом примере тестируем метод Application.InputBox с обязательным параметром Prompt, разделенным на две строки, параметром Title и значением параметра Type равным 8. Так как в данном случае диалог в качестве значения возвращает объект Range, он присваивается переменной с помощью оператора Set. Для этого примера создайте новую кнопку из панели «Элементы управления формы» и назначьте ей макрос «Test2».
Sub Test2() Dim a As Variant Set a = Application.InputBox(«Пожалуйста,» _ & vbNewLine & «выберите диапазон:», _ «Наш диалог», , , , , , 8) MsgBox a.Cells(1) MsgBox a.Address End Sub |
В первом информационном окне MsgBox выводится значение первой ячейки выбранного диапазона, во втором – адрес диапазона.
Напомню, что обращаться к ячейке в переменной диапазона «a» можно не только по порядковому номеру (индексу) самой ячейки, но и по индексу строки и столбца, на пересечении которых она находится. Например, оба выражения
указывают на первую ячейку диапазона. А в объектной переменной «a» с присвоенным диапазоном размерностью 3х3 оба выражения
указывают на центральную ячейку диапазона.
При использовании метода Application.InputBox происходит проверка введенных данных: попробуйте понажимать кнопку «OK» с пустым полем ввода и с любым введенным текстом (кроме абсолютного адреса). Реакция в этих случаях разная, но понятная.
Есть и отрицательные моменты: при использовании в диалоге Application.InputBox параметра Type со значением равным 8, нажатие кнопок «Отмена» и закрывающего крестика вызывают ошибку Type mismatch (Несоответствие типов). Попробуйте нажать кнопку «Отмена» или закрыть форму диалога.
Решить эту проблему можно, добавив обработчик ошибок. Скопируйте в стандартный модуль код следующей процедуры, создайте еще одну кнопку и назначьте ей макрос «Test3».
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Sub Test3() Dim a As Variant ‘При возникновении ошибки ‘перейти к метке «Inform» On Error GoTo Inform Set a = Application. InputBox(«Пожалуйста,» _ & vbNewLine & «Выберите диапазон:», _ «Наш диалог», , , , , , 8) MsgBox a.Cells(1) MsgBox a.Address ‘Выйти из процедуры, ‘если не произошла ошибка Exit Sub ‘Метка Inform: ‘Вывести информационное окно с ‘сообщением об ошибке MsgBox «Диалог закрыт или нажата кнопка » _ & Chr(34) & «Отмена» & Chr(34) & «!» End Sub |
Попробуйте теперь нажать кнопку «Отмена» или закрыть форму диалога крестиком.
Пример 3 – возвращение массива
Скопируйте в стандартный модуль код процедуры ниже, создайте четвертую кнопку и назначьте ей макрос «Test4». В этой процедуре указан только аргумент параметра Type равным 64, остальные необязательные параметры оставлены по умолчанию.
Sub Test4() Dim a As Variant a = Application. InputBox(«Выберите диапазон:», , , , , , , 64) MsgBox a(3, 3) End Sub |
Откройте диалоговую форму, нажав четвертую кнопку, и выберите диапазон размерностью не менее 3х3. Нажмите «OK»: информационное сообщение выведет значение соответствующего элемента массива «a», в нашем случае – «a(3, 3)». Если вы выберите диапазон по одному из измерений меньше 3, тогда строка «MsgBox a(3, 3)» вызовет ошибку, так как указанный элемент выходит за границы массива. Эта же строка по этой же причине вызовет ошибку при нажатии кнопки «Отмена» и при закрытии диалога крестиком. Если закомментировать строку «MsgBox a(3, 3)», то закрываться диалог будет без ошибок и при нажатии кнопки «Отмена», и при закрытии диалога крестиком.
Чтобы не попасть за границу массива используйте функцию UBound для определения наибольшего доступного индекса по каждому из двух измерений, например, вот так:
Sub Test5() Dim a As Variant a = Application. InputBox(«Выберите диапазон:», , , , , , , 64) MsgBox «Максимальный индекс 1 измерения = » & UBound(a, 1) & _ vbNewLine & «Максимальный индекс 2 измерения = » & UBound(a, 2) End Sub |
только присваивайте значения выражений «UBound(a, 1)» и «UBound(a, 2)» числовым переменным. А этот код используйте для ознакомления с работой функции UBound и ее тестирования.
В этой процедуре ошибка выдается при выборе одной ячейки или диапазона в одной строке, очевидно, Excel воспринимает его как одномерный массив. Хотя при выборе диапазона в одном столбце, по крайней мере в Excel 2016, все проходит гладко и вторая строка информационного сообщения отображается как «Максимальный индекс 2 измерения = 1».
Ошибка выдается и при нажатии кнопки «Отмена», и при закрытии диалога крестиком, так как переменная «а» в этом случае еще не является массивом, а мы пытаемся использовать ее как аргумент для функции массива, что и вызывает ошибку.
Пример 4 – возвращение формулы
Возвращение формулы рассмотрим на следующем примере:
Sub Test6() Dim a As Variant a = Application.InputBox(«Создайте формулу:», , , , , , , 0) Cells(1, 1) = a End Sub |
На активном листе Excel заполните некоторые ячейки числами и запустите процедуру на выполнение. После отображения диалога Application.InputBox выбирайте по одной ячейке с числами, вставляя между ними математические операторы. После нажатия на кнопку «OK» формула запишется в первую ячейку активного рабочего листа «Cells(1, 1)» (в текст формулы ее не выбирайте, чтобы не возникла циклическая ссылка). При нажатии на кнопку «Отмена» и при закрытии диалога крестиком в эту ячейку запишется слово «Ложь».
Можно записывать не только математические формулы, но и объединять содержимое ячеек с помощью оператора «&» и многое другое. Только не понятно, для чего это вообще нужно, как, впрочем, и возврат логических, числовых значений и значений ошибки. Вы можете протестировать их возврат с помощью процедуры «Test6», заменив в ней параметр Type метода Application.InputBox соответствующим для возвращения логических, числовых значений и значений ошибки.
Обработка исключений в Visual Basic.NET
Обработка исключений
Последнее обновление: 30.10.2015
В процессе выполнения программы нередко возникают такие ситуации, которые трудно или даже невозможно предусмотреть во время создания программы. Например, при передаче файла по сети может неожиданно оборваться сетевое подключение. Такие ситуации называются исключениями. Чтобы программа неожиданно не зависла в таких ситуациях, программисту нужно вводить в нее обработку исключений. Для обработки исключений в языке VB.NET имеется конструкция Try…Catch..Finally. Ее использование выглядит следующим образом:
Sub Main() Dim a(3) As Integer Try a(5) = 3 Catch ex As Exception Console. WriteLine(ex.Message) Finally Console.WriteLine("Finally block") End Try Console.ReadLine() End Sub
В данном случае у нас как раз и возникает исключение, так как в массиве a только 4 элемента, а мы пытаемся присвоить значение шестому элементу.
При использовании блока Try…Catch..Finally сначала выполняются все инструкции между операторами Try и
Catch.
И если вдруг в каком-то месте кода возникает исключение, то обычный порядок выполнения кода останавливается и программа переходит к выражению Catch.
Это выражение имеет следующий синтаксис: Catch имя_переменной As тип_исключения
. В данном случае у нас объявляется переменная ex, которая
имеет тип Exception. При чем если возникшее исключение не является исключением типа, указанного в выражении Catch, то оно не обрабатывается,
а программа просто зависает или выбрасывает сообщение об ошибке. Так как тип Exception
является базовым типом для всех исключений, то в
выражении Catch ex As Exception
абсолютно все исключения.
В нашем случае мы просто выводим сообщение об исключении на экран с помощью свойства Message
, определенное в классе Exception
.
Далее в любом случае выполняется блок после оператора Finally
. Но этот блок необязательный, и его можно при обработке исключений опускать.
В случае, если в ходе программы исключений не возникнет, то программа не будет выполнять блок Catch, сразу перейдет к блоку Finally, если он имеется.
Разработка собственных исключений
Мы можем создать свои собственные классы исключений, которые будут обрабатывать нежелательные ситуации. Для примера возьмем класс
Algorithm
, который мы сделали в одной из глав предыдущей части:
Public Class Algorithm Public Shared Function Factorial(x As Integer) As Integer If (x = 1) Then Return 1 Else Return x * Factorial(x - 1) End If End Function Public Shared Function Fibbonachi(x As Integer) As Integer If x = 0 Then Return 1 ElseIf x = 1 Then Return 1 Else Return Fibbonachi(x - 1) + Fibbonachi(x - 2) End If End Function End Class
Факториал и последовательность Фиббоначи определены только для положительных чисел, поэтому если мы передадим в функцию отрицательное число,
возникнет исключительная ситуация. Чтобы ее обработать и создадим класс NegativeNumberException
:
Public Class NegativeNumberException Inherits Exception Sub New() MyBase.New("В качестве параметра передано отрицательное число") End Sub End Class
В этом классе по сути мы только передаем сообщение в конструктор базового класса. Теперь вызовем обработку исключения в методе Factorial с помощью ключевого слова Throw:
Public Shared Function Factorial(x As Integer) As Integer If x < 0 Then Throw New NegativeNumberException() If (x = 1) Then Return 1 Else Return x * Factorial(x - 1) End If End Function
И теперь, если мы передадим в этот метод отрицательные значения, в блоке Try...Catch
будет обрабатываться исключение NegativeNumberException
:
Try Console.WriteLine(Algorithm.Factorial(-1)) Catch ex As Exception Console. WriteLine(ex.Message) End Try
VB.Net — Обработка исключений — CoderLessons.com
Исключением является проблема, возникающая при выполнении программы. Исключением является ответ на исключительное обстоятельство, которое возникает во время работы программы, например, попытка деления на ноль.
Исключения предоставляют способ передачи управления из одной части программы в другую. Обработка исключений в VB.Net основана на четырех ключевых словах — Try , Catch , Наконец и Throw .
Try — блок Try определяет блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков Catch.
Поймать — программа ловит исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему. Ключевое слово Catch указывает на перехват исключения.
Наконец, — блок «Последний» используется для выполнения заданного набора операторов независимо от того, было ли выброшено исключение или нет. Например, если вы открываете файл, он должен быть закрыт независимо от того, возбуждено ли исключение или нет.
Бросок — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова Throw.
Try — блок Try определяет блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков Catch.
Поймать — программа ловит исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему. Ключевое слово Catch указывает на перехват исключения.
Наконец, — блок «Последний» используется для выполнения заданного набора операторов независимо от того, было ли выброшено исключение или нет. Например, если вы открываете файл, он должен быть закрыт независимо от того, возбуждено ли исключение или нет.
Бросок — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова Throw.
Синтаксис
Предполагая, что блок вызовет исключение, метод перехватывает исключение, используя комбинацию ключевых слов Try и Catch. Блок Try / Catch размещается вокруг кода, который может генерировать исключение. Код в блоке Try / Catch называется защищенным кодом, и синтаксис использования Try / Catch выглядит следующим образом:
Try [ tryStatements ] [ Exit Try ] [ Catch [ exception [ As type ] ] [ When expression ] [ catchStatements ] [ Exit Try ] ] [ Catch ... ] [ Finally [ finallyStatements ] ] End Try
Вы можете перечислить несколько операторов catch для перехвата различных типов исключений в случае, если ваш блок try вызывает более одного исключения в разных ситуациях.
Классы исключений в .Net Framework
В .Net Framework исключения представлены классами. Классы исключений в .Net Framework в основном прямо или косвенно являются производными от класса System.Exception . Некоторыми из классов исключений, полученных из класса System. Exception, являются классы System.ApplicationException и System.SystemException .
Класс System.ApplicationException поддерживает исключения, генерируемые прикладными программами. Таким образом, исключения, определенные программистами, должны быть производными от этого класса.
Класс System.SystemException является базовым классом для всех предопределенных системных исключений.
В следующей таблице представлены некоторые предопределенные классы исключений, полученные из класса Sytem.SystemException.
Исключительный класс | Описание |
---|---|
System.IO.IOException | Обрабатывает ошибки ввода / вывода. |
System.IndexOutOfRangeException | Обрабатывает ошибки, сгенерированные, когда метод ссылается на индекс массива вне диапазона. |
System.ArrayTypeMismatchException | Обрабатывает ошибки, возникающие, когда тип не соответствует типу массива. |
System.NullReferenceException | Обрабатывает ошибки, сгенерированные в результате определения нулевого объекта. |
System.DivideByZeroException | Обрабатывает ошибки, возникающие при делении дивиденда на ноль. |
System.InvalidCastException | Обрабатывает ошибки, сгенерированные во время приведения типов. |
System.OutOfMemoryException | Обрабатывает ошибки, возникающие из-за недостатка свободной памяти. |
System.StackOverflowException | Обрабатывает ошибки, вызванные переполнением стека. |
Обработка исключений
VB.Net предоставляет структурированное решение проблем обработки исключений в виде блоков try и catch. Используя эти блоки, основные программные операторы отделены от операторов обработки ошибок.
Эти блоки обработки ошибок реализованы с использованием ключевых слов Try , Catch и finally. Ниже приведен пример создания исключения при делении на ноль:
Live Demo
Module exceptionProg Sub division(ByVal num1 As Integer, ByVal num2 As Integer) Dim result As Integer Try result = num1 \ num2 Catch e As DivideByZeroException Console.WriteLine("Exception caught: {0}", e) Finally Console.WriteLine("Result: {0}", result) End Try End Sub Sub Main() division(25, 0) Console.ReadKey() End Sub End Module
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —
Exception caught: System.DivideByZeroException: Attempted to divide by zero. at ... Result: 0
Создание пользовательских исключений
Вы также можете определить свое собственное исключение. Определяемые пользователем классы исключений являются производными от класса ApplicationException . Следующий пример демонстрирует это —
Live Demo
Module exceptionProg Public Class TempIsZeroException : Inherits ApplicationException Public Sub New(ByVal message As String) MyBase. New(message) End Sub End Class Public Class Temperature Dim temperature As Integer = 0 Sub showTemp() If (temperature = 0) Then Throw (New TempIsZeroException("Zero Temperature found")) Else Console.WriteLine("Temperature: {0}", temperature) End If End Sub End Class Sub Main() Dim temp As Temperature = New Temperature() Try temp.showTemp() Catch e As TempIsZeroException Console.WriteLine("TempIsZeroException: {0}", e.Message) End Try Console.ReadKey() End Sub End Module
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —
TempIsZeroException: Zero Temperature found
Бросать предметы
Вы можете выбросить объект, если он прямо или косвенно является производным от класса System.Exception.
Вы можете использовать оператор throw в блоке catch, чтобы выбросить текущий объект как —
Throw [ expression ]
Следующая программа демонстрирует это —
Module exceptionProg Sub Main() Try Throw New ApplicationException("A custom exception _ is being thrown here. ..") Catch e As Exception Console.WriteLine(e.Message) Finally Console.WriteLine("Now inside the Finally Block") End Try Console.ReadKey() End Sub End Module
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —
Ускоряем работу VBA в Excel / Хабр
Предисловие
Так уж сложилось, что на сегодняшний день много кому приходится работать(писать макросы) на VBA в Excel. Некоторые макросы содержат сотни строк кода, которые приходится выполнять каждый день (неделю, месяц, квартал и так далее) и, при этом, они занимают изрядное количество времени. Вроде бы и и процесс автоматизирован и человеческого вмешательства не нужно, но время, занимаемое выполнением макроса, может охватывать десятки минут, а то и несколько часов. Время, как говориться, — деньги и в этом посте я постараюсь значительно ускорить время выполнения Вашего макроса и, возможно, это положительно скажется на ваших делах, а в итоге и деньгах.
Перед началом работы
Перед тем, как перейти прямо к сути, я хотел бы обратить внимание на пост: Несколько советов по работе с VBA в Excel. В частности, в блоке “Ускорение работы макросов” есть полезные примеры кода, которые стоит использовать вместе с моими советами по ускорению работы, для достижения максимального результата.
Ускоряем работу макроса
Итак, к сути… Для того что бы реально ускорить работу VBA в Ecxel нужно понимать, что обращение к ячейке на листе — занимает значительно время. Если Вы хотите записать в ячейку одно значение, то это не займет значительного времени, но если Вам потребуется записать(прочитать, обратиться) к тысячам ячеек, то это потребует гораздо большего времени. Что же делать в таких случаях? На помощь приходят массивы. Массивы хранятся в памяти, а операции в памяти VBA выполняет в сотни, а то и в тысячи раз быстрее. Поэтому, если у Вас в данных тысячи, сотни тысяч значений, то время выполнения макроса может занимать от нескольких минут до нескольких часов, а если эти данные перенести в массив, то выполнение макроса может сократиться до нескольких секунд (минут).
Я наведу пример кода и в комментариях объясню что к чему, так будет яснее. К тому же, могут пригодиться некоторые строки кода, не относящееся прямо к процессу ускорения.
Пример
Предположим, что у нас есть данные на “Лист1” (“Sheet1”). Данные содержаться в 50 колонках (колонки содержат названия) и 10 000 строк. К примеру, нам нужно в последнюю колонку внести значение, которое равно значению во второй колонке, деленное на значение в третьей колонке (начиная со 2-й строки, так как первая содержит заглавие). Потом мы возьмем первые 10 колонок и скопируем их на “Лист2” (“Sheet2”), для дальнейшей обработки (для других потребностей). Пусть пример и банальный, но, как мне кажется, он может отобразить всю суть данного поста.
'Для явной инициализации переменных, включаем эту опцию
'Это поможет избежать многих ошибок
Option Explicit
Sub Test()
'К листам будем обращаться через переменные
Dim Sheet1_WS, Sheet2_WS As Worksheet
'Переменная для прохождения срок на листе (в массиве)
Dim i As Long
'Массив, в котором будут храниться наши данные
Dim R_data As Variant
'Переменные последней строки и колонки
Dim FinalRow, FinalColumn As Long
'Можно инициализировать лист не по названию, а по порядковому номеру
'Set Sheet1_WS = Application. ThisWorkbook.Worksheet("Sheet1")
Set Sheet1_WS = Application.ThisWorkbook.Sheets(1)
Set Sheet2_WS = Application.ThisWorkbook.Sheets(2)
'Поиск последней не пустой строки в первой колонке
'Нужно, что бы данные не были отфильтрованы, иначе последняя строка будет последней строкой в фильтре
'Также в последней строке, в первой колонке, не должно быть пустой ячейки. Конечно, если в этой строке вообще есть данные. Иначе последней строкой будет последняя не пустая ячейка.
FinalRow = Sheet1_WS.Cells(Rows.Count, 1).End(xlUp).Row '=10 000
'Поиск последней не пустой колонки в первой строке
FinalColumn = Sheet1_WS.Cells(1, Columns.Count).End(xlToLeft).Column '=50
'Присваиваем массиву диапазон данных на Листе 1
R_data = Sheet1_WS.Range(Sheet1_WS.Cells(1, 1), Sheet1_WS.Cells(FinalRow, FinalColumn))
For i = 2 To FinalRow
'Выполняем нужные нам операции с данными.
'Проверяем, что бы не было деления на ноль.
'Предполагается, что в колонке 2 и 3 стоят числовые данные
'Иначе потребуется обработка ошибок
If R_data(i, 3) <> 0 Then
R_data(i, FinalColumn) = R_data(i, 2) / R_data(i, 3)
End If
Next i
'Копируем данные из массива обратно на Лист1
'Перед этим очищаем данные на листе (если есть форматирование или формулы, то лучше Sheet1_WS. Cells.ClearContents)
Sheet1_WS.Cells.Delete
Sheet1_WS.Range(Sheet1_WS.Cells(1, 1), Sheet1_WS.Cells(FinalRow, FinalColumn)) = R_data
'Копируем данные на Лист2, копируем первые 10 колонок.
Sheet2_WS.Range(Sheet2_WS.Cells(1, 1), Sheet2_WS.Cells(FinalRow, 10)) = R_data
'Закрываем книгу и сохраняем её
Workbooks(Application.ThisWorkbook.Name).Close SaveChanges:=True
End Sub
В данном примере массив заполняется указанным диапазоном. Если у нас будет явно заданный двумерный массив, то скопировать его значение на лист можно таким образом:
Dim R_new() As Variant
............................................
' Явно указываем размер массива
ReDim R_new(1 To FinalRow, 1 To 50) As Variant
...........................................
Sheet1_WS.Range(Sheet1_WS.Cells(1, 1), Sheet1_WS.Cells(FinalRow, 50)) = R_new()
Заключение
Большинство операций над данными можно выполнять в массиве, при этом, отображать на лист только результат. Иногда целесообразным бывает показать результат на лист, потом выполнить некоторые действия (например, сортировку) и снова загрузить данные в массив.
Для меня было большой неожиданностью ускорения работы макроса за счет массивов, так как данные на листах, на самом деле, итак представляют собой двумерный массив. Но, оказывается, обращение к памяти происходит гораздо быстрей, чем к ячейкам на листе.
В дальнейшем я планирую написать советы (примеры) по быстрому поиску данных на листе, но это уже будет другой пост. Если будут вопросы, комментарии, пожалуйста, пишите.
Спасибо за внимание. Удачных разработок.
Как ускорить и оптимизировать код VBA
Хитрости » 20 Январь 2016 Дмитрий 43454 просмотров
Рано или поздно у пишущих на Visual Basic for Applications возникает проблема — код хоть и облегчает жизнь и делает все автоматически, но очень долго. В этой статье я решил собрать несколько простых рекомендаций, которые помогут ускорить работу кода VBA, при этом в некоторых случаях весьма внушительно — в десятки, а то и больше, раз. Основной упор в статье сделан на начинающих, поэтому в начале статьи приводятся самые простые методы оптимизации. Более «глубокие» решения по оптимизации кода приведены в конце статьи, т.к. для применения данных решений необходим достаточный опыт работы в VB и сходу такие методы оптимизации кому-то могут быть непонятны.
- Если в коде есть много всяких Activate и Select, тем более в циклах — следует немедленно от них избавиться. Как это сделать я писал в статье: Select и Activate — зачем нужны и нужны ли?
- Обязательно на время выполнения кода отключить:
- автоматический пересчет формул. Чтобы формулы не пересчитывались при каждой манипуляции на листе во время выполнения кода — это может дико тормозить код, если формул много:
Application.Calculation = xlCalculationManual
Application.Calculation = xlCalculationManual
- обновление экрана, чтобы действия по изменению значений ячеек и пр. не мелькали. Зачем это надо? Т. к. все эти действия обращаются к графическому процессору и заставляют его трудиться для перерисовки экрана — это может значительно тормозить код:
Application.ScreenUpdating = False
Application.ScreenUpdating = False
- На всякий случай отключаем отслеживание событий. Нужно для того, чтобы Excel не выполнял никаких событийных процедур, которые могут быть в листе, в котором производятся изменения. Как правило это события изменения ячеек, активации листов и пр.:
- автоматический пересчет формул. Чтобы формулы не пересчитывались при каждой манипуляции на листе во время выполнения кода — это может дико тормозить код, если формул много:
Элементы обработки ошибок времени выполнения
- Читать 12 минут
В этой статье
Ошибки и обработка ошибок
При программировании приложения необходимо учитывать, что происходит при возникновении ошибки. Ошибка может возникнуть в вашем приложении по одной из двух причин. Во-первых, какое-то условие во время работы приложения приводит к сбою действительного кода.Например, если ваш код пытается открыть таблицу, которую удалил пользователь, возникает ошибка. Во-вторых, ваш код может содержать неправильную логику, которая не позволяет ему делать то, что вы планировали. Например, ошибка возникает, если ваш код пытается разделить значение на ноль.
Если вы не реализовали обработку ошибок, Visual Basic останавливает выполнение и отображает сообщение об ошибке при возникновении ошибки в вашем коде. Пользователь вашего приложения, скорее всего, будет сбит с толку и расстроится, когда это произойдет.Вы можете предотвратить многие проблемы, включив в свой код процедуры тщательной обработки ошибок для обработки любой ошибки, которая может возникнуть.
При добавлении обработки ошибок в процедуру вы должны учитывать, как процедура будет направлять выполнение при возникновении ошибки. Первым шагом в маршрутизации выполнения обработчику ошибок является включение обработчика ошибок путем включения в процедуру некоторой формы оператора On Error . Оператор On Error направляет выполнение в случае ошибки.Если нет оператора On Error , Visual Basic просто останавливает выполнение и отображает сообщение об ошибке при возникновении ошибки.
Когда ошибка возникает в процедуре с включенным обработчиком ошибок, Visual Basic не отображает обычное сообщение об ошибке. Вместо этого он направляет выполнение обработчику ошибок, если он существует. Когда выполнение переходит к включенному обработчику ошибок, этот обработчик ошибок становится активным. В активном обработчике ошибок вы можете определить тип возникшей ошибки и устранить ее выбранным вами способом.Access предоставляет три объекта, которые содержат информацию о произошедших ошибках: объект ошибки ADO , объект ошибки Visual Basic и объект ошибки DAO .
Выполнение маршрутизации при возникновении ошибки
Обработчик ошибок определяет, что происходит в процедуре при возникновении ошибки. Например, вы можете захотеть, чтобы процедура завершилась при возникновении определенной ошибки, или вы можете захотеть исправить условие, вызвавшее ошибку, и возобновить выполнение.Операторы On Error и Resume определяют, как выполняется выполнение в случае ошибки.
Сообщение об ошибке
Оператор On Error включает или отключает процедуру обработки ошибок. Если подпрограмма обработки ошибок включена, выполнение переходит к подпрограмме обработки ошибок при возникновении ошибки.
Существует три формы оператора On Error : On Error GoTo label , On Error GoTo 0 и On Error Resume Next .Оператор On Error GoTo label включает процедуру обработки ошибок, начиная со строки, в которой находится оператор. Вы должны включить процедуру обработки ошибок перед первой строкой, в которой может произойти ошибка. Когда обработчик ошибок активен и возникает ошибка, выполнение переходит к строке, указанной в аргументе label .
Строка, указанная в аргументе label , должна быть началом процедуры обработки ошибок.Например, следующая процедура указывает, что при возникновении ошибки выполнение переходит к строке с меткой:
Функция MayCauseAnError ()
'Включить обработчик ошибок.
При ошибке Перейти к Error_MayCauseAnError
. 'Включите сюда код, который может вызвать ошибку.
.
.
Error_MayCauseAnError:
. 'Включите сюда код для обработки ошибки.
.
.
Конечная функция
Оператор On Error GoTo 0 отключает обработку ошибок внутри процедуры.Он не указывает строку 0 как начало кода обработки ошибок, даже если процедура содержит строку с номером 0. Если в вашем коде нет оператора On Error GoTo 0 , обработчик ошибок автоматически отключается, когда процедура отработал полностью. Оператор On Error GoTo 0 сбрасывает свойства объекта Err , имея тот же эффект, что и метод Clear объекта Err .
Оператор On Error Resume Resume Next игнорирует строку, вызывающую ошибку, и направляет выполнение на строку, следующую за строкой, вызвавшей ошибку.Исполнение не прерывается. Вы можете использовать оператор On Error Resume Next , если хотите проверить свойства объекта Err сразу после строки, в которой, как вы ожидаете, произойдет ошибка, и обработать ошибку внутри процедуры, а не в обработчике ошибок. .
Резюме
Оператор Resume направляет выполнение обратно в тело процедуры из подпрограммы обработки ошибок. Вы можете включить оператор Resume в подпрограмму обработки ошибок, если хотите, чтобы выполнение продолжалось в определенной точке процедуры.Однако в заявлении Resume нет необходимости; вы также можете завершить процедуру после процедуры обработки ошибок.
Существует три формы заявления Resume . Оператор Resume или Resume 0 возвращает выполнение к строке, в которой произошла ошибка. Оператор Resume Next возвращает выполнение в строку, следующую сразу за строкой, в которой произошла ошибка. Оператор Resume label возвращает выполнение в строку, указанную аргументом label .Аргумент label должен указывать либо метку строки, либо номер строки.
Обычно вы используете оператор Resume или Resume 0 , когда пользователь должен внести исправление. Например, если вы запрашиваете у пользователя имя таблицы для открытия, а пользователь вводит имя таблицы, которая не существует, вы можете снова запросить пользователя и возобновить выполнение с помощью оператора, вызвавшего ошибку.
Вы используете оператор Resume Next , когда ваш код исправляет ошибку в обработчике ошибок, и вы хотите продолжить выполнение без повторного запуска строки, вызвавшей ошибку. Вы используете оператор Resume label , если хотите продолжить выполнение в другой точке процедуры, указанной аргументом label . Например, вы можете захотеть возобновить выполнение процедуры выхода, как описано в следующем разделе.
Выход из процедуры
Когда вы включаете в процедуру подпрограмму обработки ошибок, вы должны также включать подпрограмму выхода, чтобы подпрограмма обработки ошибок запускалась только в случае возникновения ошибки.Вы можете указать процедуру выхода с меткой строки так же, как вы указываете процедуру обработки ошибок.
Например, вы можете добавить процедуру выхода к примеру в предыдущем разделе. Если ошибки не происходит, процедура выхода запускается после тела процедуры. Если возникает ошибка, выполнение переходит к подпрограмме выхода после того, как был выполнен код подпрограммы обработки ошибок. Программа выхода содержит оператор Exit .
Функция MayCauseAnError ()
'Включить обработчик ошибок. При ошибке Перейти к Error_MayCauseAnError
. 'Включите сюда код, который может вызвать ошибку.
.
.
Exit_MayCauseAnError:
Функция выхода
Error_MayCauseAnError:
. 'Включите код для обработки ошибки.
.
.
'Продолжить выполнение с процедурой выхода для выхода из функции.
Возобновить Exit_MayCauseAnError
Конечная функция
Обработка ошибок во вложенных процедурах
Когда ошибка возникает во вложенной процедуре, у которой нет включенного обработчика ошибок, Visual Basic выполняет обратный поиск в списке вызовов в поисках включенного обработчика ошибок в другой процедуре, а не просто останавливает выполнение.Это дает вашему коду возможность исправить ошибку в другой процедуре. Например, предположим, что процедура A вызывает процедуру B, а процедура B вызывает процедуру C. Если в процедуре C возникает ошибка и нет включенного обработчика ошибок, Visual Basic проверяет процедуру B, а затем процедуру A на наличие включенного обработчика ошибок. Если он существует, выполнение переходит к этому обработчику ошибок. В противном случае выполнение останавливается и отображается сообщение об ошибке.
Visual Basic также выполняет обратный поиск в списке вызовов включенного обработчика ошибок, когда ошибка возникает в активном обработчике ошибок.Вы можете заставить Visual Basic выполнять поиск в обратном направлении по списку вызовов, вызывая ошибку в активном обработчике ошибок с помощью метода Raise объекта Err . Это полезно для обработки ошибок, которых вы не ожидаете в обработчике ошибок. Если возникает непредвиденная ошибка, и вы повторно создаете эту ошибку в обработчике ошибок, то выполнение передает резервную копию списка вызовов, чтобы найти другой обработчик ошибок, который может быть настроен для обработки ошибки.
Например, предположим, что процедура C имеет активированный обработчик ошибок, но обработчик ошибок не исправляет возникшую ошибку.Как только обработчик ошибок проверит все ожидаемые вами ошибки, он может восстановить исходную ошибку. Затем выполнение передает обратно список вызовов обработчику ошибок в процедуре B, если таковой существует, предоставляя этому обработчику ошибок возможность исправить ошибку. Если в процедуре B нет обработчика ошибок или если он не может исправить ошибку и повторно создать ее, то выполнение переходит к обработчику ошибок в процедуре A, если он существует.
Чтобы проиллюстрировать эту концепцию другим способом, предположим, что у вас есть вложенная процедура, которая включает в себя обработку ошибок несоответствия типа, ошибки, которую вы ожидали.В какой-то момент в процедуре C возникает ошибка деления на ноль, которую вы не ожидали. Если вы включили оператор для восстановления исходной ошибки, выполнение передает резервную копию списка вызовов другому включенному обработчику ошибок. , если таковой существует. Если вы исправили ошибку деления на ноль в другой процедуре в списке вызовов, то ошибка будет исправлена. Если ваш код не генерирует ошибку повторно, процедура продолжает выполняться без исправления ошибки деления на ноль. Это, в свою очередь, может вызвать другие ошибки в наборе вложенных процедур.
Таким образом, Visual Basic выполняет поиск включенного обработчика ошибок в резервной копии списка вызовов, если:
Ошибка возникает в процедуре, которая не включает включенный обработчик ошибок.
Ошибка в активном обработчике ошибок. Если вы используете метод Raise объекта Err , чтобы вызвать ошибку, вы можете заставить Visual Basic выполнить обратный поиск по списку вызовов для включенного обработчика ошибок.
Получение информации об ошибке
После того, как выполнение перешло к подпрограмме обработки ошибок, ваш код должен определить, какая ошибка произошла, и устранить ее. Visual Basic и Access предоставляют несколько языковых элементов, которые можно использовать для получения информации о конкретной ошибке. Каждый подходит для разных типов ошибок. Поскольку ошибки могут возникать в разных частях вашего приложения, вам необходимо определить, какие из них использовать в своем коде, исходя из ожидаемых ошибок.
Элементы языка, доступные для обработки ошибок, включают:
Err объект
ADO Ошибка объекта и ошибки Коллекция
DAO Ошибка объекта и ошибки Коллекция
AccessError Метод
Ошибка , событие
Err объект
Объект Err предоставляется Visual Basic.Когда возникает ошибка Visual Basic, информация об этой ошибке сохраняется в объекте Err . Объект Err поддерживает информацию только об одной ошибке за раз. Когда возникает новая ошибка, объект Err обновляется, чтобы вместо этого включать информацию об этой ошибке.
Чтобы получить информацию о конкретной ошибке, вы можете использовать свойства и методы объекта Err :
- Свойство Number является свойством по умолчанию для объекта Err ; он возвращает идентификационный номер возникшей ошибки.
- Свойство Description объекта Err возвращает описательную строку, связанную с ошибкой Visual Basic.
- Метод Clear очищает текущую информацию об ошибке из объекта Err .
- Метод Raise генерирует определенную ошибку и заполняет свойства объекта Err информацией об этой ошибке.
В следующем примере показано, как использовать объект Err в процедуре, которая может вызвать ошибку несоответствия типа:
Функция MayCauseAnError ()
'Объявите константу для представления вероятной ошибки.Константа conTypeMismatch как целое число = 13
При ошибке Перейти к Error_MayCauseAnError
. 'Включите сюда код, который может вызвать ошибку.
.
.
Exit_MayCauseAnError:
Функция выхода
Error_MayCauseAnError:
'Проверить свойства объекта Err.
Если Err = conTypeMismatch Тогда
. 'Включите код для обработки ошибки.
.
.
Еще
'Восстановить исходную ошибку.
Dim intErrNum As Integer
intErrNum = Err
Err.Очистить
Err.Raise intErrNum
Конец, если
'Продолжить выполнение с процедурой выхода для выхода из функции.
Возобновить Exit_MayCauseAnError
Конечная функция
Обратите внимание, что в предыдущем примере метод Raise используется для восстановления исходной ошибки. Если возникает ошибка, отличная от ошибки несоответствия типа, выполнение будет передано обратно из списка вызовов другому включенному обработчику ошибок, если таковой существует.
Объект Err предоставляет всю необходимую информацию об ошибках Visual Basic.Однако он не дает вам полной информации об ошибках Access или ошибках ядра СУБД Access. Доступ и объекты доступа к данным (DAO) предоставляют дополнительные языковые элементы, чтобы помочь вам с этими ошибками.
Объект ошибки и коллекция ошибок
Объект Error и коллекция Errors предоставляются ADO и DAO. Ошибка Объект представляет ошибку ADO или DAO. Одна операция ADO или DAO может вызвать несколько ошибок, особенно если вы выполняете операции DAO ODBC.Каждая ошибка, возникающая во время определенной операции доступа к данным, имеет связанный объект Error . Все объекты Error , связанные с конкретной операцией ADO или DAO, хранятся в коллекции Errors , причем ошибка самого низкого уровня является первым объектом в коллекции, а ошибка самого высокого уровня — последним объектом в коллекции.
Когда возникает ошибка ADO или DAO, объект Visual Basic Err содержит номер ошибки для первого объекта в коллекции Errors .Чтобы определить, возникли ли дополнительные ошибки ADO или DAO, проверьте коллекцию Errors . Значения свойств ADO Number или DAO Number и свойств ADO Description или DAO Description первого объекта Error в коллекции Errors должны соответствовать значениям Number и Описание свойств объекта Visual Basic Err .
Метод AccessError
Вы можете использовать метод Raise объекта Err , чтобы сгенерировать ошибку Visual Basic, которая на самом деле не произошла, и определить описательную строку, связанную с этой ошибкой.Однако вы не можете использовать метод Raise для генерации ошибки доступа, ошибки ADO или ошибки DAO. Чтобы определить описательную строку, связанную с ошибкой доступа, ошибкой ADO или ошибкой DAO, которая на самом деле не произошла, используйте метод AccessError .
Событие ошибки
Событие Error можно использовать для перехвата ошибок, возникающих в форме или отчете Access. Например, если пользователь пытается ввести текст в поле с типом данных «Дата / время», возникает событие «Ошибка».Если вы добавляете процедуру обработки события «Ошибка» в форму «Сотрудники», а затем пытаетесь ввести текстовое значение в поле HireDate, запускается процедура обработки события «Ошибка».
Процедура обработки события Error принимает целочисленный аргумент DataErr. Когда выполняется процедура обработки события Error, аргумент DataErr содержит номер возникшей ошибки доступа. Проверка значения аргумента DataErr в процедуре обработки события — единственный способ определить номер возникшей ошибки. Объект Err не заполняется сведениями об ошибке после возникновения события Error.Вы можете использовать значение аргумента DataErr вместе с методом AccessError , чтобы определить номер ошибки и ее описательную строку.
Примечание
Оператор Error и функция Error предназначены только для обратной совместимости. При написании нового кода используйте объекты Err и Error , функцию AccessError и событие Error для получения информации об ошибке.
Об авторах
Ссылка предоставлена сообществом UtterAccess.
UtterAccess — это ведущая вики-страница и справочный форум Microsoft Access.
См. Также
Поддержка и отзывы
Есть вопросы или отзывы об Office VBA или этой документации? См. Раздел Поддержка и отзывы Office VBA, чтобы узнать, как получить поддержку и оставить отзыв.
Как уже было сказано, если при обработке возникает ошибка программа из раздела Try , компилятор передает обработку к следующему разделу Catch .Затем вы можете использовать раздел улова для работы с с ошибкой. Как минимум, вы можете отобразить сообщение, информирующее пользователя. Для этого вы можете создать окно сообщения в разделе Catch . Вот это пример: Система импорта. Импортирует System.Windows.Forms Модульное упражнение Начинающий общественный класс Наследует форму Частный LblNumber как метка Частный TxtNumber как текстовое поле Друг WithEvents BtnCalculate As Button Private LblResult As Label Частный TxtResult как TextBox Компоненты Dim As System. ComponentModel.Container Публичная подписка Новое () InitializeComponent () Конец подписки Открытый Sub InitializeComponent () Text = "Исключительное поведение" LblNumber = Новый ярлык LblNumber.Location = Новая точка (17, 23) LblNumber.Text = "Число:" LblNumber.AutoSize = True TxtNumber = Новое текстовое поле TxtNumber.Location = Новая точка (78, 20) TxtNumber.Size = Новый размер (83, 20) BtnCalculate = Новая кнопка BtnCalculate.Местоположение = Новая точка (78, 45) BtnCalculate.Text = "Рассчитать" BtnCalculate.Size = Новый размер (83, 23) LblResult = Новый ярлык LblResult.Location = Новая точка (17, 75) LblResult.Text = "Результат:" LblResult.AutoSize = True TxtResult = Новое текстовое поле TxtResult.Location = Новая точка (76, 72) TxtResult. Size = Новый размер (83, 20) Controls.Add (LblNumber) Controls.Add (TxtNumber) Элементы управления.Добавить (BtnCalculate) Controls.Add (LblResult) Controls.Add (TxtResult) Конец подписки Частная подпрограмма CalculateClicked (отправитель ByVal как объект, ByVal и как EventArgs) Обрабатывает BtnCalculate.Click Тусклый номер как двойной Тусклый результат как двойной Пытаться Число = CDbl (TxtNumber.Text) Результат = Число * 12,48 TxtResult.Текст = CStr (Результат) Поймать MsgBox («Произошло что-то плохое») Конец попытки Конец подписки Конец класса Функция Main () как целое число Dim frmStart As Starter = Новый стартер Application.Run (frmStart) Возврат 0 Конечная функция Концевой модуль Конечно, ваше сообщение может быть не особенно четким но на этот раз программа не выйдет из строя.
Большинство библиотек, таких как Borland VCL и Microsoft MFC поставляются со своими собственными классами для обработки исключений.Даже библиотека Win32 предоставляет свой тип механизма для выявления ошибок. Для поддержки исключения .NET Framework предоставляет специальный класс под названием Exception . Как только компилятор обнаруживает ошибку, класс Exception позволяет вам чтобы определить тип ошибки и предпринять соответствующие действия. Обычно Исключение в основном служит общим класс исключений. Он используется как улов, за которым не следует параметр. Предвидение различных типов проблем, которые могут возникнуть в программа Microsoft произвела различные классы из Exception , чтобы сделать этот вопрос дружелюбнее.В результате почти любой тип исключения, который вы можете У встречи уже есть класс, чтобы справиться с ней. Поэтому, когда ваш программа сталкивается с исключением, вы легко можете определить тип ошибки. Существует так много классов исключений, которые мы не можем изучить или просмотрите их все. Решение, которое мы будем использовать, — представить или просмотреть класс, когда мы встречаем его тип ошибки. При обработке исключений ошибки обрабатываются в Поймайте статью . Чтобы использовать его, с правой стороны Catch введите a имя параметра, за которым следует оператор As, за которым следует тип исключение, с которым вы хотите иметь дело.По умолчанию исключение первого типа Исключение . Исходя из этого, типичная формула для реализации исключения обработка: Частная подпрограмма CalculateClicked (отправитель ByVal как объект, ByVal и как EventArgs) Обрабатывает BtnCalculate.Click Тусклый номер как двойной Тусклый результат как двойной Пытаться 'Здесь можно обработать обычный ход программы Поймать ex как исключение 'Сделайте здесь исключение Конец попытки Концевой переводник Как уже говорилось, когда в возникает исключение Попробуйте раздел , компиляция кода перенесена на Catch раздел.Если вы объявляете исключение как тип Exception , это класс определит ошибку. Одно из свойств класса Exception : позвонил по номеру , сообщение . Это свойство содержит строку, описывающую тип возникшей ошибки. Затем вы можете использовать это исключение . Сообщение для отображения сообщения об ошибке, если хотите. Вот пример: Частная подпрограмма CalculateClicked (отправитель ByVal как объект, ByVal и как EventArgs) Обрабатывает BtnCalculate.Нажмите Тусклый номер как двойной Тусклый результат как двойной Пытаться Число = CDbl (TxtNumber.Text) Результат = Число * 12,48 TxtResult.Text = CStr (Результат) Поймать ex как исключение MsgBox (например, сообщение) Конец попытки Концевой переводник Как видите, одна из сильных сторон сообщения свойство состоит в том, что он дает вам хорошее представление о типе проблемы, которая произошло.Иногда сообщение, предоставленное классом Exception , может не кажутся достаточно явными. Фактически, вы можете не захотеть показывать это пользователю. поскольку, как и в этом случае, пользователь может не понимать, что означает сообщение и почему это используется. В качестве альтернативы вы можете создать собственное сообщение и отобразить его пользователю. Как было показано ранее, чтобы отобразить собственное сообщение, в разделе Catch используйте функцию MsgBox () для создания и отобразить сообщение. Вот пример: Частная подпрограмма CalculateClicked (отправитель ByVal как объект, ByVal и как EventArgs) Обрабатывает BtnCalculate.Нажмите Тусклый номер как двойной Тусклый результат как двойной Пытаться Число = CDbl (TxtNumber.Text) Результат = Число * 12,48 TxtResult.Text = CStr (Результат) Поймать ex как исключение MsgBox ("Операция не может быть выполнена, потому что" & "введенный вами номер недействителен") Конец попытки Концевой переводник Вы также можете комбинировать исключение . Сообщение сообщение и ваше собственное сообщение: Частная подпрограмма CalculateClicked (отправитель ByVal как объект, ByVal и как EventArgs) Обрабатывает BtnCalculate.Нажмите Тусклый номер как двойной Тусклый результат как двойной Пытаться Число = CDbl (TxtNumber.Text) Результат = Число * 12,48 TxtResult.Text = CStr (Результат) Поймать ex как исключение MsgBox (например, сообщение и vbCrLf & "Операция не может быть выполнена, потому что" & "введенный вами номер недействителен") Конец попытки Концевой переводник |
Обработка ошибок в Excel VBA
Ниже мы рассмотрим две программы в Excel VBA .Одна программа просто игнорирует ошибки . Другая программа продолжает выполнение в указанной строке после обнаружения ошибки.
ситуация:
Обе программы вычисляют квадратный корень из чисел.
Квадратный корень 1
Добавьте следующие строки кода к командной кнопке «Квадратный корень 1».
1. Сначала мы объявляем два объекта Range.Мы называем объекты Range rng и cell.
Dim rng As Range, cell as Range
2. Инициализируем объект Range rng с выбранным диапазоном.
Установить rng = Выбор
3. Мы хотим вычислить квадратный корень из каждой ячейки в случайно выбранном диапазоне (этот диапазон может быть любого размера). В Excel VBA для этого можно использовать цикл For Each Next. Добавьте следующие строки кода:
Для каждой ячейки In rngСледующая ячейка
Примечание: здесь случайным образом выбираются rng и ячейка, вы можете использовать любые имена.Не забудьте ссылаться на эти имена в остальной части кода.
4. Добавьте в цикл следующую строку кода.
При ошибке возобновить следующий
5. Затем мы вычисляем квадратный корень из значения. В Excel VBA мы можем использовать для этого функцию Sqr. Добавьте в цикл следующую строку кода.
cell.Value = Sqr (cell.Value)
6. Закройте редактор Visual Basic и протестируйте программу.
Результат:
Заключение: Excel VBA проигнорировал ячейки, содержащие недопустимые значения, такие как отрицательные числа и текст.Без использования оператора «On Error Resume Next» вы получите две ошибки. Будьте осторожны и используйте оператор «On Error Resume Next» только в том случае, если вы уверены, что игнорировать ошибки можно.
Квадратный корень 2
Добавьте следующие строки кода к командной кнопке «Квадратный корень 2».
1. Та же программа, что и квадратный корень 1, но вместо «При ошибке возобновить следующий» на:
При ошибке Перейти к недопустимому значению:
Примечание. Здесь случайным образом выбрано InvalidValue, вы можете использовать любое имя.Не забудьте ссылаться на это имя в остальной части кода.
2. За пределами цикла For Each Next сначала добавьте следующую строку кода:
Выходной переводник
Без этой строки будет выполнен остальной код (код ошибки), даже если ошибки нет!
3. Excel VBA продолжает выполнение со строки, начинающейся с InvalidValue: при обнаружении ошибки (не забудьте двоеточие). Добавьте следующую строку кода:
InvalidValue:
4.Пока мы сохраняем простой код ошибки. Мы отображаем MsgBox с некоторым текстом и адресом ячейки, в которой произошла ошибка.
MsgBox «не может вычислить квадратный корень из ячейки» и ячейки. Адрес
5. Добавьте следующую строку, чтобы указать Excel VBA возобновить выполнение после выполнения кода ошибки.
Продолжить следующую
6. Закройте редактор Visual Basic и протестируйте программу.
Результат:
VB Core II Условные операторы Обработка исключений Циклы Отладка массивов.
Презентация на тему: «Условные операторы VB Core II Обработка исключений Отладка массивов циклов» — Стенограмма презентации:
1 VB Core II Условные операторы Обработка исключений Циклы Отладка массивов
2 Операторы if If c> 5 Then x = 1 y = 3 End If If c> 5 Then x = 1: y = 3 If c> 5 Then x = 1 y = 3 Else z = 7 End If If If c> 5 Then x = 1 y = 3 Иначе Если c = 4 Тогда z = 7 Иначе x = 9 Конец Если
3 Упражнение — решатель квадратного уравнения Создайте форму с — 3 текстовыми полями для ввода значений для a b и c (и меток в качестве подсказок) 2 метки, где будут отображаться корни Кнопка с надписью «Решить» Код кнопки (функция квадратного корня — sqr)
4 выберите Dim Number Number = 8 ‘Инициализировать переменную.Выберите номер дела ‘Оценка номера. Случай от 1 до 5 ‘Число от 1 до 5 включительно. x = 4 Случай 6, 7, 8 ‘Число от 6 до 8. x = 5 Случай от 9 до 10’ Число 9 или 10. x = 6 Case Else ‘Другие значения. x = 7 Конец выбора
5 Исключение обработки ошибок и исключений = проблемное событие во время выполнения, обычно связанное с вводом-выводом, например, файл не найден, соединение с сервером потеряно, недопустимый ввод пользователя, а не ошибка программирования. VB вызывает ошибки исключения (в отличие от Java) VB не вызывает принудительную обработку исключений
6 Обработчики ошибок — пример — недопустимые числа Private Sub Command1_Click () Dim num1 As Integer Dim num2 As Integer Dim result As Integer On Error GoTo myErrorHandler num1 = Text1.Текст num2 = Text2.Text result = num1 + num2 Label1.Caption = result Exit Sub myErrorHandler: If Err.Number = 13 Then MsgBox («Пожалуйста, введите действительное число») Else MsgBox (Err.Description) End If Resume Next End Sub Упражнение Попробуйте это в программе калькулятора. Затем выполните деление на ноль (11)
7 Для следующих циклов Dim x как Integer, total As Integer total = 0 Для x = от 1 до 5 всего = всего + x Далее Dim x как Integer, total As Integer total = 0 Для x = от 1 до 5 Шаг 2 всего = всего + x следующий
8 Отладка — отладка.print Debug.print x, y, z Непосредственное окно — CTRL G Упражнение — напишите цикл for next для сложения нечетных чисел от 1 до 9 включительно. Используйте debug.print, чтобы проверить его работу
9 Другие циклы Dim c как целое число c = 1 Do while c <5 c = c + 1 цикл Dim c как целое число c = 1 Do до c> 4 c = c + 1 цикл Dim c как целое число c = 1 Do c = c + 1 цикл пока c <5 Dim c как целое число, x как целое число c = 1 x = 2 Do c = c + 1 цикл до тех пор, пока c> 4 и x <> 3
10 Массивы (фиксированный размер) Dim x (100) как целое число Dim i как целое число Для i = 0 до 100 x (i) = 99 Далее Dim x (от 1 до 3, от 1 до 3) как целое число Dim i как целое, j как целое Для i = от 1 до 3 Для j = от 1 до 3 x (i, j) = 99 Далее
11 Динамические массивы Dim x () As Integer ReDim x (5) Dim i, j As Integer For i = 1 To 5 x (i) = 99 Next ReDim Preserve x (10) For i = 6 To 10 x (i) = 100 следующий
.