Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Access 2007

.pdf
Скачиваний:
115
Добавлен:
11.05.2015
Размер:
23.5 Mб
Скачать

Глава 7

Основные хитрости, применяемые в запросах

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

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

— неотъемлемая часть набора рабочих средств любого настоящего фанатика запросов.

Вычисляемые поля

Когда вы начинали проектировать таблицы, то узнали, что в мире БД считается преступлением включение информации, основанной на данных другого поля или другой таблицы. Примером такой ошибки может служить таблица Products, в которой есть и поле Price (цена), и поле PriceWithTax (цена с включенным налогом). Проблема в том, что поле PriceWithTax вычисляется на основании поля Price. Хранение обоих полей — это избыточное расходование дискового пространства. Еще хуже, если налоговая ставка изменится, тогда вы останетесь с множеством записей, нуждающихся в обновлении, и возможностью появления противоречивых данных (например, когда цена с налогом окажется ниже цены без налога).

Даже зная, что не следует создавать поля, такие как PriceWithTax, иногда вы вынуждены отображать в программе Access вычисляемые данные. Прежде чем компания Boutique Fudge напечатает список для одного из своих наименее любимых розничных продавцов, она хочет установить для цены надбавку 10%. Для этого компании необходимо откорректировать информацию о цене до вывода данных на печать. Если продавец увидит более низкую цену без надбавки, компания будет вынуждена запросить ее.

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

241

Определение вычисляемого поля

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

ИмяВычисляемогоПоля: Выражение

Например, поле цены с налогом, PriceWithTax, определяется следующим образом: PriceWithTax: [Price] * 1.10

По сути, это выражение сообщает программе Access о том, что нужно взять поле Price и умножить его на 1.10 (что эквивалентно повышению цены на 10%). Access повторяет это вычисление для каждой записи, входящей в результаты запроса. Для того чтобы это вычисление выполнялось, в таблице должно существовать поле Price. Но вовсе необязательно отображать отдельно это поле в окне результатов запроса.

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

PriceWithTax: [Products].[Price] * 1.10

Такая синтаксическая запись нужна, если в ваш запрос включено несколько таблиц (например, использование запроса с операцией объединения (query join), описанного в разд. "Запросы и связанные таблицы" главы 6), и одно и то же поле есть в обеих таблицах. В этой ситуации следует применять полное имя для того, чтобы избежать неоднозначности. (Если не сделать этого, Access выдаст сообщение об ошибке при попытке выполнить запрос.)

Примечание

Пользователи предыдущих версий программы Access иногда вместо точки используют восклицательный знак (например, [Products] ! [ Price]), что равнозначно.

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

Теперь вы готовы к выполнению запроса. Когда вы выполните его, вычисляемые данные появятся рядом с другими столбцами (рис. 7.2). Если вы не довольны тем, что вычисляемые данные несколько иначе отформатированы — больше знаков в дробной части и нет символа валюты — это можно исправить с помощью округления (см. разд. "Применение функций " далее в этой главе) и форматирования (см.разд. "Форматирование чисел "далее в этой главе).

У вычисляемых полей есть одно ограничение — поскольку информация не сохраняется в вашей таблице, вы не можете их редактировать. Если нужно изменить цену, необходимо отредактировать базовое поле Price — попытка корректировать поле PriceWithTax привела бы программу Access в полное замешательство.

Примечание

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

242

Рис. 7.1. Этот запрос отображает два поля непосредственно из БД (ID и Name)

и вставляет вычисляемое поле PriceWithTax. Обычное поле Price, которое программа Access применяет для вычисления поля PriceWithTax, вообще не отображается

Рис. 7.2. Результаты запроса отображают поле PriceWithTax с надбавкой 10%. Главное состоит в том, что вычисляемая информация теперь доступна постоянно, несмотря на то, что она не хранится в БД. Попробуйте проверить это с помощью карманного калькулятора

243

На профессиональном уровне. Синхронизация запросов

Можно опробовать интересный прием. Выполните запрос ProductsWithTax и оставьте его открытым, отображающим свои результаты. Теперь откройте таблицу Products, содержащую реальные данные, и измените цену любого продукта. Вернитесь снова в запрос Products WithTax. Изменилось значение в этом запросе?

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

