15. Основы отладки программ.В этом разделе Вы познакомитесь с понятием отладки и приведете свою программу в рабочий вид. Кроме того, Вы создадите собственную процедуру. Приготовьтесь к работе, перейдите в окно кода формы frmSheet, в обработчик события txtSheet_Change (как помните, здесь мы закончили работу накануне).
Это – точка останова (BreakPoint), при выполнении кода программа остановится на этой строке и Вы сможете произвести некоторые отладочные действия.
Запустите программу, откройте окно дневника, нажмите на кнопку « Страничка». Как видите, программа остановилась при выполнении события Change, хотя мы еще не успели изменить текст! Дело в том, что событие Change происходит и при загрузке текстового поля (ведь в нем появляется текст, значит – содержимое текстового поля изменяется). Подобные ситуации могут встречаться в процессе вашей работы, особенно вначале, когда вы еще недостаточно умелы. При этом и помогают средства отладки, самой полезное из которых – точки останова.
Как же нам выйти из ситуации? Следует, чтобы при первом запуске формы флаг не устанавливался, но устанавливался впоследствии. Это делается так (исправьте код обработчика события): Private Sub txtSheet_Change() Static boolFirst As BooleanIf boolFirst = False ThenboolFirst = TrueExit SubEnd IfboolChange = True End Sub Первая строка: Static boolFirst As Boolean Слово Static(Статический) используется при объявлении так называемых статических переменных. Эти переменные сохраняют свое значение в промежутках между вызовами процедуры - в отличие от обычных переменных, которые всегда создаются заново при каждом обращении к процедуре. При создании формы происходит автоматическая инициализация переменных, в т. ч. переменной boolFirst, по умолчанию она получает значение False (старайтесь не полагаться на автоматическую инициализацию, проводимую VB, но здесь у нас нет выхода).
If boolFirst = False Then boolFirst = TrueExit Sub End If
Теперь в начале обработчика события выгрузки формы-странички проверяйте значение переменной boolChange, и, если она равна True, производите действия для работы с БД. Действия с коллекцией форм-страничек выполняются всегда (т.к. надо удалить страничку с экрана, и, значит, из коллекции страничек). Private Sub Form_Unload(Cancel As Integer) Dim varPosition On Error Resume Next ‘действия при изменении содержимого странички If boolChange = True Then With frmDiary.datPrimaryRS.RecordsetvarPosition = .AbsolutePosition.MoveLast.MoveFirstDo Until .EOFIf frmDiary.datPrimaryRS.Recordset ("Dates") = Me.Caption ThenfrmDiary.datPrimaryRS.Recordset ("Note") = Me.txtSheet.Text.AbsolutePosition = varPositionExit DoEnd If.MoveNextLoopEnd With End If ‘действия для удаления странички из коллекции For Each NewSheet In colSheets If NewSheet.Caption = Me.Caption ThencolSheets.Remove Me.CaptionExit ForEnd If Next NewSheet End Sub Как видите, обработчик получился громоздкий. К тому же, он состоит из двух независимых частей. Безусловно, вы можете оставить как есть, но профессионально будет выполнить разбиение процедуры обработчика на две части. Заодно вы познакомитесь с созданием собственных процедур. Для создания процедур используется специальное средство VB. Мы уже неоднократно использовали понятие процедуры без определения ее.
Приготовьтесь к работе. Откройте окно кода формы frmDiary.
Появится окно Add Procedure: Строка Name – для ввода имени процедуры, переключатели группы Type (Тип) определяют тип создаваемого блока: Sub (Процедура), Function (Функция), Property (Свойство), Event (Событие). Переключатели группы Scope (Область Видимости) определяют область видимости процедуры. В поле Name введите имя будущей процедуры RefreshDB (ОбновитьБД).
Область видимости Private для процедуры означает, что обратиться к этой процедуре можно будет только из модуля, в котором она находится. Щелкните OK. Как видите, появилась заготовка процедуры: Private Sub RefreshDB()
End Sub Конечно, это можно было сделать и вручную. Но свойства Property и события Event удобнее создавать, используя эту возможность VB. Перенесите часть кода из обработчика события Form_Unload в эту процедуру, чтобы она приняла вид: Private Sub RefreshDB() Dim varPosition With frmDiary.datPrimaryRS.Recordset varPosition = .AbsolutePosition.MoveLast.MoveFirstDo Until .EOFIf frmDiary.datPrimaryRS.Recordset ("Dates") = Me.Caption ThenfrmDiary.datPrimaryRS.Recordset ("Note") = Me.txtSheet.Text.AbsolutePosition = varPositionExit DoEnd If.MoveNextLoop End With End Sub Соответственно, удалите этот код из обработчика события. А на месте этого кода в обработчике выгрузки формы просто вызовите созданную процедуру: Private Sub Form_Unload(Cancel As Integer) On Error Resume Next If boolChange = True Then ‘вот оно!RefreshDB End If For Each NewSheet In colSheets If NewSheet.Caption = Me.Caption ThencolSheets.Remove Me.CaptionExit ForEnd If Next NewSheet End Sub Как видите, код еще более упростился. Взгляните на участок: If boolChange = True Then RefreshDB End If После проверки условия происходит лишь одно действие. Этот участок можно еще более упростить (сделайте это): If boolChange = True Then RefreshDB Сохраните проект и испытайте программу. У вас может возникнуть вопрос: «Мой компьютер достаточно мощный, и, даже при обязательном сохранении всех страничек я не замечаю разницы в производительности. К чему возиться со всеми этими проверками?» Отлично. Заменим совсем немного кода и получим практическую пользу из проверки. Замените строку If boolChange = True Then RefreshDB на блок Dim varAnswer If boolChange = True Then varAnswer = MsgBox("Текст странички изменен." _& vbCrLf & "Сохранить его?", _vbYesNoCancel Or vbQuestion, _"Закрытие странички")If varAnswer = vbYes ThenRefreshDBElseIf varAnswer = vbCancel ThenCancel = 1Exit Sub End If End If Если значение флага boolChange равно True, то мы начинаем довольно сложный блок проверки, определяющий, следует ли сохранять сделанные изменения. В начале этого блока мы объявляем вспомогательную переменную varAnswer. Затем вызывается функция MsgBox.
Не забудьте впоследствии поэкспериментировать с этими значениями, по очереди подставляя их вместо указанных.
Возвращаемое функцией MsgBox значение зависит от второго параметра.
Понятие «параметр» мы также использовали без пояснения, что же это такое.
Параметры, как частный случай переменной, имеют те же типы, что и переменная. Объявлять типы параметров надо обязательно. Общий синтаксис параметров: Sub MySub (par1 As Long, par2 As String) То есть, список параметров заключается в скобки и идет за именем процедуры. Объявления параметров разделяются запятыми. При вызове этой процедуры параметры будут переданы ей и могут использоваться в работе самой процедуры. Параметр может изменяться в процессе работы процедуры, а по завершению вызывающий код может определять значения изменившихся параметров – это называется «возврат значений в параметрах». Далее идет блок проверки значения, возвращенного функцией: If varAnswer = vbYes Then RefreshDB ElseIf varAnswer = vbCancel Then Cancel = 1Exit Sub End If
Заметьте также, что в коде один блок If... Then находится внутри другого. Это называется вложенностью блоков. Позволяется делать так с блоками циклов и проверки условий. Процедуру вкладывать в другую процедуру нельзя! Запустите программу. К сожалению, в программе осталась еще одна неприятная особенность. В поле « Дата» формы дневника вы можете ввести повторяющееся значение даты, и это приведет к ошибке. Для устранения ее вам придется :
Все эти операции мы уже делали. При этом можно использовать обработчик события текстового поля LostFocus(ПотеряФокуса), возникающего при переходе к другому контролу на форме (или к самой форме). Эти исправления предоставляется сделать Вам самостоятельно, как «выпускной экзамен» нашего курса. Поверьте, в настоящей книге есть информация, требуемая для этого. Удачи! Вопросы
Задания
|