Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 21.10.2020
Просмотров: 7914
Скачиваний: 25

Параметры
и SaleTax в приведенном выше примере объявлены та-
ким образом, что любые изменения их значений внутри процедуры CalculateSal-
esTax останутся в силе после ее завершения. Вряд ли вы предусматривали бы именно
такое развитие событий, поэтому семантическая правильность подобного кода остает-
ся под вопросом.
Язык Access VBA позволяет предпослать любому аргументу процедуры определен-
ное служебное
(обратитесь к общему описанию синтаксиса про-
цедур, приведенному выше), чтобы оговорить дополнительные требования и обеспе-
чить верную передачу смысла. Хотя применять
вовсе не обязательно,
в определенных обстоятельствах они дают возможность уточнить семантику кода и
уменьшить количество потенциальных ошибок (и время, которое придется провести в
"обществе" отладчика). Подробные сведения о
аргументов и приемах
их использования приведены в нескольких следующих разделах этой главы. Вы уви-
дите более надежные и верные варианты кода предыдущего примера.
ByVal
(передача параметра по значению)
применяют в тех случаях,
когда необходимо исключить возможность изменения значения аргумента процедуры
после ее завершения. Другими словами, после того как процедура будет выполнена,
переменная-аргумент сохранит первоначальное значение, которое было передано
процедуре в момент ее вызова.
Аргумент, помеченный
ByVal,
может
изменять свое значение в
процессе выполнения процедуры, но эти изменения носят временный характер. На
самом деле параметр, снабженный словом ByVal, получает и хранит
копию
переда-
ваемых данных. Только ее вы и сможете изменить, а оригинал останется нетронутым.
Внесем в код рассмотренной ранее процедуры исправления, позволяющие предохра-
нить содержимое аргументов от случайного искажения.
Global TotalSale As Double
Sub
ByVal SaleAmount As Double, ByVal SalesTax As
Double )
TotalSale = SaleAmount * (1 + SalesTax)
End Sub
Применяйте Квалификатор ByVal в тех случаях, когда необходимо гарантировать
сохранность содержимого конкретного аргумента процедуры после ее завершения.
Ничто не запрещает пользоваться аргументом по своему усмотрению внутри процеду-
ры, но по окончании ее выполнения все изменения, внесенные в содержимое аргу-
мента, будут утрачены. Чтобы проверить, как вы поняли смысл сказанного, рассмот-
рим следующий код.
Листинг
Пример
квалификатора ByVal в аргументах процедур
1:
2:
3:
4 :
5 :
6:
7 :
8:
9 :
11:
Sub TestByVal
А = 5
A
End Sub
ByVal A As Integer )
Sub CallFoo( )
Dim A As Integer
A = 10
Call
A )
MsgBox A
End Sub
8-й час. Декомпозиция задач
145

Если вы согласны с тем, что при выполнении строки 3 в окне сообщения
будет отображено число 5, а результат вызова процедуры
в
строке 10 — это число 10, тогда можно говорить о взаимопонимании.
ByRef
(передача параметра по ссылке)
уведомляет компилятор VBA
(и читателя программы) о том, что значение аргумента разрешается изменять внутри
процедуры с сохранением изменений после ее завершения. Приведем еще один ис-
правленный вариант процедуры CalculateSalesTax — сейчас нам удастся избежать
использования глобальной переменной TotalSale:
Sub
As Double,
SalesTax As
Double, ByRef TotalSale As Double )
TotalSale = Sale * (1 + SalesTax)
End Sub
Квалификатор ByRef указывает, что в процедуру передается адрес исходной пере-
менной, а не ее значение-копия. Поэтому результат изменения параметра не зависит от
того, где оно было совершено — внутри процедуры или за ее пределами. Применяйте
Квалификатор ByRef в тех случаях, когда процедуре должна быть предоставлена воз-
можность изменения данных, объявленных извне и переданных в качестве аргумента.
Квалификатор Optional
Квалификатор Optional
(необязательный аргумент)
позволяет создавать более гиб-
кие процедуры, учитывающие конкретные обстоятельства вызова. Для аргумента про-
цедуры, помеченного словом Optional, задавать значение необязательно. Этот
лификатор чрезвычайно удобен в тех ситуациях, когда в соответствии с условиями за-
дачи аргумент в большинстве случаев принимает одно заранее известное значение и
только изредка — какие-то другие.
Вернемся к нашему примеру, касающемуся расчета стоимости, и предположим,
что нам дополнительно необходимо учитывать зависимость ставки налогообложения
от места изготовления изделия. Если в большинстве случаев процедура должна вычис-
лять полную стоимость изделий, произведенных в штате Мичиган, снабдите аргумент
SalesTax
Optional и значением по умолчанию, соответствующим
ставке налогов штата Мичиган. Теперь пользователю не придется заботиться о явном
задании ставки, поскольку она заранее известна, а понадобится указывать ее только в
тех редких случаях, когда речь идет об изделиях, произведенных за пределами штата.
Исправленная версия процедуры представлена в тексте листинга 8.2.
Аргументы, снабженные квалификатором Optional, должны занимать
место в конце списка параметров процедуры, иначе компилятор VBA
выдаст сообщение об ошибке. /
Листинг 8.2. Пример использования
Optional
1:
2:
3:
4:
5:
6:
Sub
ByRef TotalSale As Double,
ByVal SaleAmount As Double,
Optional TaxPersent As Double
TotalSale = SaleAmount
End Sub
Sub
)
Dim SaleAmount As Double
.06 }
(1 + TaxPersent)
146
Часть III. Использование ресурсов Access