Есть лишь несколько исключений из этого правила.

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

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

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

Если несколько пользователей на разных компьютерах редактируют БД (как описано в главе 18), вы не увидите немедленно изменения, внесенные другими пользователями.

Для получения самых свежих результатов можно обновить отдельные записи или весь запрос целиком. Для обновления одной записи выберите Главная → Записи → Обновить → Обновить запись (Home Records Refresh Refresh Record). Для повторного выполнения запроса и полного обновления выберите Главная → Записи → Обновить → Обновить все (Home Records Refresh Refresh All). Это действие также выводит на экран любые новые записи и скрывает те записи, которые после внесения изменений больше не удовлетворяют вашим условиям отбора.

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

Всегда выбирайте уникальное имя. Выражение Price: [Price] * 1.10 создает циклическую ссылку, поскольку имя используемого вами поля такое же, как имя создаваемого поля. Программа Access не допускает подобных проделок.

Формируйте выражения из полей, чисел и математических операций. Наиболее распространенные вычисляемые поля содержат одно или несколько существующих полей или числовые константы и соединяет их друг с другом с помощью хорошо знакомых знаков математических операций, таких как сложение (+), вычитание (-), умножение (*) или деление (/).

Не удивляйтесь присутствию квадратных скобок. Выражение PriceWithTax: [Price] * 1.10 эквивалентно выражению PriceWithTax: Price * 1.10 (единственное отличие — квадратные скобки вокруг имени поля Price). Технически скобки нужны только,

244

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

Малоизвестная или недооцененная возможность. Переименование поля в запросе

Устали от длинных имен полей в окне результатов ваших запросов? Используя толькочто полученные знания, касающиеся выражений, можно безболезненно переименовать поле в окне результатов вашего запроса. Все что вам требуется — это вычисляемое поле. Хитрость заключается в создании (с помощью выражения) вычисляемого поля, совпадающего с одним из существующих полей и присвоении ему нового имени. Технически в этом поле не выполняются никакие вычисления, но оно все равно корректно действует. Далее приведен пример вычисляемого поля, которое переименовывает DateCustomerPlacedPurchaseOrder в Date: Date: DateCustomerPlacedPurchaseOrder Новое имя (в данном примере Date) называют псевдонимом (alias).

Используя этот прием, помните о том, что исходное иоле (в данном случае DateCustomerPlacedPurchaseOrder) не надо включать в ваш запрос. Нужная вам информация отображается в вычисляемом поле (Date).

Простая математическая обработка числовых полей

Многие вычисляемые поля полагаются на обычные арифметические операции. В табл. 7.1 представлен краткий обзор основных вариантов комбинирования чисел.

Таблица 7.1. Арифметические операции

Операция

Название

Пример

Результат

+

Сложение

1+1

2

 

 

 

 

-

Вычитание

1-1

0

 

Умножение

2*2

4

 

Возведение в степень

2^3

8

/

Деление

5/2

2.5

\

Деление нацело (возвращает наименьшее целое

5\2

2

 

число и отбрасывает остаток)

 

 

 

 

 

 

Mod

Остаток от деления (возвращает остаток,

5 Mod 2

1

 

полученный в результате деления нацело)

 

 

 

 

 

 

Для создания выражения можно использовать произвольное количество полей и операций. Рассмотрим таблицу Products с полем QuantityInStock (количество на складе), в котором записано количество единиц товара, находящихся в вашем хранилище. Для определения

245

стоимости данного товара, имеющегося у вас под рукой, введите следующее выражение, применяющее два поля:

ValueInStock: [UnitsInStock] * [Price]

Подсказка

При выполнении математической операции над полем может произойти сбой, если в поле пропущено значение. Для устранения этой проблемы вам необходима функция Nz ( ), описанная в разд. "Обработка пропущенных или неопределенных значений" далее в этой главе.

Поля с датами

Операции сложения и вычитания можно применять к полям, содержащим даты. (Можно применять и умножение, деление и все что угодно, но реального смысла такие значения иметь не будут.)

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

