Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Access_2007.doc
Скачиваний:
257
Добавлен:
17.03.2015
Размер:
20.6 Mб
Скачать

Практические занятия для опытных пользователей. Применение пользовательских функций в запросах

После того как вы создали функцию, ее можно использовать в вашей БД для построения запросов или условий на значения. Единственное требование — ваша функция должна находиться в пользовательском модуле, который вы добавили (не в модуле формы) и в ее объявлении не должно быть слова Private. Если ваша функция соответствует ука­занным требованиям, вы можете вызывать ее так же легко, как любую встроенную функцию программы Access.

Можно создать, например, такой запрос с вычисляемым полем (при условии, что в него включены два поля, названные LengthOfRoom (длина комнаты) и WidthOfRoom (ширина комнаты) соответственно):

RoomArea: Area (LengthOfRoom, WidthOfRoom)

Или можно создать следующее условие на значение для таблицы:

Area(LengthOfRoom * WidthOfRoom) < 10000

См. в главе 7 дополнительные соображения по поводу применения функций в вычис­ляемых полях и в главе 4 дополнительную информацию об условиях на значения или правилах верификации. Если же вы хотите увидеть этот конкретный пример в действии, обратитесь к БД MyHouse, которая включена в примеры к данной главе.

Подытожим: функция

для проверки кредитных карт

Теперь, когда вы познакомились с языком Visual Basic, самое время подвести итог с по­мощью примера, демонстрирующего все, что вы узнали о VB (и даже немного больше).

В данном примере рассматривается пользовательская функция ValidateCard (допустимая карта), которая проверяет номер кредитной карты. Функция ValidateCard возвращает одно из двух значений: True (что означает допустимый номер карты) и False (что означает неверный номер).

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

На профессиональном уровне. Алгоритм Луна (Luhn Algorithm)

В функции ValidateCard применяется алгоритм, названный алгоритмом Луна, кото­рый разработал специалист компании IBM в 1960 гг. Алгоритм Луна действует, т. к. компании, выпускающие кредитные карты, следуют его правилам. Другими словами, они выпускают только такие номера, которые считаются допустимыми с точки зрения алгоритма Луна.

Полное объяснение алгоритма Луна можно найти на Web-странице http://en.wikipedia.org/wiki/Luhn_algorithm. Далее приведено описание его принципа действия в версии журнала "Reader's Digest".

  1. Удвойте каждую вторую цифру номера кредитной карты, начиная с последней цифры номера. Оставьте все цифры с четным2 номером неизменными. Например, номер 1111 превратится вномер2121.

  2. Если в процессе удвоения получается число большее 9, сложите две цифры полученного результата вместе и поставьте их на место исходной цифры. Например, номер 1166 превратится в номер 2136. Вторая от конца цифра 6 была удвоена (до 12) и цифры результата (1 и 2) сложили вместе (для получения 3).

  3. Сложите все цифры получившегося номера вместе. Если у вас в данный момент номер 2136, сложите вместе 2+1+3+6 (что даст 12).

  4. Если результат заканчивается 0 (или иначе, если он кратен 10), номер карты допустимый. В противном случае — нет.

Алгоритм Луна проверяет, может ли предоставленный вами номер быть номером реаль­ной кредитной карты. Но он делает только то, что делает. Этот алгоритм не может обна­ружить номер кредитной карты, технически приемлемый, но на самом деле не присво­енный никакому банковскому счету (и ясно, что не может определить финансовое положение владельца счета и наличие на счету требуемого для покупки лимита).

Далее приведен полный программный код функции ValidateCard. Все строки кода пронумерованы, поэтому вы можете разбить его на элементарные порции (построчные объ­яснения даются после кода):

1 Function ValidateCard(CardNumber As String)

' Это промежуточный итог (создаваемый с помощью алгоритма Луна)

  1. Dim SumOfDigits

  2. SumOfDigits = 0

' Эта переменная определяет, в какой вы находитесь позиции,

