Visual Basic. Программирование на Visual Basic

..........................................................................................................................

[ Главная ] [ Статьи ] [ Для новичков ] [ Примеры ] [ Программы ] [ Microsoft Agent 2.0 ] [ Пособие ] [ Уроки ] [ Разное ]
..........................................................................................................................


Урок № 16. Отладка программы

Итак, на предыдущем уроке мы нашли баги (от слова Bug - жук) в нашей программе, т.е. недочёты (ошибки) . От этих багов нужно избавиться. Посмотрим причину возникновения ошибок. Запустите программу. Ничего не вводя в поля нажмите на кнопку. Visual Basic выдаст окно, в котором скажет: "Type mismatch", т.е. ошибка в типах. В окне доступны 3 кнопки:

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

End - завершить приложение
Debug - показать место возникновения ошибки, чтобы мы смогли от неё избавиться
Help - вызвать справку о возникшей ошибке.

Нажмите Debug. Visual Basic покажет вам причину возникновения ошибки:

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

Жёлтым цветом выделена строка - причина ошибки. Если навести курсор мыши на имя переменной, то всплывёт подсказка, в которой Visual Basic сообщит нам её значение. Такая возможноть доступка только в режиме Debug. Текущий режим можно узнать из заголовка окна Visual Basic. Например:

в режиме проектировки интерфейса это строка:
Имя_Проекта - Microsoft Visual Basic [design]

при запущенном приложении:
Имя_Проекта - Microsoft Visual Basic [run]

в режиме Debug:
Имя_Проекта - Microsoft Visual Basic [break]

Наведите мышкой на txtParamA.Text. VB сообщит о том, что значение текстового поля txtParamA.Text = "" (пустым кавычкам, или по другому - пустая строка). Здесь можно догадаться, почему происходит ошибка несовпадения типов. Ведь переменная paramA должна хранить вещественное число, а здесь мы пытаемся присвоить ей строковое значение - "". Если бы paramA имела тип String, или в txtParamA.Text была бы строка - число ("123") - ошибка бы не возникла. А здесь Visual Basic просто не может сам конвертировать строку "" в число типа Double. Мы должны найти возможное решение ошибки. Давайте заглянем в раздел vbhelprus. Найдём там функцию Val. О! Это как раз то, что нужно! Давайте изменим код:

paramA = txtParamA.Text
paramB = txtParamB.Text
paramC = txtParamC.Text

На код:

paramA = Val(txtParamA.Text)
paramB = Val(txtParamB.Text)
paramC = Val(txtParamC.Text)

Теперь ошибок несовпадения типов быть не может, т.к. функция Val при любом параметре возвратит число, а сама функция Val никогда не вызовет ошибки, хотя ... но это уже на совести разработчиков VB :)

Проанализируем полученный результат. Что изменилось после того, как мы вставили функцию Val? Теперь мы знаем что переменным paramA, paramB и paramC в любом случае присвоится число. Но вот какое число? Ведь если мы введём в поля нули, то и переменные будут содержать нули! Также, если в поля мы введём !буквы!, то переменные также будут содержать нули. Значит нужно сделать проверку на содержание в переменных нулей. Запустите программу и введите в поля нули (или буквы) и нажмите кнопку. Visual Basic выдаст окно:

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

Нажимаем Debug и вот что видим:

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

Причина ошибка заключается в невозможности деления на 0, а paramA у нас как раз и равен 0. К тому при нулевых коэффициентах квадратное уравнение решается гораздо проще (например, если c=0, то x вынесем за скобку, ну а дальше всё просто). Избавимся от этого недоразумения. Для этого, вставим после присвоения значения свойства Text переменным ещё одну проверку - проверку на содержание нулей в переменных:

If paramA = 0 Or paramB = 0 Or paramC = 0 Then
    MsgBox "Нули в качестве коэффициентов не допускаются!", _
    vbCritical
    Exit Sub
End If

