Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методический комплекс ПЗ СППР 2011.doc
Скачиваний:
27
Добавлен:
16.02.2016
Размер:
1.27 Mб
Скачать

2. Упражнение

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

УПРАЖНЕНИЕ 1. ОТЛАДКА КОДА

Это упражнение основано на упражнении 12.1 предыдущей главы. Как и ранее его назначением является получение от пользователя сведений о регионе, способ вычисления итоговых показателей и как минимум одном товаре, продаваемом в я регионе. В результате итоговые сведения о выбранном регионе и товарах отображаются с помощью последовательности окон сообщений — по одному для каждого выбранного товара. Единственным отличием по сравнению с упражнением из предыдущей главы является возможность выбора нескольких товаров вместо одного.

В файле Debugging.xlsпредставлены все необходимые пользовательскиеформы и код приложения. Но в коде допущено несколько ошибок, которые стан заметны только при запуске приложения. Это не скрытые ошибки, созданным специально для того, чтобы ввести вас в заблуждение, а достаточно распространенна ошибки, совершаемые начинающими разработчиками. Вашей задачей является Л иск и устранение этих ошибок. Если поиск и исправление ошибок не дает ощутимых результатов и вы подозреваете, что нашли не то, что нужно (или то, что совсем не нужно), то воспользуйтесь файломDebuggingFinished.xls, который содержитполностью исправленный код. Кроме того, в начале модуля вы найдете комменЛ рий со списком ошибок, внесенных в файл Debugging. xls. Как и раньше, несЛ шите обращаться к этому файлу, пока не попробуете самостоятельно выполнится задание.

3. Отладка

Сначала мы рассмотрим ошибки, которые может допустить разработчик, т.е. вы или я в процессе написания программы; также будут описаны методы поиска! исправления этих ошибок. Ошибки можно разделить на три основные категории синтаксические ошибки, ошибки выполнения и логические ошибки.

Синтаксические ошибки

Синтаксические ошибки обычно проще всего обнаружить и исправить. Так как ошибки возникают при неправильном написании ключевых слов, пропуске ключевого слова или внесении каких-либо других "грамматических" ошибок. Их довольно просто обнаружить, так как VBE замечает их сразу после введения, выделяя ошибочный код красным цветом и выводя предупреждение в окне сообщения1. Возможно, вы уже встречались с подобным поведением редактора VB А, но если этого не происходило, то введите следующий код и нажмите клавишу <Enter>.

If FirstName > SecondName

1Такое поведение VBE принято по умолчанию; его не стоит менять. Но если предупреждении вас утомили, то воспользуйтесь командой Tools - Options и сбросьте флажок Auto Syntax Check (Автоматическая проверка синтаксиса) на вкладкеEditor.

Редактор немедленно сообщит, что строка содержит синтаксическую ошибку: отсутствует ключевое слово Then. Иногда сообщение об ошибке будет явно указывать на причину ошибки, однако бывает, что сообщения предельно запутанны. По крайней мере, сообщение дает понять, что существует проблема в синтаксисе кода, а это позволяет немедленно исправить ошибку. Если вы не уверенны в правильности синтаксиса введенного кода, то обратитесь к справочному руководству.

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

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

Option Explicit

Option Base 1

Sub Test ()

Dim MyArray(10) As Integer, i As Integer, NRep As Integer

NRep = InputBox("Enter the number of replications")

For i = 1 To NRep

MyArray (1) = 20 * i

Next

End Sub

Этот код не содержит синтаксических ошибок, но, скорее всего, его выполнение приведет к ошибке во время выполнения. У пользователя запрашивается количество ограничений, которое сохраняется в переменной NRep. Если пользователь введет значение, меньшее или равное 10, то программа будет работать правильно. Если пользователь введет значение, превышающее 10, программа попытается внести вмассив больше значений, чем в состоянии хранить массив. Если запустить приложение и ввести в поле ввода данных 15, то будет выведено сообщение об ошибке, показанное на рис. 13.1. Это одно из тех загадочных сообщений об ошибке, которыми знаменита компания Microsoft и ее программные продукты. Многие пользователи искренне ненавидят эти сообщения, так как, во-первых, они указывают на существование ошибки, а во-вторых, не приводят никакой дополнительной информации о месте расположения ошибки.

На этом этапе вы можете поступить одним из трех способов.

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

  2. Завершить выполнение программы, что не поможет решить проблему.

  3. Щелкнуть на кнопке Debug(Отладка).