' нечетной или четной.

' Вы начинаете с нечетной позиции (1)

  1. Dim OddNumbered

  2. OddNumbered = True

2 В этом случае четные от начала номера, применяемого в качестве примера. — Пер.

6 Dim i

7 For i = Len(CardNumber) To 1 Step -1

8 Dim CurrentNumber

9 CurrentNumber = Mid(CardNumber, i, 1)

10 If OddNumbered = False Then

' Цифра удваивается

11 CurrentNumber = CurrentNumber * 2

12 If CurrentNumber >= 10 Then '

' Если результат состоит из двух цифр, они складываются.

' Это странная часть, поскольку нужно использовать

' функции преобразования строк

13 Dim NumText As String

14 NumText = CurrentNumber

15 CurrentNumber = Val(Left(NumText, 1)) +

16 Val(Right(NumText, 1))

17 End If

18 End If

' К промежуточному итогу добавляется полученное число

19 " SumOfDigits = SumOfDigits + CurrentNumber

‘Переход из нечетной позиции в четную или наоборот.

' Эта строка кода изменяет значение True на False или

' False на True

  1. OddNumbered = Not OddNumbered

  2. Next

' Если сумма кратна 10, номер допустимый

22 If SumOfDigits Mod 10 = 0 Then

23 ValidateCard = True

24 Else

25 ValidateCard = False

26 End If

27 End Function

Функция работает следующим образом.

  • В строке 1 объявляется функция. Обратите внимание на то, что у функции один параметр — текст с номером кредитной карты. Он явно определяется как строка с помощью оборота As String. Таким образом, вы избегаете ошибок, возникающих при попытке передать в функцию число.

  • В строках 2—3 создается переменная, хранящая в течение всего процесса обработки промежуточный итог.

  • В строках 4—5 создается переменная, которая следит за тем, в какой позиции номера вы находитесь, четной или нечетной, считая от конца номера.

  • В строках 6—7 начинается цикл For/Next. Этот цикл немного отличается от виденных вами ранее циклов, поскольку у него в конце есть выражение Step -1. Оно сообщает о том, что после каждого прохода цикла из счетчика вычитается 1 (в отличие от добавления 1 при стандартном поведении). Вы можете обрабатывать номер от конца к началу.

Примечание

В цикле применен еще один прием — нижнее граничное значение задается с помощью функ­ции Len, которая возвращает длину текстового фрагмента. Другими словами, если номер кре­дитной карты состоит из 11 цифр, этот код выполняется 11 раз (один раз для каждой цифры).

  • В строках 8—9 извлекается цифра в текущей позиции, на которую указывает счетчик цикла. Функция Mid позволяет вырезать одну цифру.

  • В строке 10 проверяется, находится ли полученная цифра в четной или нечетной позиции, считая от конца номера.

  • Строки 11—17 выполняются, только если позиция цифры не кратна двум, считая от конца номера. В этом случае ее следует удвоить (строка 11). Если получилось двузначное число, его цифры нужно сложить (строки 13—15).

  • В строке 19 текущее число добавляется к промежуточному итогу. Если вы находитесь в четной позиции, число не менялось. Если вы в нечетной позиции, число было удвоено и скомбинировано.

  • В строке 20 гарантируется переход из четной позиции в нечетную позицию (и обратно).

  • В строке 21 выполняется переход к строке 6 и повторение цикла для следующей цифры в номере кредитной карты.

  • В строках 22—26 проверяется окончательный итог. Если он кратен 10, номер допустимый. Для проверки применяется операция Mod, выполняющая деление и извлекающая остаток от деления нацело (Если остатка нет при делении числа на 10, вы знаете, что оно без проблем делится нацело.)

Может потребоваться некоторое время для того, чтобы разобраться в работе функции от начала до конца и выяснить точно, что происходит, но в конце концов все это относится к основным элементам языка VB, таким как условия, циклы и переменные. Если вы действи­тельно хотите изучить данный пример, его можно посмотреть в действии с помощью средств отладки.