ExtendedDeadline: [DueDate] + 14

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

Используя операцию вычитания, можно найти число дней между двумя датами. Далее показано, как вычисляется период между временем помещения заказа и временем доставки: ShippingLag: [ShipDate] - [OrderDate]

Если доставка произошла через 12 дней после того, как сделан заказ, вы увидите значение 12.

Примечание

Поля типа Дата/время включают информацию о времени суток. В вычислениях данные о времени представляются как дробная часть числа. Если вы вычли одну дату из другой и получили число 12.25, оно представляет период 12 дней и 6 часов (поскольку 6 часов равно 25% суток).

Помните, что если вы хотите включить фиксированные даты в ваши запросы, их необходимо обрамлять символами # и использовать формат Месяц/День/Год (Month/Day/Year). Далее приведен пример, использующий такой подход для вычисления количества дней между датой своевременного предоставления задания (20 марта 2007 г.) и датой действительного его предоставления: LateDays: [DateSubmitted] - #03/20/07#

Положительное значение указывает на то, что значение в поле DateSubmitted больше (более поздняя дата), чем предельный срок сдачи — другими словами, студент опоздал. Значение 4 указывает, что студент на 4 дня задержался, в то время как -4 означает, что студент сдал работу на четыре дня раньше назначенного в расписании срока.

Порядок выполнения операций

Если о вашем выражении длинная строка вычислений, программа Access следует строгим правилам определения старшинства операций или, говоря математическим языком, учитывает,

246

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

1.Скобки (любые вычисления, заключенные в скобки, Access всегда выполняет первыми).

2.Проценты.

3.Возведение в степень.

4.Деление и умножение.

5.Сложение и вычитание.

Предположим, что вы хотите использовать поля QuantityInStock (количество на складе) и QuantityOnOrder (количество в заказах) для подсчета всех товаров, имеющихся в наличии и находящихся на пути к клиенту. Если вы не знаете правил старшинства операций, то можете сформировать следующее выражение:

TotalValue: [UnitsInStock] + [UnitsOnOrder] * [Price]

Проблема состоит в том, что программа Access перемножит поля QuantityOnOrder и Price и добавит полученное значение к значению ноля QuantityInStock. Для устранения этой оплошности нужно применить скобки следующим образом:

TotalValue: ([UnitsInStock] + [UnitsOnOrder]) * [Price]

Теперь поля QuantitylnStock и QuantityOnOrdeг суммируются, а затем умножаются на поле Price для получения общей суммы.

Подсказка

Вам нужно больше свободного места для набора длинного выражения? Можно расширить любой столбец в Конструкторе запросов для увеличения видимой зоны, но в случае сложных вычислений этого все равно не хватит. Лучше щелкнуть кнопкой мыши в области Поле и нажать сочетание клавиш <Shift>+<F2>. Это действие распахивает на экране диалоговое окно Область ввода (Zoom), отображающее все содержимое в большом текстовом поле, разделенном на столько строк, сколько вам нужно. Когда просмотр или редактирование выражения завершены, щелкните мышью кнопку ОК, чтобы закрыть окно и сохранить изменения, или кнопку Отмена для отказа от них.

Выражения с текстовыми значениями

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

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

Для слияния текста применяется оператор амперсанд (&). Далее показано, как создать поле FullName (ФИО), в котором собрана информация из полей FirstName и LastName:

FullName: [FirstName] & [LastName]

Это выражение выглядит достаточно корректным, но на самом деле у него есть один недостаток. Поскольку вы не вставили никаких пробелов, имя и фамилия в результате прижаты

247

друг к другу, например, так: BenJenks. Лучше слить три фрагмента текста: имя, пробел и фамилию. Вот исправленная версия: FullName: [FirstName] & " " & [LastName]

Приведенное выражение создаст значение: Ben Jenks. Можно также поменять местами имя и фамилию и отделить их запятой, если вы предпочитаете указывать фамилию первой (например, Jenks, Ben) для облегчения сортировки: FullName: [LastName] & ", " & [FirstName]

Примечание

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