Последний вариант приведет к выделению желтым цветом строки кода, которая вызвала ошибку. Если навести указатель мыши на переменные, то на экране будет отображено их текущее значение. В результате вы сможете получить всю необходимую информацию о решении возникшей проблемы. На рис..2 показано, что произойдет, если щелкнуть на кнопке Debug и навести указатель на переменную i в строи которая привела к выводу сообщения об ошибке. В этом случае переменная имен значение 11, а массив в состоянии вместить только 10 элементов.

Puc. 2. Окно кода после щелчка на кнопке Debug

Это именно та подсказка, которая потребуется для исправления кода программы, как показано ниже. Суть решения заключается в изменении размеров массива после получения значения переменнойNRep.

Sub Test()

Dim MyArray(lO) As Integer, i As Integer, NRep As Integer

NRep = InputBox("Enter the number of replications")

ReDim MyArray(NRep)

For i = 1 To NRep

MyArray(l) = 20 * i

Next

End Sub

Основной особенностью ошибок выполнения является их огромное многообразие, а сообщения о таких ошибках, выводимые программами Microsoft, как правило, весьма запутанные. Рассмотрите текущую процедуру, в которой специально нарушено правило выравнивания строк кода для скрытия ошибки. Сможете ли вы самостоятельно обнаружить ошибку?

SubTest()

DimcellAsRange

for Each cell In Range ("Al :D10 " )

If sell.Value > 10 Then

f With cell .Font

.Bold = True

.Italic = True

End if

Next

End Sub

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

Sub Testt()

Dim cell As Range

For Each cell In Range ( "Al: D10 " )

If cell.Value > 10 Then

With cell.Font

.Bold = True

.Italic= True

End With

EndIf

NextSub

Если вы запустите эту программу (первый вариант), будет выдано сообщение об ошибке, которое показано на рис. 3, а желтым цветом будет выделена строка с ключевыми словамиEndIf! Несложно догадаться, что такая информация об которая не дает никакой информации, мешает работе и в итоге вызывает ) отвращение. Конечно, анализ кода показывает, что ошибка не связана с конструкциейIf-EndIf; возникла она из-за проблем с конструкциейWith-EndНо ничего не подозревающему программисту предлагается не только искатьошибку, но и дается совет искать ее не там, где нужно. Чистой воды дезинформация! Таким образом, весьма осторожно относитесь к сообщениям об ошибках выполнения. Обычно такие сообщения указывают на "приблизительное" расположениеошибки, но не всегда определяют саму ошибку. Как несложно догадаться, щелчок на кнопке Справка (Help) в данном случае не приведет к отображению информации о решении проблемы.

Рис. 3. Сообщение об ошибке, не несущее полезной информации

При получении одного из таких сообщений программа перейдет в режим паузы т.е. выполнение программы приостанавливается. В режиме паузы выполняема! данный момент строка кода выделяется желтым цветом. Иногда можно использовать приложение в этом режиме и продолжить его работу, щелкнув на кнопке N Sub/UserForm на стандартной панели инструментов VBE (рис. 13.4). Но чаше продолжение выполнения программы просто невозможно. В таком случае щелкни на кнопке Reset, исправьте ошибку и повторно запустите программу. Обычно более предпочтительно перезапустить приложение. При каждом появлении сообщением невозможности выполнить какое-нибудь действие лучше всего перейти в VВЕ щелкнуть на кнопкеReset.

Логические ошибки

Третий распространенный типом ошибок — это логические ошибки. Они самые опасные, так как обычно вы не подозреваете, что ошибка существует. Программа запускается, выводит на экран или рабочий лист результат, и вы поздравляете себя завершением сложной и важной работы. Но если программа содержит логические ошибки, пусть даже одну "очень маленькую", то будет выведен неверный результат Программа может и не предложить сообщения, которое извещает об ошибке.

Ниже описан типичный пример такой ошибки. Необходимо подсчитать ерем значение чисел в столбце А (по 10 строку включительно), который показаврис. 13.5. Среднее значение должно отображаться на экране в окне сообщения. Н вильное среднее значение, подсчитанное с помощью функции Excel Avera зано в ячейкеAl2.

Приведенная ниже процедура AverageScoresне содержит синтаксическиеошибок и не приводит к ошибкам выполнения2. Если запустить это приложение на экране появится окно сообщения, показанное на рис. 13.6. Данное сообщение выведет неправильный результат! Можете самостоятельно обнаружить причину проблемы?