После завершения создания функции, подобной ValidateCard, ее можно вызвать для проверки соответствия номера кредитной карты.

Далее приведен пример, реагирующий на ввод данных кредитной карты в текстовое по­ле, названное CardNumber:

Private Sub CardNumber_BeforeUpdate(Cancel As Integer)

If ValidateCard(CardNuraber) Then

MsgBox "Your card is valid," Else.

MsgBox "Your card is invalid. " & _

"Did you forget a number, or are you trying to cheat us?" Cancel = True

End If

End Sub

Для проверки выполните приведенный код и введите один из номеров ваших кредитных карт в поле CardNumber, как показано на рис. 17.3.

Рис. 17.3. Эта форма демонстрирует работу функции Validate Card в форме AddCreditCard (вставка кредитной карты) из БД Boutique Fudge . Когда бы ни менялось поле CardNumber, процедура проверяет его допустимость и отменяет изменения, если значение не приемлемо

Обработка сбойных ситуаций

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

возникают и случается это часто. Этот факт не должен пугать вас. В конце концов, одна из при­чин применения кода на языке Visual Basic вместо обычных макросов состоит в том, что вы можете с изяществом выявлять ошибки и реагировать на них.

Вы столкнетесь с двумя типами ошибок в вашем коде.

  • Ошибки. Это ошибки кодирования, которые вы вносите случайно. Обычно они обнаруживаются при тестировании вашей БД. (Если повезет, редактор Visual Basic заметит ошибку, как только вы введете ее, и затем выведет соответствующее предупреждающее сообщение.)

  • Непредвиденные ограничения. Эти ошибки возникают в определенных обстоятельствах, которые вы возможно не предусмотрели. Скажем, вы создаете две формы: Order и Order_Subform. Форма Order_Subform проектировалась для применения в качестве подчиненной формы в форме Order и содержит программный код, который обращается к элементам управления на форме Order. Если же кто-либо откроет непосредственно фор­му Order_Subform, форма Order окажется недоступной и этот программный код завер­шится аварийно.

Ваша задача, как добросовестного программиста, исправить все ошибки и обработать не­предвиденные ограничения наилучшим образом. Для выхода из затруднений Visual Basic предлагает два средства. Можно использовать отладку для диагностики и устранения не­обычных проблем и код обработки ошибок для выявления неожиданных проблем и опове­щения о них других пользователей.

Отладка

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

Подсказка

Настоящее преимущество отладки заключается в том, что она позволяет вам проверить ваши предположения. У каждого программиста есть собственные предположения о том, как работа­ет фрагмент кода. Однако если код делает именно то, чего вы ждали, у вас, вероятнее всего, нет ошибок. С помощью отладки можно точно найти место, где код делает что-то неожиданное — когда вычисление дает странный результат, условный оператор отправляет неверным путем, цикл повторяется лишний раз и т. д. Затем можно исправить ошибку.

Самый легкий способ отладки — установка точек прерывания или останова, специально­го маркера, сообщающего программе Access о том, где вы хотите начать отладку. Когда Ac­cess достигает строки кода с точкой останова, программа приостанавливает выполнение ко­да. Затем она позволяет вам выполнять код с заданной вами скоростью, поочередно одну строку кода за другой.

Точки останова применяют следующим образом.

1. Найдите первую строку кода, которую хотите отладить.

Если нужно проверить подпрограмму целиком, начните с оператора Sub или Function. Если вы хотите проверить конкретную часть кода, перейдите к ней.

2. Щелкните слева кнопкой мыши для установки точки останова в этой строке (рис. 17.4). Каждая точка останова — это сигнал программе Access о месте начала отладки.

В некоторых строках кода нельзя поместить точки останова. Эти строки не содержат вы­полняемого кода, строки с пробелами, комментарии и объявления переменных. Все ос­тальные строки — поле для игры по правилам.