Символ "_" используется в том случае, когда вы хотите перенести часть выражения на другую строчку. В данном случае мы переносим константу vbCritical.

Здесь мы проверяем переменные на содержание в них нулей. В принципе, можно было бы проверить не переменные, а сами тектовые поля (If Val(txtParamA.Text)=0 Then....). Это уже дело вкуса. Всё равно, результат одинаков.

Второй баг побеждён! Можно запускать программу и решать уравнения :).

Итоговый код программы:

Private Sub cmdCalculate_Click()

' объявляем переменные
Dim paramA As Double
Dim
paramB As Double
Dim
paramC As Double

Dim
x1 As Double
Dim
x2 As Double
Dim
D As Double

paramA = Val(txtParamA.Text)
paramB = Val(txtParamB.Text)
paramC = Val(txtParamC.Text)


If paramA = 0 Or paramB = 0 Or paramC = 0 Then
    MsgBox "Нули в качестве коэффициентов не допускаются!", _
    vbCritical
    Exit Sub
End If

D = (paramB * paramB) - (4 * paramA * paramC)

If D > 0 Then
    x1 = (paramB + Sqr(D)) / (2 * paramA)
    x2 = (paramB - Sqr(D)) / (2 * paramA)
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1
    lblX2.Caption = "Корень №2: " & x2
ElseIf D = 0 Then
    x1 = paramB / (2 * paramA)
    x2 = x1
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корень №1: " & x1
    lblX2.Caption = "Корень №2 = Корню №1"
ElseIf D < 0 Then
    lblD.Caption = "Дискременант: " & D
    lblX1.Caption = "Корней нет!"
    lblX2.Caption = ""
    MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical
End If

End Sub

Может быть вы уже заметили, что при каждом запуске программы, форма появляется всё время в разных местах. Давайте избавимся от этого, и сделаем так, чтобы форма при каждом запуске появлялась в центре экрана. Для этого изменим свойство StartUpPosition в "2-CenterScreen".

Использование пошаговой трассировки:

Пошаговая трассировка - это метод отладки приложения при котором можно выполнять код по одной команде и следить за ходом её выполнения. Это очень полезный метод! Таким методом можно находить те ошибки, которые не может найти Visual Basic. Такие ошибки называются логическими. Здесь я бы хотел привести очень интересный и поучительный отрывок из книги "Программирование в среде Visual Basic 5":

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

"Тестирование программ - это больше исскусство, чем наука. Не существует каких-либо правил, которые всегда срабатывают. Если программа имеет большой размер кода или достаточно сложную структуру и нет уверенности в том, что удастся проверить её по всем возможным путям выполнения, то в этом случае вам стоит подойти к процессу тестирования с точки зрения здравого смысла. Например, фирма Microsoft не имеет возможности проверять каждую новую версию ОС на всех возможных конфигурациях аппаратного обеспечения."

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

"В истории не говорится о реакции разгневанного клиента, однако, если эта история произошла на самом деле, то вина программиста, написавшего приложение, в том, что он забыл вставить проверку на наличие пустых счетов. Видимо он просто не предполагал, что подобная ситуация может возникнуть. (Хотя, по правде говоря, многие программисты используют в операторах сравнения выражение a > b, вместо a >= b)."

"Мораль этой истории такова, что надо для проверки корректности работы программы использовать граничные значения, так как именно такие значения позволяют находить ошибки."

Вот так вот дорогие читатели. Как видите программ без ошибок не бывает. Теперь я думаю вам понятно, почему время от времени приходится переустанавливать Windows :))).

Ну вернёмся к отлаживанию (избавлению программы от лажи ;). На чём мы остановились? Ах да, на пошаговой трассировке и логических ошибках. Вот именно такая логическая ошибка оставила клиента без электричества. Для нахождения этих ошибок очень удобно использовать пошаговую трассировку.