7: Dim TotalSale As Double
8:
= 100
9: Call
(
SaleAmount)
10: Dim
As Double
11: WashingtonSalesTax
.08
12:
Call
TotalSale, SaleAmount,
WashingtonSalesTax )
End Sub
Optional, используемый в строке заголовка процедуры
| CalculateTotalSale, позволяет упростить код программы, поскольку
наиболее часто используемое значение аргумента
— .06 — из-
вестно заранее. Обратите внимание, что процедура CalculateTotalSale
вызывается дважды — один раз с двумя параметрами (в строке 9), а дру-
гой — с тремя (в строке 12). Приемлемы оба варианта вызова.
Напомним — все аргументы с
Optional должны
располагаться в конце списка параметров процедуры.
Как строить функции
Функции
(еще одна именованная конструкция) очень схожи с процедурами и раз-
личаются только в одном аспекте — они могут возвращать значения определенного
типа. (Если вы не читали начало главы, рекомендуем сделать это сейчас.)
Ниже приведена информация о том, как задавать возвращаемый аргу-
мент и использовать его в операторах присваивания. Общий синтаксис
определения функции почти совпадает с правилами оформления проце-
дуры и отличается только началом (теперь вместо служебного слова Sub
следует задавать слово Function), суффиксом, указывающим тип воз-
вращаемого значения, и конструкцией завершающей строки:
Function
(
As Тип-
Данных,
] ) As ТипДанных
End Function
Напомним: при определении реальной функции вместо словосочетаний ИмяФунк-
ции и ИмяАргумента надлежит ввести четкие и запоминающиеся наименования
(идентификаторы), а параметры ТипДанных заменить соответствующими служебными
словами VBA, обозначающими допустимые типы данных. Символ многоточия означа-
ет, что разрешено задавать произвольное число аргументов.
Функции следует использовать в тех случаях, когда блок кода должен возвращать
результат определенного типа. Процедуру CalculateTotalSale листинга 8.2 можно
легко преобразовать в функцию — и решение задачи станет несколько более изящ-
ным. Взгляните на текст листинга 8.3.
Листинг 8.3. Пример определения и использования функции
1: Function CalculateTotalSale (
SaleAmount As Double,
Optional TaxPercent As Double = .06 ) As Double
2: CalculateTotalSale = SaleAmount * (1 + TaxPercent )
End Function
час. Декомпозиция задач
147