Рис. 17.4. Все точки останова выглядят как кружки красного цвета. Удалить точку останова можно, щелкнув ее кнопкой мыши. В данном примере точка останова (обведена) помещается вначале функции ValidateCard

Примечание

Когда вы закроете вашу БД и откроете ее позже, все точки останова исчезнут.

3. Запустите ваш код.

Вы можете начать выполнять код обычным образом. Если вы отлаживаете обработчик события для нажатия кнопки, откройте соответствующую форму и затем щелкните кнопку мышью.

Когда программа Access достигнет точки останова, она приостановит выполнение и пе­реключится в режим прерывания (break mode). Все в вашем приложении замрет.

В режиме прерывания у вас есть несколько вариантов.

Можно выполнять код пошагово. Это означает, что вы выполняете по одному оператору, останавливаясь после каждого из них. Для опробования нажмите клавишу <F8>. Это действие выполняет текущий оператор (который выделен желтой стрелкой), переходит к следующему выполняемому оператору и снова останавливается (рис. 17.5). Вы можете

продолжать, сколько захотите, нажимая клавишу <F8> для выполнения каждой строки кода.

Подсказка

Пошаговая отладка позволяет следить за работой кода. Если применить ее к функции ValidateCard, описанной ранее, вы увидите, как программа Access выполняет цикл не­сколько раз и как она переходит к разным секциям условного блока в зависимости от того, об­рабатывается цифра в нечетной или четной позициях.

Рис. 17.5.В данном примере точка останова останавливает выполнение кода в начале функции ValidationCard. Затем пользователь, проводящий отладку, нажимает несколько раз клавишу <F8> для продвижения по коду. В данный момент код приостановлен в начале цикла For/Next (обведено)

Можно прекратить выполнение кода. Нажмите кнопку Stop (остановить) (она выглядит как квадрат) на панели инструментов редактора Visual Basic для завершения выполне­ния вашего кода.

Можно внести изменения. Если вы нашли ошибку, можно исправить ваш код и затем продолжить выполнение с внесенными изменениями. Конечно, существуют определен­ные типы корректировок, которые заставляют программу Access остановить отладку. Ес­ли вы внесли именно такое изменение, то увидите окно сообщения, предупреждающее о том, что "This action will reset your project" ("Это действие сбрасывает ваш проект"). Если щелкнуть мышью кнопку ОК, программа Access остановит выполнение вашего кода, как будто вы щелкнули мышью кнопку Stop (остановить) на панели инструментов редакто­ра Visual Basic.

  • Можно просмотреть, что хранится в переменной. Для этого просто проведите указате­лем мыши поверх имени переменной где-нибудь в вашем коде (рис. 17.6).

Рис. 17.6. Проведя указателем мыши поверх имени переменной CurrentNumber, можно увидеть, что в данный момент она хранит число 4. Можно провести указателем мыши поверх имен переменных в любой строке кода, кроме текущей строки. Если применяется клавиша <F8> для пошагового прохода кода, можно следить за изменением значения по мере выполнения операций

Можно возобновить выполнение в нормальном режиме. Если вы обнаружили источник проблемы и не хотите продолжать отладку, просто нажмите клавишу <F5> (или щелк­ните мышью кнопку Play (выполнить) на панели инструментов редактора Visual Basic). Программа Access выполнит текущую строку и затем продолжит выполнение быстрым способом (по крайней мере, до встречи с очередной точкой останова).

Подсказка

Вы можете выполнить ловкий трюк с желтой стрелкой. Ее можно использовать для выполнения строк, расположенных в другом месте кода. Просто перетащите стрелку с нажатой кнопкой мыши к строке, которую хотите выполнить следующей, и затем нажмите клавишу <F5> для вы­хода из режима отладки и возобновления выполнения кода в обычном режиме.

У редактора Visual Basic есть множество других средств отладки. Однако точек останова вполне достаточно для начала исследования того, что делается под капотом, когда выполня­ется ваш код.