Sub AverageScores()

Dim ScoreRange As Range , cell As Range, Sum As Single

With Range ("Al")

Set ScoreRange = Range (.Offset(0, 0), .End(xlDown))

End With

For Each cell In ScoreRange

If IsNumeric(cell.Value) Then Sum = Sum +cell.value

Next

MsgBox "Средняя оценка: " & Sum / ScoreRange.Cells .Count

End Sub

Рис. 5. Числа, на основе которых необходимо рассчитать среднее значение

Рис..6. Отображение неправильного результата

2Конечно, мало кто захочет писать настолько сложный код для выполнения такой простой дачи. Этот код используется в данном случае только в демонстрационных целях

В данном коде на самом деле присутствует две проблемы. Первая и, возможно, самая важная, заключается в следующем: если в ячейке А12 не представить правильное значение, то вполне можно решить, что ответ в окне сообщения на самом деле правильный. Задумайтесь над этим — сколько программ, использующихся в реальных системах, содержат ошибки, о которых никто не подозревает? Возможна ли ситуация, при которой такие ошибки "вкрадываются" в гигантские программы, используемые для расчета налоговых издержек? Весьма пугающая мысль, неправда ли?

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

Рис. 7. Панель инструментов Debug

Воспользуемся этим методом для обнаружения логической ошибки в приложении. Запустите VBEи отследите значения, которые принимает переменнаяSumлюбые значения, которые эта переменная принимает в коде). Выберите в кодепе-1 ременнуюSum(установите в ней курсор) и щелкните на кнопкеWatch(Контрактное значение). Откроется окноWatchs, которое показано на рис.8. Это окно позволяет отслеживать значение, принимаемое переменнойSumв процессе выполнена программы. Обычно контрольные значения можно устанавливать для любого количества переменных.

Рис.8. Окно Watches

На этом этапе переменная Sum еще не определена, поэтому вместо ее значения указывается <out of context>. При построчном выполнении программы значение переменной Sum изменяется. Сначала установите курсор в любой части процедуры AverageScores, а затем несколько раз щелкните на кнопке Step into (Шаге заходом). (Также можно несколько раз нажать клавишу <F8>.) Это приведет к выполнению следующей (после строки с курсором) строки кода. Если строка изменяй значение переменной Sum, то обновленное значение отображается в окне Watches К моменту завершения цикла For Each окно Watches должно выглядеть так, од показано на рис. 9.

Рис. 9. Окно Watches после завершения цикла For Each

Если сложить числа, указанные в диапазоне А2 :А10 (рис..5), то сумма будет действительно равна 762. Это значит, что логическая ошибка не связана с подсчетом суммы. Еще одной возможностью совершения логической ошибки является неправильное деление значения переменной Sum для получения среднего значения. (Теперь заметили ошибку?) Внимательное изучение кода позволяет сделать вывод что диапазон ScoreRange содержит надпись в ячейке А1. Таким образом, оператор ScoreRange.Cells .Count возвращает 10, а не 9. Правильное среднее значение рассчитывается как 762/9, а не 762/10.

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

  • Точка останова. Разместите курсор в любой строке кода и щелкните на кнопке Toggle breakpoint (Точка останова). При этом слева от строки будет добавлена красная точка (если такая точка уже присутствует слева от строки, то щелчок на этой кнопке приведет к удалению точки остановки). Процедура будет выполняться до указанной строки, после чего остановится. В результате вы сможете проверить значения переменных или перейти в построчный режим выполнения процедуры. Обычно при щелчке на кнопке Run Sub/UserForm программа выполняется до ближайшей точки остановки. (Если следующая точка остановки просто не задана, то программа выполняется до конца.)

  • Шаг с обходом. При построчном выполнении процедуры можно столкнуться с ситуацией, когда в определенной строке находится оператор вызова другой процедуры. Если нет смысла построчно выполнять вызываемую процедуру (вы полностью уверены, что она не содержит ошибок), то щелкните на кнопке Step over (Шаг с обходом). Вызываемая процедура будет выполнена за один этап, не требуя построчного рассмотрения.

  • Шаге выходом. Аналогично, если при построчном выполнении процедуры вы считаете, что оставшуюся часть кода процедуры детально рассматривать не требуется, то щелкните на кнопке Step out (Шаг с выходом). Оставшаяся часть процедуры будет выполнена за один этап, а управление будет передано обратно в вызывающую процедуру. После этого можно продолжить построчное выполнение вызывающей процедуры.

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