Как использовать такую трассировку? Нужно всего навсего в нужном месте программы поставить точку останова (брикпоинт (Breakpoint)). Дойдя до такого места, Visual Basic преостановит выполнение программы и переведёт вас в режим Debug, где вы сможете выполнять код покомандно. Давайте поставим брикпоинт в нашей программе, и проследим ход её выполнения. Чтобы поставить точку останова нужно кликнуть на вертикали слева от кода:

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

А можно и по другому. Нажмите правой кнопкой мыши на той строчке кода, где вы хотите поставить брикпоинт и в меню выбрать Toggle->Breakpoint. Замечание: такую точку нельзя ставить на строчке с объявлением переменной.

Поставьте точку как показано на рисунке и запустите программу. Введите следующие данные в качетсве параметров: a = 3, b = -6, c = 2. Нажмите на кнопку "Решить!". Visual Basic остановит выполнение программы точно на той строчке, на которой стоит брикпоинт. Теперь VB в режиме Debug. Вы можете просматривать значения переменных, наводя на них курсор мыши и выполнять программу по шагам. Чтобы выполнить одну команду, нужно нажать F8 или Shift+F8. Отличие этих двух команд заключается в том, что при нажатии F8 на строчке с вызовом процедуры Visual Basic войдёт в эту процедуру и вы сможете продолжить пошаговое выполнение в этой процедуре до строчки End Sub, где VB вернёт вас на то место, где произошёл вызов. Если же нажать Shift+F8, то Visual Basic выполнит процедуру, но не будет заходить в неё для пошаговой трассировки.

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

Visual Basic - здесь можно почитать и скачать статьи, книги, примеры, описания к API функциям

Здесь изображены все наши локальные переменные. Их 6 штук. "А вот что такое Me?" - спросите вы. Никак "Millenium"? :) Нет, "Me" - это тоже зарезервированное слово Visual Basic. Оно указывает на текущую форму. В своей программе вы можете обращаться к своей форме через Me. Например, если написать

Me.Hide

То с экрана скроется та форма, в коде которой написан этот код. (простите за каламбур).

Также можно заметить значок "+" слева от "Me". При нажатии на него произойдёт раскрытие списка со всеми дочерними объектами формы. Там же будут находится все элементы управления помещённые на форму, а также все глобальные переменные уровня этой формы.

Заметьте, что окно Locals - плавающее , и при двойном щелчке по заголовку окна оно "пристыкуется" в среду VB. При очередном двойном щелчке окно "отстыкуется".

Дотрассируйте (т.е. пройдите пошагово) программу до конца. Закройте её.

Обработка других ошибок

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

В Visual Basic существуют несколько глобальных объектов. Это Err, Printer, Screen, Clipboard и App. Эти объекты доступны в любом месте программы. В данном случае нас интересует только объект Err. О назначении и использовании других объектов, возможно, расскажу в статьях.

Объект Err содержит в себе 6 свойств и 2 метода. Этот объект содержит информацию о последней произошедшей ошибке. Вот наиболее важные свойства:

Err.Number
Err.LastDllError

Эти свойства содержат номер последней произошедней ошибки. Первое - содержит номер ошибки самого Visual Basic. Второе - номер ошибки при работе с API функциями. Пока нам понадобится только первое свойство.

Visual Basic располагает оператором, с помощью которого можно контролировать ход программы при возникновении ошибок. Это оператор On Error. Он имеет несколько видов:

On Error GoTo МЕТКА
On Error Resume Next
On Error GoTo 0

Первый оператор позволяет указать Visual Basic метку (номер строки) на которую передастся управление программы при возникновении ошибки. Рассмотрим пример использования этого оператора:

Private Sub Command1_Click()
    Dim myString As String
    On Error GoTo ERRH
    myString = "ERROR HANDLING WITH VB IS COOL"
    MsgBox Mid(myString, 0, 1) '<--- здесь ошибка (#)
    Exit Sub '<--- досрочно выходим, если нет ошибок
ERRH: '<--- метка
    MsgBox Error(Err.Number) '<--- выводим свою ошибку
End Sub

