Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 21.10.2020

Просмотров: 7914

Скачиваний: 25

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Параметры

 и 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


background image

Если вы согласны с тем, что при выполнении строки 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


background image

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


background image

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


background image

вторяется в тексте программы двадцать раз, любое изменение в этой группе придется

воспроизвести именно двадцать раз. Если хотя бы в одном месте вы допустите ошиб-

ку, программа не достигнет поставленной цели. Подобного не случится при использо-

вании единой функции.

Заповедь 2: „Выражайся лаконично"

Старайтесь писать короткие функции. Короткие — не более пяти-десяти строк. В

большинстве случаев функции, объем которых превышает указанный предел, могут и

должны считаться слишком большими. Практическая реализация данного правила по-

требует от вас, вероятно, немалых усилий. Помните, код должен работать правиль-

но — это самое главное. Впрочем, достаточно важны и другие его характеристики —
например, стоимость сопровождения и возможность повторного применения. Так вот,

чем более короткими и простыми будут функции, тем легче с ними совладать, тем

ниже стоимость их сопровождения и выше вероятность повторного использования.

Заповедь 3: „Ограничивай число
аргументов твоих"

В самых лучших образцах функций используется всего лишь по несколько аргу-

ментов. Больше и не нужно, ведь функции просты. "Скромнее надо быть!" - этот

житейский постулат вполне справедлив даже в программировании.

В набросках черновика программы старайтесь добиться, чтобы она просто решала

поставленную задачу. Но во время второго, третьего и последующих сеансов правки

текста уделите внимание лаконичности и надежности кода, а также убедитесь, что все

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

Заповедь 4: „Проясняй мысль твою

посредством

Активно применяйте квалификаторы аргументов процедур и функций —

ByRef и Optional (мы говорили о них выше, в разделе "Определение типов аргумен-
тов"), чтобы ясно выразить свою мысль и довести ее до сведения компилятора. Воз-

можно, человек, читающий вашу программу, не сочтет целесообразным или возмож-

ным углубляться во все подобные тонкости, но компилятор должен это делать. Даже

если код уже подвергался отладке и работает, не поленитесь явно указать нужные

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

Заповедь 5: „Обусловливай решения твои"

В практике программирования часто встречаются ситуации, когда гарантией

точных результатов служит выполнение некоторых условий относительно значений

переменных, наличия файлов и т.п. Автор программы выдвигает определенные тре-

бования, а ее пользователь обязан их удовлетворить. Каждое условие необходимо

снабжать комментариями и усиливать конструкциями, проверяющими его выпол-

нение. Если требование не выполнено, автор программы должен предусмотреть

адекватные действия.

8-й час. Декомпозиция задач 149