Обработка ошибок

Некоторые ошибки возникают не по вашей вине. Быть может, вы пытаетесь выполнить за­дачу с данными, которые получаете от кого-то, и эти данные некорректны. Представьте себе, что произойдет, если кто-нибудь вызовет функцию ValidateCard и передаст в нее номер кредитной карты, содержащий буквы и знаки пунктуации!

Несмотря на то, что такие ошибки могут произойти в результате чьей-то небрежности, именно вы должны обработать их наилучшим образом. Следует объяснить возникшую про­блему с помощью понятного окна сообщения и закончить текущую задачу (или перейти к следующему шагу). Вы можете позаботиться об этом, добавив код обработки ошибок.

Подсказка

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

Обычно, когда программа Access обнаруживает ошибку, она переходит к коду, вызвав­шему проблему, переключается в режим прерывания и отображает сообщение об ошибке. Такое поведение полезно, если вы планируете устранять проблему, но оно лишь травмирует обычных пользователей, которые, возможно, работают с вашей БД. Мало того, что они ни­когда раньше не видели программного кода, они окажутся в большой опасности, попытав­шись исправить его, и создадут новые проблемы.

Вместо этого вам нужен способ обработки ошибки средствами программного кода. В языке Visual Basic есть специальный оператор, сообщающий программе Access о том, как поступать с ошибками. Это оператор On Error.

Оператор On Error предоставляет несколько вариантов. Можно заставить программу Access пропустить ошибки и попытаться выполнить очередную строку кода, например, сле­дующим образом:

On Error Resume Next

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

Можно также заставить программу Access перейти в конкретное место кода. Далее при­веден пример.

On Error Goto ErrorHandlingCode

В данном примере программа Access переходит к разделу, названному ErrorHandlingCode, как только она обнаруживает какую-либо проблему. Вы должны обо­значить этот раздел, указав в отдельной строке его имя и следом за ним вставив двоеточие (:), например, так:

ErrorHandlingCode:

' Если возникла ошибка, Access начинает выполнять ваш код с этой точки

Очень легко понять, как действует система обработки ошибок, если рассмотреть ее ис­пользование на примере функции ValidateCard:

Function ValidateCard(CardNumber As String)

On Error Goto ErrorHandlingCode

' Здесь расположен код, реализующий алгоритм Луна

Exit Function

ErrorHandlingCode:

MsgBox "Oops. Did your credit card number have letters?"

ValidateCard = False

End Function

Перечислим несколько важных деталей. Во-первых, оператор On Error помещается в cамом начале программного кода процедуры, поэтому вы можете обнаружить ошибки, возникшие в любом месте последующего кода. Во-вторых, обратите внимание на то, что после ого, как закончен код проверки номера, процедуру завершает оператор Exit Function. Этот оператор не дает программе Access попасть в следующий далее код обработки ошибок, если никакой ошибки не произошло. Наконец, код обработки ошибок выводит окно сообщения, в котором сообщается о нарушении естественного хода событий и возвращается результат, ясно обозначающий проблему. Чаще всего разработчики именно так обрабатывают ошибки. Только помните об обязательном использовании оператора Exit Sub или Exit Function, чтобы избежать случайного выполнения кода обработки ошибок.

Примечание

Как было указано ранее, пользователь, применяющий форму AddCreditCard, может получить два типа сообщений об ошибке — одно, объясняющее проблему, связанную с включением в номер карты букв и знаков пунктуации, и второе, констатирующее очевидный факт недопусти­мости номера. Если это сообщение кажется ненужным наказанием, вы можете перенести код обработки ошибок из функции ValidateCard в обработчик события При обновлении (On Update), с которым он на самом деле связан. В этом случае в обработчике события При об­новлении (On Update) можно выбрать точный способ решения проблемы. Для того чтобы уви­деть преобразованный код, посмотрите загружаемые из Интернета примеры к данной главе.