Sub Test ( )
Dim
As Double
Dim TotalSale As Double
SaleAmount = 100
TotalSale =
4
5
6
7
8
9
Dim
As Double
11: WashingtonSalesTax = .08
TotalSale =
WashingtonSalesTax )
13: End Sub
Изменения, внесенные нами в текст программы, служат цели пояснения
различий между процедурами и функциями. Код функции с прежним
именем — CalculateSalesTax — начинается со служебного слова Func-
tion и завершается им. Теперь вы можете не использовать параметр To-
talSale —
роль исполняет возвращаемый аргумент, имя которого
совпадает с названием функции (см. строку 2).
Думается, вы уже ощутили различия между процедурами и функциями.
В ходе дальнейшего изложения будем использовать термины
подпрограмма
и
функция
как синонимы, если это не станет противо-
речить контексту обсуждаемой темы.
Итак, функции весьма схожи с процедурами. Различие состоит в синтаксических
правилах оформления (вместо служебного слова Sub используется Function), конст-
рукции завершения строки заголовка, а также наличии оператора присваивания, в ле-
вой части которого употребляется идентификатор возвращаемого аргумента, совпа-
дающий с наименованием функции. В каких же случаях использовать процедуры, а в
каких — функции? Ответ на этот вопрос весьма прост. Обращайтесь к процедурам,
если вам не нужны возвращаемые значения. Впрочем, всегда можно безболезненно
изменить свое решение.
Заповеди программирования
Существует шесть известных заповедей программирования, которые необходимо
принимать во внимание при использовании процедур и функций. Истинность этих
эмпирических правил подтверждается десятилетиями развития теории и практики
программирования. Неукоснительно им следуя, вы сможете с чистой совестью и чув-
ством исполненного долга ежедневно покидать свой офис ровно в пять часов вечера.
Ниже об этих правилах — более подробно.
Заповедь
повторяющиеся строки
кода твоего в функции"
Наилучшая программа — маленькая программа (естественно, при прочих равных
условиях). Чтобы код работал лучше и выглядел более прозрачным, его должно быть
по возможности меньше. Если вы видите, что определенные строки программы по-
вторяются несколько раз, создайте на их основе функцию. Фрагмент кода, который
встречается в тексте программы только единожды, проще тестировать, изменять и
поддерживать в надлежащем состоянии.
С
кодом работать сложнее. При необходимости внесения исправ-
лений возрастает вероятность ошибок. Если, скажем, группа из пяти строк кода по-
Часть III. Использование ресурсов Access

вторяется в тексте программы двадцать раз, любое изменение в этой группе придется
воспроизвести именно двадцать раз. Если хотя бы в одном месте вы допустите ошиб-
ку, программа не достигнет поставленной цели. Подобного не случится при использо-
вании единой функции.
Заповедь 2: „Выражайся лаконично"
Старайтесь писать короткие функции. Короткие — не более пяти-десяти строк. В
большинстве случаев функции, объем которых превышает указанный предел, могут и
должны считаться слишком большими. Практическая реализация данного правила по-
требует от вас, вероятно, немалых усилий. Помните, код должен работать правиль-
но — это самое главное. Впрочем, достаточно важны и другие его характеристики —
например, стоимость сопровождения и возможность повторного применения. Так вот,
чем более короткими и простыми будут функции, тем легче с ними совладать, тем
ниже стоимость их сопровождения и выше вероятность повторного использования.
Заповедь 3: „Ограничивай число
аргументов твоих"
В самых лучших образцах функций используется всего лишь по несколько аргу-
ментов. Больше и не нужно, ведь функции просты. "Скромнее надо быть!" - этот
житейский постулат вполне справедлив даже в программировании.
В набросках черновика программы старайтесь добиться, чтобы она просто решала
поставленную задачу. Но во время второго, третьего и последующих сеансов правки
текста уделите внимание лаконичности и надежности кода, а также убедитесь, что все
параметры функций действительно нужны и используются по назначению.
Заповедь 4: „Проясняй мысль твою
посредством
Активно применяйте квалификаторы аргументов процедур и функций —
ByRef и Optional (мы говорили о них выше, в разделе "Определение типов аргумен-
тов"), чтобы ясно выразить свою мысль и довести ее до сведения компилятора. Воз-
можно, человек, читающий вашу программу, не сочтет целесообразным или возмож-
ным углубляться во все подобные тонкости, но компилятор должен это делать. Даже
если код уже подвергался отладке и работает, не поленитесь явно указать нужные
квалификаторы, чтобы до конца прояснить свой замысел.
Заповедь 5: „Обусловливай решения твои"
В практике программирования часто встречаются ситуации, когда гарантией
точных результатов служит выполнение некоторых условий относительно значений
переменных, наличия файлов и т.п. Автор программы выдвигает определенные тре-
бования, а ее пользователь обязан их удовлетворить. Каждое условие необходимо
снабжать комментариями и усиливать конструкциями, проверяющими его выпол-
нение. Если требование не выполнено, автор программы должен предусмотреть
адекватные действия.
8-й час. Декомпозиция задач 149