Вы даже можете применять амперсанд для сцепления текста с числовыми значениями. Если вы хотите, чтобы слегка бесполезный текст "The price is" появлялся перед каждым значением цены, примените следующее вычисляемое поле:

Price: "The price is: " & [Price]

Функции запросов

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

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

Функции пригодятся для всех видов обработки данных в программе Access. Вы можете примять их в:

вычисляемых полях для включения данных в результаты ваших запросов;

условиях отбора для задания записей, отображаемых в запросе;

коде на языке Visual Basic, многоцелевой расширяемой системе для программы Access, с которой вы познакомитесь в части V.

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

Примечание

Функции — это встроенная часть версии языка SQL (см. разд. "Режим SQL" главы 6), применяемой в программе Access для обработки данных.

248

Применение функций

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

Для примера рассмотрим очень полезную функцию Round (), которая принимает число с дробной частью и убирает любые нежелательные позиции в дробной части. Эта функция — удобный способ приведения в порядок отображаемых значений вычисляемого поля. Вы оцените полезность функции Round (), если создадите выражение, подобное приведенному далее и вычисляющее цены, сниженные на 5%:

SalePrice: [Price] * 0.95

Примените это выражение к цене $43.97 и получите в результате 41.7715, что вряд ли будет выглядеть уместно на ценнике товара. Здесь пригодится функция Round (). Передайте ей неокругленное число и число знаков в дробной части, которое нужно сохранить:

SalePrice: Round([Price] * 0.95, 2)

Технически функции Round ( ) требуется две порции информации или два аргумента. Первый — это число, которое округляется (в данном случае это результат вычисления Price * 0. 95), а второй — количество цифр, которое вы хотите оставить справа от десятичной точки

(2). В результате получается значение, округленное до двух десятичных знаков, или 41.77.

Примечание

Большинству функций, подобных Round (), требуются два или три аргумента. Но некоторые функции могут принять гораздо больше, в то время, как нескольким функциям вообще не нужны аргументы

Часто задаваемый вопрос Банковское округление

Похоже, программа Access округляет числа неправильно. Как быть?

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

Разница между арифметическим и банковским округлением заключается в трактовке цифры 5. Поскольку число 21.985 находится точно в середине, между числами 21.98 и 21.99, не просто решить, что с ним делать. При постоянном округлении числа с 5 на конце до большего числа вносится систематическое отклонение в итоги и средние значения. Поскольку вы округляете до большего чаще, чем до меньшего, любые итоги или среднее, которые вы вычисляете, получаются чуть больше, чем следовало бы.

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

249

Число 21.985 округляется до меньшего числа 21.98, а число 21.995 — до большего, 22. Это не единственный способ борьбы с систематическим отклонением (можно решать случайным образом, когда округлять, а когда нет), но это общепринятая практика в бухгалтерских расчетах и статистике.

Вложенные функции

В вычисляемом поле или условии отбора можно применять несколько функций. Этот прием известен как вложенные функции: специальный термин, обозначающий вставку одной функции внутрь другой. Например, в программе Access есть встроенная функция определения абсолютного значения числа Abs ( ), преобразующая отрицательные числа в положительные (и оставляющая положительные числа без изменения). Далее приведен пример деления одного поля на другое и получения в результате заведомо положительного значения:

Speed: Abs ([DistanceTravelled] / [TimeTaken])

Если полученный результат нужно округлить, можно поместить целиком все выражение внутрь скобок функции Round ( ):

Speed: Round (Abs([DistanceTravelled] / [TimeTaken]), 2)

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

Speed: Abs(Round([DistanceTravelled] / [TimeTaken], 2) )

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

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

Построитель выражений

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

Примечание

В этой книге описана далеко не каждая функция {если бы это было так, вам пришлось бы, сидя над книгой, бороться со сном). Но в следующих разделах вы познакомитесь с наиболее полезными функциями для работы с числами, тестом и датами. Для поиска дополнительных функций используйте Построитель выражений (Expression Builder) Если же вы предпочитаете интерактивный режим обучения, проверьте информативный Web-pecypc www.techonthenet.com/access/functions.

250

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