У вас есть еще только один вариант обработки ошибок. Можно заставить программу Ac­cess немедленно остановить выполнение и перейти в режим отладки с помощью следующего оператора:

On Error Goto 0

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

Углубленное рассмотрение объектов

В жизни любого программиста Access наступает момент, когда вы осознаете, что знаете дос­таточно о языке VB, чтобы сводить концы с концами. С этого момента вы будете проводить большую часть времени, изучая различные объекты, а это гораздо более трудоемкая задача.

В программе Access есть несколько десятков встроенных объектов, которые собранные вместе формируют то, что программисты называют объектной моделью. Наряду с объектами элементов управления и форм, которые вы хорошо знаете, в программе есть объекты, пред­ставляющие запросы, проекты, отчеты, смарт-теги, принтеры и многое другое. Вы не сможе­те познакомиться со всеми этими объектами в одной главе. Но даже если бы могли, то обнаружили бы, что многие из них вам просто не интересны. Однако следует знать достаточно для того, чтобы найти нужные вам средства, когда принимаетесь за особенно трудную зада­чу на языке VB.

Вы можете изучить объектную модель программы Access несколькими способами:

  • воспользоваться справочной системой программы Access (см. указания по поиску нужной информации в разд. "Применение объектов" главы 16);

  • использовать интерактивное руководство по языку VBA (Visual Basic for Applications), предоставляемое корпорацией Microsoft (перейдите на страницу http://msdn.microsoft.com/office/reference/vba).

Даже если вы освоили раскидистую объектную модель программыAccess, за ее предела­ми остается еще много дополнительных объектов. Если же вы обладатель черного пояса как VB-программист, то можете выбрать вариант создания собственных объектов. Если нет, возможно, вы решите применить какой-нибудь компонент, предоставляющий еще больше объектов для работы.

Примечание

На языке программистов компонент — это просто файл, содержащий некоторые объекты, ко­торые можно использовать в вашем программном-коде. В файле acedao.dll есть объекты, ко­торые можно применять для непосредственного взаимодействия с вашей БД (см. разд. "Обновление единиц наличного запаса" далее в этой главе).

Рис. 17.7. Для добавления ссылки на компонент, который хотите использовать, найдите его в списке и затем установите флажок, расположенный рядом с ним. Компоненты, на которые есть ссылки в данный момент, приведены в верхней части списка. Здесь показаны объекты, на которые автоматически устанавливаются ссылки в каждой БД, — объекты, встроенные в язык Visual Basic и поставляемые вместе с программой Access, и объекты доступа к данным, которые можно применять для непосредственного чтения и редактирования БД

Позже в этой главе вы узнаете, как использовать DAO (Data Access Objects, объекты дос­тупа к данным) для взаимодействия с вашей БД. Технология DAO — настолько популярная составляющая программирования в Access, что большинство считают эту библиотеку встро­енной частью объектной модели Access. Однако технически DAO состоит из набора объектов,

предоставляемых отдельным компонентом, поддерживаемым программой Access. Мно­жество дополнительных компонентов ждут, чтобы вы нашли их.

Для применения нового компонента необходимо добавить ссылку на него в вашу БД. Для этого в меню редактора Visual Basic выберите последовательность команд ToolsReferences (Сервис Ссылки). Вы увидите диалоговое окно References, показанное на рис. 17.7.

Проблема диалогового окна References заключается в том, что вам нужно точно знать, какой компонент вы хотите использовать. Список Available References (доступные ссылки) полон компонентов со звучными именами, которые не предназначены для использования в программе Access и не будут корректно работать с вашим программным кодом. Среди ком­понентов, которыми можно воспользоваться, есть компоненты Microsoft, позволяющие взаимодействовать с другими приложениями пакета Office. Но, самостоятельно экспери­ментируя, вы не многого добьетесь. Следует найти пример кода в Интернете или в справоч­ной системе программы Access.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]