Что здесь произойдёт при выполнении этого кода? Итак, сначала объявляется переменная myString. Затем мы используем оператор On Error.... В качестве метки указываем метку ERRH (Метка в VB - это слово с двоеточием на конце). Т.е. здесь мы указываем VB, что при возникновении ошибки нужно передать управление на метку ERRH. Далее мы присваиваем строке некоторое значение. Пока всё в рамках правил. А вот в строке (#) происходит ошибка, а именно - функция Mid выдаёт ошибку "Invalid procedure call or argument" (Неверные вызов процедуры или аргумент). Это происходит, потому что второй параметр функции Mid меньше единицы. А он должен быть больше или равен ей (так написано в документации). Таким образом, происходит ошибка с номером 5. В нашем обработчике ошибки мы выводим MsgBox с описанием возникшей ошибки. Функция Error имеет один аргумент - номер ошибки. Функция возвращает строку - описание ошибки. Теперь запустите этот код (Для этого поместите на форму кнопку и вставьте этот кусок в код формы). Вы увидите наш MsgBox c ошибкой. Обратите внимание, что этот MsgBox выдаём мы, а не сам Visual Basic, как было бы, если бы не было оператора On Error. Также заметьте оператор Exit Sub, который мы поставили перед меткой ERRH. Как вы помните, этот оператор предназначен для досрочного выхода из процедуры. Он здесь необходим для того, чтобы случайно не выполнился наш обработчик ошибки в том случае, когда ошибки нет. Т.е. если вы измените второй аргумент функции Mid с 0 на 1, убрав таким образом причину ошибки, то вы увидите только MsgBox в строке (#). Код после ERRH выполнятся не будет.

Итак, вывод. Используйте оператор On Error тогда, когда вы не полностью уверены в правильности выполнения того или иного кода. Например, вы можете перед открытием файла поставить On Error с указанием метки, где вы сможете спокойно обработать случай, когда, например, файла нет на диске, или диск не доступен и т.д.

Необходимо подчеркнуть тот факт, что теперь при возникновении ошибки Visual Basic не выдаёт своё окно с описанием ошибки и нашей любимой кнопкой Debug :). Это можно исправить. Для этого нажмите правой кнопкой в любом месте кода программы и выберите Toggle->Break On All Errors. Теперь Visual Basic всегда будет переводить программу в режим Debug при возникновении любой ошибки (естесственно, это не касается логических ошибок, на них не действует ни один оператор :(.

Давайте теперь посмотрим на оператор Оператор On Error Resume Next. Его можно использовать тогда, когда вы просто хотите подавить ошибку. Т.е. продолжить программу без всяких предупреждений. Замените в нашем примере On Error GoTo ERRH на On Error Resume Next и посмотрите что прозойдёт. Вы не увидите никаких признаков ошибки. Код просто будет продолжен со следующей строчки. В нашем случае - это Exit Sub.

Оператор On Error GoTo 0 удаляет все ранее установленные обработчики ошибок, т.е. разрешает Visual Basic использовать его собственный обработчик ошибок (При возникновении которой, он закроет приложение. А это иногда совсем не к чему).

За более подробной информацией можно обратиться к справочникам.

Переходим к следующему уроку.



..........................................................................................................................

[ Главная ] [ Диски ] [ Книги ] [ Архив рассылки ] [ Архив новостей ] [ Готовые кусочки программ ] [ Карта сайта ]
..........................................................................................................................

По страницам сайта Visaul Progs
или Изучение Visual Basic
Рассылка 'По страницам сайта Visaul Progs' >>> Подпишись на рассылку - будешь получать новые статьи , примеры и много полезной информации из первых рук!!! >>>Если у вас есть статья которой нет на сайте
пришлите ее мне-------->
Послать статью
>>>Если вы хотите задать вопрос
пишите-------->
Мне нужна помощь


Рейтинг сайтов YandeG Rambler's Top100
Реклама:

...:::Design by Mystf0rse 2005-2010 year:::...