Руководство пользователя altAwin:Дизайнер отчётов

Материал из AltecDocs
Перейти к:навигация, поиск
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.

Введение

В процессе работы постоянно необходимо выводить различную информацию на печать. Для этого в дистрибутиве altAwin поставляется набор отчётных документов для работы фирмы-производителя. Документы, как правило, формируются после расчёта изделия. Однако на любом производстве есть своя специфика работы. В случае если стандартные отчёты вам по каким-либо причинам не подходят, можно отредактировать уже существующие отчёты или сформировать новые. Для этого в составе altAwin поставляется дизайнер отчётов FastReport. В данном руководстве даются только общие сведения о методике создания отчётов, а также описываются специфичные для altAwin моменты. Более полную информацию можно получить на сайте FastReport’a по адресу [1]

Соглашения

В табл. «Соглашения данного руководства» сведены все обозначения, используемые в данном руководстве.

Таблица 0.0. Соглашения данного руководства

Стиль Описание
Отчёт Этим шрифтом обозначаются названия кнопок, команд меню, поля и заполняемые значения, названия окон, а также большинство элементов интерфейса.
qryOrders Таким шрифтом выводится содержимое объектов и код, который выполняется при формировании отчёта.
IconWarning.png Так выделяются моменты, на которые следует обратить особое внимание. Игнорирование указанных сведений может сильно осложнить работу с программой.

Работа с компонентом FastReport

Для работы с отчётами в altAwin используется компонент FastReport.

В меню ФайлОтчёт приведены названия стандартных отчётов, поставляемых с altAwin и доступных в текущем разделе altAwin. Чтобы сформировать отчёт, вызовите пункт меню с названием отчёта. Компонент FastReport запустит выполнение шаблона, а затем перейдет в режим предпросмотра и покажет готовый отчёт. Чтобы просмотреть ранее сохраненный готовый отчёт, воспользуйтесь командой Открыть отчёт. Для запуска всех отчётов в определённой папке требуется выполнить щелчок мышью по этой папке, удерживая клавишу Shift.

Также возможно редактирование уже сформированного отчёта. Для этого воспользуйтесь командой Редактировать страницу из меню Отчёт или контекстного меню. Произведенные изменения будут действовать только для уже сформированного документа и не затронут шаблон отчёта.

Для создания нового шаблона отчёта вам необходимо выполнить команду Дизайнер из меню Документы в программе altAwin.

Интерфейс

При вызове дизайнера отчётов откроется окно Дизайнер (см. рис. «Главное окно программы»).

Рис. Главное окно программы


Панель «Стандартная»

На данной панели располагаются кнопки управления объектами и документом в целом.

Рис. Панель «Стандартная»


Кнопки управления шаблоном (Создать, Открыть, Сохранить) и кнопки редактирования объектов (Копировать, Вырезать, Отменить и пр.) имеют тот же смысл, что и в большинстве приложений в операционной системе Windows. В табл. «Кнопки панели «Стандартная»» представлены дополнительные кнопки для управления отчётом.

Таблица 0.0. Кнопки панели «Стандартная»

Кнопка Название Назначение
Intro panel instruments preview.png Предварительный просмотр Выполняет отчёт и переводит дизайнер в режим предпросмотра готового отчёта.
Intro panel instruments newpage.png Добавить страницу в отчёт Добавление в шаблон листа отчёта.
Intro panel instruments add dialog.png Добавить форму в отчёт Добавление в шаблон диалоговой формы.
Intro panel instruments delpage.png Удалить страницу Удаление из шаблона страницы (как листа, так и диалогофой формы)
Intro panel instruments options.png Настройки страницы Вызов диалога настройки параметров текущего листа отчёта.
Intro panel instruments variables.png Переменные Вызов списка переменных и функций в отчёте.
Intro panel instruments group.png Группировать Объединить выделенные объекты в одну группу.
Intro panel instruments selectall.png Разгруппировать Разбить группу на составляющие.
Intro panel instruments coords.png Показывать сетку Включение/выключение координатной сетки на листе и диалоговой форме.
Intro panel instruments gravity.png Выравнивать объекты по сетке При включенной опции добавляемые объекты располагаются вблизи узлов координатной сетки.
Intro panel instruments sizecoords.png Расположить объекты по сетке Выравнивание границ выделенных объектов по сетке.

Панель «Текст»

Данная панель предназначена для настройки атрибутов текста объектовизменить: атрибуты текста.

Рис. Панель «Текст»


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

Панель «Прямоугольник»

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

Рис. Панель «Прямоугольник»


С помощью кнопок, расположенных на панели, вы можете включить отображение той или иной границы объекта, указать толщину и цвет рамки, а также указать цвет заливки объектаобъект: оформление границизменить: границы объекта.

Объекты

Справа от листа расположена панель объектов, на которой расположены объекты, добавляемые в отчёт.

В зависимости от вида страницы, с которой вы работаете в данный момент, окно Объекты имеет разный вид. Подробнее об объектах и их свойствах см. раздел «Работа с шаблонами».

объект: добавление; добавить: объектОбъекты можно добавлять на лист шаблона или диалоговую форму. Для этого нажмите на кнопку на панели левой кнопкой мыши, затем поместите курсор мыши на лист шаблона или диалоговую форму в том месте, куда вы хотите поместить объект и нажмите ещё раз левую кнопку мыши.

Инспектор объектов

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

Инспектор объектов можно скрыть или показать. Для этого используйте команду Инспектор из меню ВидПанели инструментов.

Дерево отчета

Данная панель отображает структуру отчёта. Корень дерева — это узел Report, дочерними узлами которого являются листы и диалоговые формы. Чтобы выбрать какой-либо элемент, достаточно выделить его в дереве отчёта.

Дерево данных

Дерево данных имеет несколько закладок — это переменные, функции и классы, существующие в отчёте, а также дерево данных из БД, аналогичное дереву отчёта.

Настройка

Настройка интерфейса дизайнера производится в окне Настройки дизайнеранастройки: дизайнера. Чтобы открыть это окно, вызовите команду Настройки… из меню Вид (см. табл. «Окно Опции»).

Рис. Окно Опции


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

Опция Вызывать редактор после вставки открывает редактор кода после вставки объекта.

Опция Показывать заголовки бэндов позволяет отключать заголовки у бэндов в целях экономии свободного места на странице.

Если шаблон вызывается из программы altAwin, в него передаются данные выделенного элемента. Так, например, при выборе заказа и вызове отчёта Задание в цех шаблону будут переданы данные из этого заказа. Показывать выпадающий список полей позволяет выводить список переданных шаблону полей в выпадающем списке объекта текст.

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

Работа с шаблонами

Дизайнер FastReport может работать с двумя видами документов: шаблонами отчётов и готовыми отчётами.

Работа с готовыми отчётами будет рассмотрена позже. В этом разделе остановимся на шаблонах.

Шаблоны

Шаблон отчёта не содержит данных. На этапе оформления шаблона задаются условия, по которым готовый отчёт будет наполняться данными. Например, при оформлении шаблона можно использовать системную переменную [DATE], которая в готовом отчёте будет заменена на текущую дату. В квадратных скобках указываются переменные и выражения. При формировании отчёта выражения, заключенные в квадратные скобки, вычисляются и заменяются на полученный результат.

Свойства шаблона

Опции

В FastReport можно задавать параметры шаблонанастройки: шаблона. Для этого вызовите команду Настройки… из меню Отчёт. В окне Настройки отчёта можно выбрать принтер, на котором будет печататься готовый отчёт, а также указать число этапов формирования готового отчёта.

Если флаг Делать два прохода установлен, формирование отчёта будет осуществляться в два этапа. На первом проходе отчёт формируется, осуществляется его разбивка на страницы, но результат нигде не сохраняется. На втором проходе происходит обычное формирование отчёта с сохранением результата в потоке.

Для чего нужно делать два прохода? Наиболее часто эта опция применяется, если в отчёте имеется упоминание об общем количестве страниц, то есть информация вида Страница 1 из 15. Общее количество страниц подсчитывается на первом проходе и доступно через системную переменную [TOTALPAGES]. Часто эту переменную применяют в однопроходном отчёте, в этом случае она возвращает 0.

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

Переменные

настройки: словаря данныхДля каждого отчёта можно создать собственный список данных, в котором может содержаться список переменных, список данных из БД а также список источников данных. Чтобы настроить список данных, воспользуйтесь командой Переменные на панели инструментов.

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

Прежде чем вы объявите переменную, необходимо создать категорию, в которую она будет входить. Для этого нажмите кнопку Новая категория Intro dictionary variables newcategory.png. В области Переменные появится значок папки. Переменные будут лежать в этой категории. Для объявления переменной нажмите кнопку Новая переменная Intro dictionary variables newvariable.png.

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

Открытие шаблона

шаблон: открытьЧтобы открыть шаблон, вызовите команду Открыть из меню Файл или нажмите кнопку Открыть отчёт (Intro panel instruments open.png) на панели инструментов. В стандартном диалоге открытия файла укажите имя шаблона, который вы хотите открыть. Шаблоны хранятся в папке Reports, которая расположена в каталоге установки altAwin.

Сохранение шаблона

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

Лист отчета

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

Следует различать лист шаблона и страницу отчёта. Лист шаблона определяет структуру страниц, создаваемых во время формирования отчёта. Если данные невозможно вывести на одной странице, автоматически создается следующая. Её структура будет определяться тем же листом шаблона. То есть, по одному листу шаблона может быть создано несколько страниц отчёта. В одном отчёте может быть несколько листов, для создания страниц с разным оформлением. Чтобы добавитьдобавить: лист шаблона ещё один лист, нажмите кнопку Добавить страницу Intro panel instruments newpage.png на панели инструментов.

Для любого листа шаблона можно настроитьнастройки: листа опции формирования. Для этого воспользуйтесь командой Настройки страницы… из меню Файл. В этом окне настраивается лист отчёта — размер бумаги, поля принтера и т. д. На закладке «Прочее» можно указать количество колонок на листе и расстояние между ними. Также можно включить опцию Печать на предыдущей странице. Если эта опция включена, то при наличии на предыдущем листе свободного места текущий лист начинает печататься на предыдущей странице.

Объекты и их свойства

объект: листа отчёта Таблица 0.0. Компоненты панели «Объекты»

Объект Название Описание
Intro panel object edittext.png Редактор текста Позволяет перейти в режим редактирования текста.
Intro panel object copyiface.png Копирование внешнего вида Копирует стиль текста выделенного объекта другому объекту.
Intro panel object report memo.png Текст Отображает текст внутри прямоугольной области.
Intro panel object report band.png Бэнд Позволяет задать область отчёта с определённым поведением.
Intro panel object report picture.png Рисунок Предназначен для вставки графического файла в формате BMP, WMF, ICO (и JPG, если установлен соответствующий модуль) в документ.
Intro panel object report subreport.png Вложенный отчёт Позволяет вставить дополнительный отчёт внутрь основного.
Intro panel object report slavetext.png Служебный текст Предназначен для вставки переменных, агрегатных функций и пр.
Intro panel object report gradient.png Градиент Выводит градиентно окрашенный прямоугольник.
Intro panel object report crosstab.png Cross-tab Выводит таблицу с заданным количеством колонок и столбцов. Каждая ячейка впоследствии может быть отредактирована вручную.
Intro panel object report dbcrosstab.png DB Cross-tab Аналогично объекту Cros-tab, но число колонок и столбцов определяется источником из БД.
Intro panel object report diagram.png Диаграмма Отображает данные в виде диаграмм различных типов (круговая диаграмма, гистограмма и т. п.).
Intro panel object report barcode.png Штрих-код Предназначен для вставки штрих-кодов в документ (доступно около десятка разных типов штрих-кодов).
Intro panel object report chekbox.png CheckBox Отображает крестик или галочку внутри прямоугольника.
Intro panel object report ole.png OLE Предназначен для вставки OLE объектов в документ.
Intro panel object report richedit.png RichText Отображает форматированный текст в формате Rich text (RTF).
Intro panel object report line.png Рисование Позволяет добавить в шаблон графические элементы: линии, стрелки, фигуры.
Intro panel object report altec.png Altec® altAwin™ Добавление на лист изображения конструкции, сварки и пр. Описание данных объектов приведено в главе .

объект: свойстваУ каждого объекта есть набор свойств, который определяет внешний вид и поведение этого объекта. Изменение этих свойств происходит в инспекторе объектов. Все свойства можно разделить на четыре основные группы:

Таблица 0.0. Группы свойств объектов

Группа свойств Описание
Булевые свойства Могут принимать только значение True или False. Значение True означает, что свойство включено. False — свойство выключено.
Перечислямые свойства Данные свойства могут принимать фиксированное значение из приводимого списка.
Числовые свойства Могут принимать численные значения, вводимые с клавиатуры.
Составные свойства Состоят из нескольких подсвойств. В инспекторе объектов значение данного свойства заключено в скобки. При двойном щелчке но полю открывается редактор, в котором можно настроить все подсвойства.

Объект «Бэнд»

объект: бэндОстановимся подробнее на объекте Бэнд.

Бэнд представляет собой некоторую область на листе. Поведение бэнда зависит от его типа. В табл. «Перечень используемых бэндов» приведен полный перечень бэндов и выполняемых ими функций.

Таблица 0.0. Перечень используемых бэндов

Название Функция
Заголовок отчёта Печатается один раз в начале отчёта
Подвал отчёта Печатается один раз в конце отчёта
Заголовок страницы Печатается вверху на каждой странице
Подвал страницы Печатается внизу на каждой странице
Заголовок данных Печатается перед первым бэндом с данными, который следует после данного бэнда
Подвал данных Печатается после бэнда с данными
Данные 1-6 уровня Выводят данные разного уровня вложенности
Заголовок группы Выводится в начале группы
Подвал группы Выводится после группы
Дочерний бэнд Может быть прикреплен к любому из бэндов, кроме Page footer. При этом бэнд будет выводиться вместе с родительским.
Заголовок колонки Выводится в начале колонки
Подвал колонки Выводится после колонки
Вертикальные бэнды Позволяет расположить бэнды вертикально. Все элементы имеют тот же смысл, что и при горизонтальном размещении.

Редактор для дата-бэндов позволяет выбрать источник данных из списка доступных либо выбрать виртуальный источник данных. При выборе виртуального источника необходимо указать, из скольких записей он состоит. При формировании отчёта бэнд с виртуальным источником будет напечатан столько раз, сколько записей было задано. Редактор для бэнда Заголовок группы позволяет ввести условие группировки. Остальные бэнды не имеют редакторов.

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

Для различных бэндов в испекторе объектов доступны различные свойства. Их описание приводится внизу инспектора.

Диалоговая форма

Шаблон отчёта, помимо листов, может содержать диалоговые формы. Диалоговая форма используется, когда необходимо задать какие-либо данные при формировании готового отчёта. Чтобы добавить диалоговую форму в шаблон, нажмите кнопку Добавить форму диалога Intro panel instruments add dialog.png на панели инструментов.

Объекты диалоговой формы, их свойства и методы

объект: диалоговой формыКак и на листе, на диалоговой форме можно разместить различные объекты. Эти объекты представлены в табл. «Компоненты панели «Объекты»».

Таблица 0.0. Компоненты панели «Объекты»

Объект Название Описание
Intro panel object dialog label.png Label Используется для вывода поясняющей надписи.
Intro panel object dialog edit.png Edit Предназначен для ввода однострочного текста с клавиатуры.
Intro panel object dialog memo.png Memo Объект аналогичен объекту Edit, но позволят вводить несколько строк текста.
Intro panel object dialog button.png Button Этот объект используется, если необходимо запустить выполнение какого-либо события.
Intro panel object dialog checkbox.png CheckBox Представляет собой флаг, который может быть в двух положениях — включен или выключен. Рядом выводится поясняющая надпись.
Intro panel object dialog radiobutton.png RadioButton Объект используется в группе. Может находиться в двух состояниях — включен или выключен. Если объект включен, то все остальные объекты RadioButton переходят в выключенное состояние.
Intro panel object dialog dblookupcombobox.png DBLookupCombоBox Представляет собой выпадающий список строк с возможностью выбора одной из них. Строками являются записи указываемого поля из БД.
Intro panel object dialog listbox.png ListBox Представляет собой список строк с возможностью выбора одной из них.
Intro panel object dialog combobox.png ComboBox Представляет собой выпадающий список строк с возможностью выбора одной из них.
Intro panel object dialog panel.png Panel Представляет собой панель, которая служит для объединения нескольких элементов управления.
Intro panel object dialog groupbox.png GroupBox Представляет собой панель с поясняющей надписью, которая служит для объединения нескольких элементов управления.
Intro panel object dialog dateedit.png DateEdit Позволяет выбрать дату.
Intro panel object report picture.png Image Позволяет вывести изображение в формате BMP, ICO, WMF, EMF.
Intro panel object dialog bevel.png Bevel Предназначен для оформления диалоговой формы.
Intro panel object dialog bitbtn.png BitBtn Аналогичен объекту Button, но позволяет указать тип кнопки (Close, Help, Ok и т. п.).
Intro panel object dialog speedbtn.png SpeedButton Аналогичен объекту Button, но не может принимать фокус.
Intro panel object dialog mask.png MaskEdit Представляет собой поле для ввода информации по заданному шаблону.
Intro panel object dialog checklistbox.png CheckListBox Представляет собой объединение двух компонентов — ListBox и CheckBox.
Intro panel object dialog tlistview.png TListView Предназначен для отображения данных в табличной форме.

У каждого объекта есть свое имя. Это уникальный в пределах отчёта идентификатор. Он отображается в поле Name. В отчёте у вас может быть несколько таких объектов, поэтому рекомендуется задавать «говорящие» имена всем новым объектам.

Объекты диалоговой формы имеют свои свойства, которые также могут быть сведены к четырём группам, описанным в табл. «See Группы свойств объектов».

Доступ к свойствам как диалоговой формы, так и листа отчёта осуществляется с помощью точки после имени объекта. Например, доступ к тексту объекта Edit с именем Edit1 осуществляется следующим образом:

Edit1.Text

Таким обращением можно изменить текст, прочитать его и т. д. Например, следующий скрипт изменяет содержимое объекта:

Edit1.Text := 'Hello World!';

Кроме свойств у объектов есть методы — определённые операции, которые производятся над объектом. Например, чтобы выполнить SQL-запрос объекта Запрос с именем Query1, необходимо создать скрипт вида:

Query1.Open;
Пример использования компонента ListView
var LI : TListItem; LC : TListColumn; LIs : TListItems ;
begin
LC := ListView1.Columns.Add;
LC.Caption := 'Self create'; 
LC := ListView1.Columns.Add;
LC.Caption := 'Self create'; 
LC := ListView1.Columns.Add; 
LC.Caption := 'Self create';
LI := ListView1.Items.Add;
LI.Caption := 'rt';
LI.SubItems.Add('test1');
LI.SubItems.Add('test2');
LI.SubItems.Add('test3');
end;

Скрипт — это программа на языке высокого уровня, которая является частью отчёта. Скрипт позволяет выполнить обработку данных, которую невозможно сделать штатными средствами FastReport, например, скрыть ненужные данные в зависимости от какого-либо условия. Также используется для управления диалоговыми формами, входящими в состав отчёта.

Скрипт создается для событий — действий, которые наступают при определённых условиях. У разных объектов существуют различные события.

Код

На странице Код создается скрипт, который позволяет изменять внешний вид, редактировать данные, форматировать вывод данных и прочее. Именно на этой странице следует обращаться к свойствам и методам объектов, как это описано выше.

Данные

Для вывода информации из БД требуется создать запросы. Это делается с помощью компонентов на странице Данные.

Объекты данных

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

Таблица 0.0. Компоненты на панели «Объекты»

Объект Название Описание
Intro panel object report memo.png Текст Выводит вспомогательный текст на листе данных.
Intro panel object report line.png Рисование Выводит вспомогательное изображение на листе данных.
Intro panel object dialog queryibx.png Запрос IBX Динамический запрос к БД. Этот объект не отображается на форме при выполнении отчёта.
Intro panel object dialog table.png Таблица ADO Может содержать таблицу из любой БД, подключенной к отчёту. Этот объект не отображается на форме при выполнении отчёта.
Intro panel object dialog query.png Запрос ADO Динамический запрос к БД. Этот объект не отображается на форме при выполнении отчёта.
Intro panel object dialog DB.png База данных ADO Позволяет подключить к отчёту БД из файла. Выбор файла осуществляется в стандартном диалоге открытия окна. Этот объект не отображается на форме при выполнении отчёта.

Режим предпросмотра

Созданный шаблон содержит переменные и различный код. Чтобы шаблон превратился в отчёт, необходимо воспользоваться кнопкой Предварительный просмотр Intro panel instruments preview.png на панели инструментов. При этом выполняются все скрипты, написанные для различных объектов, вычисляются переменные, бэнды формируются необходимое количество раз и т. д. После выполнения всех операций откроется окно Предварительный просмотр, в котором содержится готовый отчёт. В этом окне можно изменять масштаб отчёта, искать какую-либо информацию, печатать отчёт на принтере. Также можно сохранить этот отчёт или открыть ранее сохраненный.

Изменение готового отчета

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

Сохранение готового отчета

Чтобы сохранить готовый отчёт, воспользуйтесь кнопкой Сохранить отчёт в файле Intro panel instruments save.png на панели инструментов. Готовый отчёт имеет расширение .frp и может использоваться в дальнейшем.

В дистрибутиве altAwin поставляется специальная утилита для просмотра готовых отчётов ReportViewer.

Примеры создания отчетов

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

Создание пустого бланка

Создадим бланк листа замера. Бланк должен содержать название заказчика, фамилию замеряющего, а также информацию по нескольким изделиям: ширина, высота, цвет и т. д.

Для вывода заголовка отчёта удобно использовать бэнд Заголовок отчёта. Бэнд такого типа отображается один раз в начале отчёта.

Теперь добавьте объект Прямоугольник с текстом (в дальнейшем — Текст) так, чтобы он располагался поверх бэнда. Этот объект будет отображать заголовок отчёта. Если опция Редактирование после вставки включена, откроется окно редактирования Memo объекта. Если выключена, дважды щелкните мышью по объекту. В окне редактора Memo объекта введите следующий текст:

Лист замера

В табл. «Свойства объекта Текст» приведены некоторые свойства, которые мы будем использовать для создания текущего отчёта.

Свойство Описание
AutoWidth Если свойство имеет значение True, то при печати отчёта ширина объекта увеличивается по ширине содержащегося в объекте текста.
Align Положение объекта на бэнде. Может быть равно одной из констант: baNone, baLeft, baRight, baCenter, baWidth, baBottom.

Таблица 0.0. Свойства объекта Текст

Произведем следующие настройки объекта Текст.

Полю Align присвоим значение baWidth, чтобы объект растянулся по всей ширине страницы.

Настроим оформление заголовка. Для этого необходимо использовать кнопки на панели «Текст». Установите следующий стиль для заголовка: выравнивание по центру страницы, шрифт «Verdana», 18 pt, белый на сером фоне.

Обратите внимание, что после произведенных нами изменений, введенный текст полностью не виден в объекте. Измените размеры объекта мышью.

Добавьте ещё один объект Текст. Расположите его на бэнде под названием отчёта. В Memo введите

Заказчик:

Следующий Текст расположите рядом с ним. Включите отображение контура объекта кнопкой Все линии рамки на панели «Прямоугольник». Растяните объект в длину.

Заголовок отчёта готов. Теперь при формировании отчёта FastReport расположит бэнд Заголовок отчёта в самом верху первой страницы.

Content report blank reporttitle.png

Рис. Пример оформления заголовка отчета


Оформим итог отчёта. Здесь должна содержаться информация об исполнителе и дата выполнения замера. Добавьте бэнд Подвал отчёта. Этот бэнд располагается после вывода всех данных. Расположите на бэнде шесть объектов Текст. У трех из них включите отображение контура. Для оставшихся трех в Memo введите следуюшие записи:

Замер произвел:
Дата:
Подпись:

Эти объекты будут служить подписями к пустым прямоугольникам.

Content report blank reportsummary.png

Рис. Пример оформления итога отчета


Теперь оформим содержимое отчёта. Добавьте бэнд Данные 1 уровня. Этот бэнд может повторяться несколько раз по числу записей, выводимых из БД. Также можно вручную указать число повторов. В окне Источник данных, которое открывается по двойному щелчку левой кнопки мыши, выберите пункт Виртуальный. В поле Количество записей укажите число повтора бэнда.

Content report blank masterdata.png

Рис. Пример оформления формы замера


Расположите на бэнде нужное число объектов Текст, настройте их оформление. Для изменения оформления контура объектов, цвета их заливки, толщины и цвета рамки используйте панель «Прямоугольник». Для изменения выравнивания текста внутри объекта, а также стиля выводимого текста, используйте панель «Текст». На рис. «Пример оформления формы замера» приведено примерное оформление формы заказа для одного изделия. Так как объект Данные 1 уровня должен выводиться несколько раз, эта форма полностью повторится столько раз, сколько вы указали в поле Количество записей для бэнда Master data.

Для просмотра готового отчёта воспользуйтесь кнопкой Предварительный просмотр на панели инструментов или соответствующей командой в меню Файл.

Content report blank.png

Рис. Пример готового отчета


Создание одноуровневого отчета

Создадим отчёт, который будет выводить информацию о заказах в виде таблицы. Также под таблицей заказов будем выводить общее число заказов и их общую стоимость.

Данные

Чтобы вывести данные в отчёт, необходимо использовать запрос в БД. При вызове отчёта из программы altAwin автоматически создается и выполняется запрос по выделенным записям — если выделен заказ, то запрос возвращает данные по заказу, если папка — данные по заказам в этой папке и т. п. Вызовите команду Данные из меню Отчёт и укажите, какие запросы будут использоваться в отчёте. В нашем случае — это CurrentRecordsSet. Теперь мы можем обращаться к данному запросу при построении листа отчёта.

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

Лист отчета

Оформим заголовок отчёта.

Content report leveltwo reporttitle.png

Рис. Пример оформления заголовка


Настроим вывод данных из БД. Настроим заголовок таблицы заказов. Добавьте бэнд Заголовок данных. Этот бэнд отображается один раз перед выводом данных. Добавьте объект Текст на бэнд. В Memo введите:

Номер заказа

Растяните объект мышью так, чтобы полностью отображался текст.

Добавьте ещё один объект Текст. В Memo укажите:

Стоимость заказа

Произведите такие же операции, как и с предыдущим объектом.

Content report leveltwo masterheader.png

Рис. Пример оформления заголовка таблицы заказов


Теперь выведем список заказов. Добавьте объект Данные 1 уровня. Если в настройках FastReport стоит опция Редактирование после вставки, то автоматически откроется окно Источник данных. Если данная опция отключена, дважды щелкните по области бэнда. Укажите в качестве источника CurrentRecordsSet. При выводе на печать бэнд и все его содержимое будут повторены столько раз, сколько записей было возвращено в ответ на запрос.

Для вывода необходимой информации добавьте в отчёт два объекта Текст так, чтобы они находились на этом бэнде. Наведите мышью на объект, справа появится кнопка выпадающего списка. В списке содержатся поля запроса мастер-источника того бэнда на котором расположен объект. Выберите поля, которые необходимо вывести. Для номера заказа это поле ORDERNO, а цены на заказ — TOTALPRICE.

Для правильного отображения таблицы выполните следующие настройки:

  • Расположите эти объекты под соответствующими заголовками на Заголовке данных.
  • В качестве обрамления укажите Все линии рамки.
  • Растяните объекты так, чтобы их размеры совпадали с соответствующими заголовками.
  • Включите у объектов и у бэнда Данные 1 уровня свойство Stretched.

Content report leveltwo masterdata.png

Рис. Оформление таблицы заказов


Выведем под таблицей заказов сообщение об общем числе заказов. Для этого добавим бэнд Подвал данных. Расположим на нём объект Текст. В Memo объекта введем следующий текст:

Всего заказов: [COUNT(MasterData1)]

Здесь мы использовали одну из агрегатных функций COUNT(<имя бэнда>). Эта функция возвращает количество повторов бэнда. В данном примере мы использовали идентификатор бэнда с данными MasterData1. Очевидно, что это имя не говорит о наполнении бэнда, поэтому в дальнейшем будем переименовывать все добавляемые объекты.

Для отображения общей стоимости заказов добавьте на объект Master footer ещё один объект Текст. Воспользуемся агрегатной функцией SUM(<выражение>, <бэнд>).

на сумму: [SUM(<CurrentRecordsSet."TOTALPRICE">, MasterData1)]

Функция SUM() просуммирует все значения поля TOTALPRICE из бэнда MasterData1.

Content report leveltwo masterfooter.png

Рис. Итог таблицы заказов


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

Content report leveltwo.png


Создание двухуровневого отчета

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

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

Данные

Включите в отчёт запрос CurrentRecordsSet — он будет выводить данные по выделенным заказам.

Добавьте на страницу Данные объект Запрос IBX. Для этого щелкните мышью по кнопке Intro panel object dialog query.png Запрос на панели объектов, а затем на странице данных. У объекта Запрос есть разные свойства. В данном отчёте будут использоваться только некоторые из них. Их описание приведено в табл. «Свойства объекта Запрос».

Таблица 0.0. Свойства объекта Запрос

Поле Описание
Name В этом поле указывается уникальный идентификатор, по которому осуществляется доступ к объекту и его свойствам.
SQL Поле, в котором хранится SQL-запрос для выбора данных из БД, указанной в поле Database. По двойному щелчку на этом поле открывается окно Редактор SQL, в котором можно создать или отредактировать запрос.

Каждый объект FastReport имеет уникальный в пределах отчёта идентификатор. Он отображается в поле Name. Добавленный нами только что объект Запрос имеет имя ABDQuery1. В дальнейшем у вас может быть несколько таких объектов. Поэтому рекомендуется задавать «говорящие» имена всем новым объектам. Изменим имя запроса на qryWindows.

В поле Master укажите CurrentRecordsSet. Это означает, что запрос CurrentRecordsSet является для текущего запроса мастер-источникомзапрос:мастер-источник. Мастер-источник чаще всего используется для создания многоуровневых отчётов.

Content dialog simple query SQLedit.png

Для вывода списка изделий и их цен необходимо создать следующий SQL-запрос:

select * from orderitems
where orderid = :orderid

Данный запрос возвращает значение всех полей из тех записей в таблице ORDERITEMS, у которых идентификатор заказа совпадает с идентификатором заказа текущей записи из мастер-источника. В нашем случае запись :orderid указывает, что значение берется из соответствующего поля мастер-источника, к которому привязан запрос qryWindows. Подробнее работа с внешними параметрами будет рассмотрена в следующем примере.

Лист отчета

Перейдем на страницу отчёта. Оформите заголовок отчёта так, как это было описано в предыдущем разделе.

Для вывода списка заказов добавьте бэнд Данные 1 уровня. В качестве источника данных установите CurrentRecordsSet.

На бэнде разместите объект Текст. Объект будет выводить номер заказа, поэтому для вывода данных из БД укажите поле ORDNO. В Memo объекта появится следующая запись.

[CurrentRecordsSet."ORDNO"]

Разместите на листе отчёта под бэндом Данные 1 уровня бэнд с типом секции Данные 2 уровня. В качестве источника данных укажите qryWindows. Добавьте на бэнд два объекта Текст. Этот бэнд будет выводить данные второго уровня. В Memo объектов для вывода номера изделия укажите источник NAME, а для цены на изделие — PRICE.

Если вы хотите вывести список изделий как таблицу, проделайте операции по оформлению таблицы, рассмотренные в предыдущем примере. Для вывода заголовка перед данными второго уровня также используйте бэнд Заголовок данных. Этот бэнд должен располагаться над бэндом Данные 2 уровня (но под бэндом Данные 1 уровня..

Рис. Пример оформления шаблона отчета


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

Рис. Пример отчета


Изменение запроса при формировании отчета

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

Диалоговая форма

Добавьте в отчёт диалоговую форму с помощью кнопки Intro panel instruments add dialog.png Добавить форму в отчёт. Положите на форму объект Edit. Измените имя на edtCount.

Чтобы сформировался отчёт по заданному шаблону, необходимо сначала закрыть диалоговую форму. Добавьте на форму две кнопки Button. У одной кнопки установите свойство ModalResult равным mrOk. При нажатии на эту кнопку диалоговое окно закроется и начнется формирование отчёта. У другой кнопки установите свойство ModalResult равным mrCancel. Эта кнопка закроет диалоговую форму без последующего формирования отчёта. Обе кнопки на форме будут иметь подписи Button. Чтобы изменить подписи, свойству Caption каждой из кнопок присвойте значения OK для кнопки со свойством ModalResult равным mrOk и Cancel для другой кнопки.

Данные

Измените SQL-запрос компонента qryWindows.

select * from orderitems where orderid = :orderid

При этом запрос выдаст все поля таблицы ORDERITEMS для текущей записи в CurrentRecordsSet. Но этого не достаточно. Необходимо, чтобы выдавались не все конструкции, а только те, количество которых больше определённого значения, которое на этапе шаблона неопределено. Модификация запроса будет осуществляться с помощью скрипта.

Лист отчета

Перейдите на страницу отчёта.

Проверьте, что у бэнда Данные 1 уровня свойство PrintIfDetailEmpty выключено — это позволяет не печатать данные о заказе, если в нём не существует изделий, удовлетворяющих условию.

На бэнд Данные 2 уровня к уже существующим объектам добавьте объект Конструкция/изделие. Укажите объекту имя winPicture.

Для оформления таблицы проделайте следующие операции:

  • Установите нужные вам размеры Рисунка. Включите Все линии рамки объекта соответствующей кнопкой на панели «Прямоугольник».
  • Установите высоту бэнда Данные 2 уровня таким образом, чтобы нижняя граница бэнда совпадала с нижней границей Рисунка. Включите у бэнда свойство Stretched.
  • У объектов Текст, отображающих номер изделия и его стоимость, также включите свойство Stretched. Это необходимо для того, чтобы высота объектов была равна высоте бэнда, на котором они лежат, а следовательно, и высоте объекта Рисунок. Таким образом, получим таблицу, содержащую номер изделия, его стоимость и изображение.

Код

Необходимо, чтобы SQL-запрос изменился после выбора количества изделий, то есть, после закрытия диалогового окна по кнопке OK. У объекта Button есть событие OnClick, наступающее при нажатии на кнопку. изменить:SQL-запросЧтобы изменить SQL-запрос, необходимо создать следующий скрипт для этого события:

begin
 qryWindows.SQL.Add('and qty >= ' + edtCount.text);
end

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

SQL-запрос окончательно формируется после закрытия диалоговой формы с помощью скрипта. Однако можно обойтись и без скрипта. Для этого используем внешние параметры SQL-запроса. Для qryWindows создайте SQL-запрос:

select * from orderitems where orderid = :orderid and qty >= :qty

Content report leveltwo SQL params.png

В данном SQL-запросе qty и orderid являются внешними параметрами. Синтаксис задания внешнего параметра любого SQL-запроса — :<имя_параметра>. Все параметры хранятся в свойстве Params SQL-запроса. Дважды щелкните левой кнопкой мыши по соответствующему полю в инспекторе объектов. При этом откроется окно Параметры. Каждый параметр по умолчанию указывает на поле из мастер-источника. Для параметра orderid это верно, но параметр qty должен возвращать значение текстового поля на диалоговой форме. Установите тип параметра в Integer, а в поле Значение укажите

StrToInt(edtCount.text)

Здесь используется встроенная функция преобразования типов StrToInt(<строка>) — перевод строкового значения в числовое.

При выполнении SQL-запроса вместо параметров orderid и qty будут подставлены соответствующие значения.

Чтобы передать объекту winPicture xml-строку с изображением изделия, необходимо выбрать бэнд Данные 2 уровня и создать событие OnBeforePrint — для этого перейдите в инспекторе на вкладку События и дважды щелкните по полю ввода напротив соответствующего события. Создайте следующий код:

winPicture.Data := <qryWindows."PACKINFO">;

Оформление шаблона закончено, для вывода отчёта перейдите в режим предпросмотра.


Взаимодействие объектов между собой

Сформируем отчёт, который позволит выбирать выводимые заказы на этапе формирования отчёта.

Диалоговая форма

Создайте диалоговую форму. Заголовок окна пуст, что не удобно. В поле Caption испектора объектов введите Выбор заказов. Обратите внимание, что заголовок окна изменился.

Добавьте на форму компонент DateEdit, измените его имя на dedOrders. Этот компонент позволит выбрать заказы, созданные в нужный день. Чтобы указать пользователю, зачем нужен данный компонент, добавьте рядом объект Label и в его свойстве Caption укажите Дата оформления заказа.

Добавьте компонент CheckListBox, присвойте ему имя clbOrders. Здесь из всех заказов будем выбирать только те, которые требуется распечатать. Над этим компонентом расположите ещё один объект Label. В свойстве Caption укажите Заказы.

Теперь следует добавить кнопки, которые закроют форму и начнут формирование отчёта. Добавьте две кнопки: одна должна начать формирование отчёта, другая — отменит выполнение. Создание таких кнопок описано в предыдущем примере.

Диалоговая форма готова (см. рис. «Диалоговая форма отчета»).

Рис. Диалоговая форма отчета


Данные

В этом отчёте нам не понадобятся данные текущего заказа, поэтому объект CurrentRecordsSet можно отключить.

Добавьте объект Запрос, измените имя на qryOrders. Этот запрос будет возвращать список заказов на определённую дату. Создайте следующий SQL-запрос:

select * from orders where dateorder=:date

В свойстве Params укажите, откуда должно браться значение параметра date — в данном случае это значение должно быть типа Date и браться из dedOrders.Date.

Добавьте ещё один запрос, переименуйте его в qryWindows. Укажите в качестве мастер-источника объект qryOrders. Создайте SQL-запрос:

select * from orderitems where orderid = :orderid

Лист отчета

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

Код

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

begin
end.

var //Задание переменных
 orderid: Array[0..1000] of Integer;
 i: integer;

procedure FillOrdersList();
//Процедура для заполнения списка заказов
begin
 clbOrders.Items.Clear; // Очищаем список заказов
 i := 0;
 qryOrders.Close; // Закрываем ранее открытый запрос
 qryOrders.Open; // Открытие запроса...
 qryOrders.First; // и позиционирование на первую запись
 while not qryOrders.Eof do // Пока не кончится запрос...
  begin
   // ...добавляем в список номера закзаов...
   clbOrders.Items.Add(<qryOrders.&quot;ORDERNO&quot;>);
   orderid[i] := <qryOrders.&quot;ORDERID&quot;>; // ...а в массив их id...
   inc(i); // ...увеличиваем счетчик...
   qryOrders.Next; // ...и переходим на следующую запись
  end;
end;
procedure DialogPage1OnActivate(Sender: TfrxComponent);
// При активации дилоговой формы…
begin
 // ...установить текущую дату в поле выбора дат...
 dedOrders.Date := <Date>; 
 FillOrdersList(); // ...и заполнить список заказов
end;
procedure dedOrdersOnChange(Sender: TfrxComponent);
// При изменении даты…
begin
 FillOrdersList(); // ...заполнить список заказов
end;

procedure btnOkOnClick(Sender: TfrxComponent);
// При нажатии на кнопку OK
var
 Filter: String; // Задаем переменную для фильтра списка заказов
begin
 for i := 0 to clbOrders.Items.Count - 1 do
  begin
   if clbOrders.Checked(i) then
    if Filter = '' then
     Filter := Filter + IntToStr(orderid[i])
    else
     Filter := Filter + ', ' +  IntToStr(orderid[i]);
  end;
 if Filter = '' then // Если ни один заказ не выбран, то
  begin
   ShowMessage('Необходимо выбрать хотя бы один заказ');
   DialogPage1.ModalResult := mrNone; // не закрываем окно
  end
 else
  begin
   // добавляем строку с фильтром в запрос
   qryOrders.SQL.Add('and orderid in (' + Filter + ')');
   qryOrders.Open; // и открываем запрос
  end;
end;

procedure DetailData1OnBeforePrint(Sender: TfrxComponent);
// Перед выводом каждого бэнда DetailData…
begin
 // ...устанавливаем источник для рисунка
 ModelView1.Data := <qryOrderItems.&quot;PACKINFO&quot;>;
end;
begin
end.


Создание Cross-tab отчетов

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

Данные

Для начала необходимо получить список всех заказчиков. Добавьте объект Запрос. Измените имя объекта на qryCustomers.

В базе данных altAwin информация о заказчиках и поставщиках хранится в одной таблице CONTRAGENTS. В таблице заказчиков CUSTOMERS хранятся только указатели, которые ссылаются на записи в таблице CONTRAGENTS. Таким образом, чтобы получить список заказчиков, необходимо создать следующий SQL-запрос:

select * from customers
inner join contragents 
 on customers.contragid = contragents.contragid

Этот запрос выполняется в два этапа: сначала в таблице CONTRAGENTS выбираются записи, на которые ссылаются указатели в таблице CUSTOMERS, а затем полученная таблица объединяется с таблицей CUSTOMERS. Результатом данного запроса будет весь список заказчиков, когда-либо заведенных в БД, в том числе будут указаны и удаленные заказчики. Во многих таблицах БД (CUSTOMERS, ORDERS и др,) информация не удаляется, а лишь помечается как удаленная. В таких таблицах в поле DELETED хранится дата удаления записи, а у неудаленных записей данное поле содержит NULL. Чтобы предотвратить вывод удаленных заказчиков, измените запрос на:

select * from customers
inner join contragents 
 on customers.contragid = contragents.contragid
where customers.deleted is null

Добавьте ещё один Запрос. Измените имя объекта на qryDates. Создайте следующий SQL-запрос:

select distinct extract(month from dateorder) d_month,
                extract(year from dateorder) d_year from orders
where deleted is not null
order by 2, 1

При выполнении SQL-запроса будет просмотрен каждый заказ в БД и возвращена таблица, все записи которой будут содержать два поля — месяц и год заказа. Модификатор distinct удалит повторяющиеся записи из таблицы. Таким образом запрос вернет список всех сочетаний месяц-год, в которые были оформлены заказы. Затем все записи будут упорядочены по возрастанию даты.

Добавьте Запрос, который будет работать с заказами, измените его имя на qryOrders. В качестве мастер-источника назначьте запрос qryCustomers. Создайте следующий SQL-запрос:

select coalesce(sum(orders.totalprice), 0) sumprice from orders
where customerid = :customer
 and extract(month from orders.dateorder) = :month
 and extract(year from orders.dateorder) = :year

В параметрах запроса установите для month и year следующие значения:

<qryDates."D_MONTH">
<qryDates."D_YEAR">

Лист отчета

На этапе оформления шаблона отчёта неизвестно, сколько столбцов должно быть в таблице. Чтобы построить подобную таблицу используются Cross-tab отчёты.

Cross-tab отчёт можно создать двумя способами: с помощью компонента Cross-tab и собрать таблицу из бэндов. Объект Cross-tab имеет некоторые недостатки, в частности, позволяет работать только с одним запросом, поэтому в данном примере рассмотрим второй способ.

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

Добавьте вертикальный бэнд Заголовок данных. Он неоходим для вывода названия строк таблицы. Для вывода столбцов добавьте вертикальный бэнд Данные 1 уровня. В окне Источник данных необходимо указать источник — qryDates. При этом бэнд повторится столько раз, сколько записей будет возвращено запросом qryDates.

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

В результате получится девять зон, образованных пересечением бэндов (см. рис. «Бэнды для построения таблицы»).

Рис. Бэнды для построения таблицы


На пересечении горизонтального бэнда Данные 1 уровня и вертикального бэнда Заголовок данных разместите объект Текст, измените размеры бэндов и объекта Текст так, чтобы объект полностью лежал в пределах зоны, образованной пересечением бэндов. В Memo объекта Текст укажите:

[qryCustomers."NAME"]

При формировании отчёта в этом поле будет выводиться название заказчика.

Объект Текст на пересечении горизонтального бэнда Подвал данных и вертикального бэнда Подвал данных будет выводить название последней строки в таблице. В Memo объекта укажите необходимый текст, например, «Итого:».

На пересечении горизонтального бэнда Заголовок данных и вертикального бэнда Данные 1 уровня разместите объект Текст. В Memo объекта укажите следующее:

[qryDates."D_MONTH"].[qryDates."D_YEAR"]

При формировании отчёта отобразится запись даты типа mm.yyyy.

Для вывода стоимости заказов, совершенных заказчиком в какой-либо месяц, необходимо разместить Текст на пересечении горизонтального бэнда Данные 1 уровня и вертикального бэнда Данные 1 уровня. В Memo объекта укажите поле БД:

[qryOrders."SUMPRICE"]

Для вывода суммы стоимостей всех заказов за определённый месяц разместите Текст на пересечении бэндов Master footer и Cross data. Чтобы получить сумму стоимостей, используйте агрегатную функцию SUM() и введите в Memo следующий текст:

[SUM(<qryOrders."SUMPRICE">, MasterData1)]

Объект Текст на пересечении бэндов Заголовок данных и Cross footer будет выводить заголовок последнего в таблице столбца. В Memo объекта укажите необходимый текст, например, "Итого:..

Для вывода суммы стоимостей всех заказов каждого заказчика разместите Текст на пересечении горизонтального бэнда Данные 1 уровня и вертикального бэнда Подвал данных. Используте агрегатную функцию SUM() и введите в Memo следующий текст:

[SUM(<qryOrders."SUMPRICE">)]

Шаблон, по которому будет создаваться и заполняться данными таблица, готов (см. рис. «Шаблон таблицы данных»).

Рис. Шаблон таблицы данных


Код

Запрос qryOrders выполняется каждый раз при изменении мастер-источника. Однако в нашем случае он должен изменяться каждый раз, когда меняется любой из «родительских» запросов. Эту задачу можно решить несколькими способами, но проще всего создать событие для объекта, в котором выводится информация по стоимости, в данном случае — Memo5. Создайте в инспекторе событие OnBeforePrint и напишите следующий код:

qryOrders.Close;
qryOrders.Open;

Данный скрипт выполняет заново запрос qryOrders каждый раз, когда выводится объект Memo5.


Справочник

SQL

Данная глава посвящена описанию работы с SQL запросами при работе с дизайнером отчётов.

SQL-оператор состоит из зарезервированных слов, а также из слов определяемых пользователем. Зарезервированные слова являются постоянной частью языка SQL и имеют фиксированное значение. Их следует записывать в точности так, как это установлено, и нельзя разбивать на части для переноса из одной строки в другую. Слова, определяемые пользователям, задаются самим пользователем (в соответствии с определёнными синтаксическими правилами) и представляют собой имена различных объектов базы данных — таблиц, столбцов, представлений индексов и т. д. Слова в операторе размещаются в соответствии с установленными синтаксическими правилами.

Большинство компонентов SQL-операторов не чувствительны к регистру. Это означает что могут использоваться любые буквы — как строчные так и прописные. Одним важным исключением из этого правила являются символьные литералы-данные, которые должны вводится точно так же, как были введены соответствующие им значения, хранящиеся в базе данных. Например, если в базе данных хранится значение фамилии 'Минеев', а в условии поиска указан символьный литерал 'МИНЕЕВ', то эта запись не будет найдена.

Поскольку язык SQL имеет свободный формат, отдельные SQL-операторы и их последовательности будут иметь более читабельный вид при использовании отступов и выравнивания. Рекомендуется придерживаться следующих правил:

  • Каждая фраза в операторе должна начинаться с новой строки;
  • Начало каждой фразы должно быть выровнено с началом остальных фраз оператора;
  • Если фраза имеет несколько частей, каждая из них должна начинаться с новой строки с некоторым отступом относительно начала фразы, что будет указывать на их подчиненность;

В дальнейшем для определения формата SQL-операторов будет применяться следующая форма:

  • Вертикальная черта указывает на необходимость выбора одного из нескольких приведенных значений, например, a .
  • Фигурные скобки определяют обязательный элемент, например, {a}.
  • Квадратные скобки определяют необязательный элемент, например, [a].
  • Многоточие используется для указания необязательной возможности повторения конструкции, от нуля до нескольких раз, например {a. Эта запись означает что после a или b может следовать от нуля до нескольких повторений c разделенных запятыми.

Литералы

Прежде чем приступить к обсуждению SQL-операторов, необходимо выяснить, что означает такое понятие как «литерал». Литералы представляют собой константы, которые используются в SQL-операторах. Существуют различные формы литералов для каждого типа данных, которые поддерживаются SQL. Однако не углубляясь в детали можно указать лишь различия между литералами, которые следует заключать в одинарные кавычки, и теми, которые не следует. Все нецифровые значения данных всегда должны заключаться в одинарные кавычки. Вот пример использования литералов при помещении данных в таблицу:

insert into windcharge
(windchargeid, namefactor, chargefactor, deleted, userconst)
values (1, 'A', 0.6, null, 0)

Здесь литералами являются указанные в скобках после value значения полей.

Оператор SELECT

Оператор SELECT является наиболее сложной и чаще всего используемой командой языка SQL. Его назначение состоит в выборке и отображении данных одной или более таблиц базы данных. Общий вид оператора SELECT имеет следующий вид:

select [distinct | all] {* | [<имя_поля> [as <новое_имя>]] [,…]}
from <имя_таблицы> [<псевдоним>] [,]
[where <условие>]
[group by <список_полей>] [having <условие>]
[order by <список_полей>]

Здесь параметр <имя_поля> представляет собой имя поля или выражение из нескольких имен. Параметр <имя_таблицы> является именем существующей в базе данных таблицы или представления, к которым необходимо получит доступ. Необязательный параметр <псевдоним> — это сокращение, устанавливаемое для имени таблицы <имя_таблицы>. Обработка элементов оператора SELECT выполняется в следующей последовательности:

Таблица 0.0. Выполнение элементов оператора SELECT}

Элемент Описание
SELECT Устанавливается, какие поля должны присутствовать в выходных данных
FROM Определяются имена используемой таблицы или нескольких таблиц
WHERE Выполняется фильтрация строк объекта в соответствие с заданными условиями
GROUP BY Образуются группы строк, имеющих одно и то же значение в заданном поле
HAVING Фильтруются группы строк объекта в соответствие с указанным условием
ORDER BY Определяется упорядоченность результатов выполнения оператора

Порядок предложений и фраз в операторе SELECT не может быть изменён. Только два предложения оператора — SELECT и FROM — являются обязательными, все остальные предложения и фразы могут быть опущены. Операция SELECT является закрытой: результат запроса к таблице представляет собой другую таблицу. Существует множество вариантов записи данного оператора, что иллюстрируется приведенными ниже примерами.

Выборка всех строк

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

select orderid, orderno, customerid,
from orders

В результате получим таблицу вида:

ORDERID. ORDERNO. CUSTOMERID.
1 Заказ № 1 1002
2 Заказ № 11 3192
3 Заказ № 32 1329
5 Заказ № 42 5677

Поскольку выборка всех имеющихся в таблице полей выполняется достаточно часто, в языке SQL определён упрощенный вариант записи значения «все поля» — вместо имени полей указывается символ звездочки *. Приведенный ниже пример представляет собой упрощенный вариант записи запроса для выбора всех полей:

select *
from windcharge

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

select dateorder
from orders

Результат:

DATEORDER
17.10.2004 0:00:00
01.09.2005 0:00:00
01.09.2005 0:00:00
16.09.2005 0:00:00
16.09.2005 0:00:00
16.09.2005 0:00:00
19.09.2005 0:00:00
19.09.2005 0:00:00

Как видно из примера оператор SELECT не исключает дублирующихся значений при выборке одного или нескольких полей. Для удаления из результирующей таблицы дублирующихся строк используется ключевое слово DISTICT.

select distinct dateorder
from orders

Результат:

DATEORDER
01.08.2004 0:00:00
01.09.2004 0:00:00
17.10.2004 0:00:00
01.09.2005 0:00:00
16.09.2005 0:00:00
19.09.2005 0:00:00

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

select orderno, totalprice*29.9 as rus_price
from orders

Результат:

ORDERNO RUS_PRICE
Order2 20130.77
A32 6809.72
456218953 182.00
Order3 0.00
28949 8752.33

Выбор строк (предложение WHERE)

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

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

В языке SQL можно использовать следующие операторы сравнения:

Таблица 0.0. Операторы сравнения}

Оператор Описание
= равенство
< меньше
> больше
< = меньше или равно
> = больше или равно
< > не равно (стандарт ISO)

Более сложные предикаты могут быть построены с помощью логических операторов AND, OR или NOT, а также с помощью скобок, используемых для определения порядка вычисления выражения (если это необходимо или желательно). Вычисление выражений в условиях выполняется последующим правилам,

  • Выражение вычисляется слева направо.
  • Первыми вычисляются подвыражения в скобках.
  • Операторы NOT выполняются до выполнения операторов AND и OR.
  • Операторы AND выполняются до выполнения операторов OR.

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

select name
from orderitems
where orderid = 2

Результат:

NAME
A32-1
A32-3
A32-4

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

select orderno, totalprice, dateorder
from orders
where dateorder between '20.05.2005' and '17.08.2005'

Результат:

ORDERNO TOTALPRICE DATEORDER
456218953 182.00 16.06.2005 0:00:00
Order3 0.00 16.06.2005 0:00:00
28949 8752.33 29.07.2005 0:00:00

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

Существует и отрицательная версия этой проверки (NOT IN., которая используется для отбора любых значений, кроме тех, которые указаны в представленном списке. Как и в случае ключевого слова BETWEEN, условие IN незначительно повышает выразительную мощность языка SQL. Однако использование ключевого слова IN представляет собой более эффективный способ записи условий поиска, особенно если набор допустимых значений достаточно велик.

Сортировка результатов (фраза ORDER BY)

В общем случае строки в результирующей таблице SQL-запроса не упорядочены каким-либо определённым образом. Однако их можно требуемым образом отсортировать, для чего в оператор SELECT помещается фраза ORDER BY. Фраза ORDER BY включает список разделенных запятыми идентификаторов полей, по которым требуется упорядочить результирующую таблицу запроса. Идентификатор поля может представлять собой либо его имя, либо номер, который идентифицирует элемент списка SELECT его позицией в этом списке. Самый левый элемент списка имеет номер 1, следующий — номер 2 и т. д. Номера полей могут использоваться в тех случаях, когда поля, по которым следует упорядочить результат, являются вычисляемыми, а фраза AS с указанием имени этого поля в операторе SELECT отсутствует. Фраза ORDER BY позволяет упорядочить выбранные записи в порядке возрастания (ASC. или убывания (DESC. значений любого поля или комбинации полей, независимо от того, присутствуют эти поля в таблице результатов или нет.

select orderno, totalprice, dateorder
from orders
where dateorder between '20.05.2005' and '17.08.2005'
order by dateorder desc

Результат:

ORDERENO TOTALPRICE DATEORDER
456218953 182.00 16.06.2005 0:00:00
Order3 0.00 16.06.2005 0:00:00
28949 8752.33 29.07.2005 0:00:00

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

select orderno, totalprice, dateorder
from orders
where dateorder between '20.05.2005' and '17.08.2005'
order by dateorder desc, totalprice asc

Результат:

ORDERNO TOTALPRICE DATEORDER
Order3 0.00 16.06.2005 0:00:00
456218953 182.00 16.06.2005 0:00:00
28949 8752.33 29.05.2005 0:00:00

Использование обобщающих функций языка SQL

Стандарт ISO содержит определение следующих пяти обобщающих функций:

Таблица 0.0. Обобщающие функции}

Функция Описание
COUNT Возвращает количество значений в указанном поле
SUM Возвращает сумму значений в указанном поле
AVG Возвращает усредненное значение в указанном поле
MIN Возвращает минимальное значение в указанном поле
МАХ Возвращает максимальное значение в указанном поле

Все эти функции оперируют со значениями в единственном поле таблицы и возвращают единственное значение. Функции COUNT, MIN и МАХ применимы как к числовым, так и к нечисловым полям, тогда как функции SUM и AVG могут использоваться только в случае числовых полей. За исключением COUNT(*), при вычислении результата любых функций сначала исключаются все пустые значения, после чего требуемая операция применяется только к оставшимся конкретным значениям поля. Вариант COUNT(*) является особым случаем использования функции COUNT — его назначение состоит в подсчете всех строк в результирующей таблице, независимо от того, содержатся там пустые, дублирующиеся или любые другие значения.

select count(*)
from orders

Результат:

COUNT
24

Если до применения обобщающей функции необходимо исключить дублирующиеся значения, следует перед именем поля в определении функции поместить ключевое слово DISTINCT. Стандарт ISO допускает использование ключевого слова ALL с целью явного указания того, что исключение дублирующихся значений не требуется, хотя это ключевое слово подразумевается по умолчанию, если никакие иные определители не заданы. Ключевое слово DISTINCT не имеет смысла для функций MIN и МАХ. Однако его использование может оказывать эффект на результаты выполнения функций SUM и AVG, поэтому следует заранее обдумать, должно ли оно присутствовать в каждом конкретном случае. Кроме того, ключевое слово DISTINCT в каждом запросе может быть указано не более одного раза.

select min(totalprice), max(totalprice), avg(totalprice)
from orders

Результат:

MIN MAX AVG
0.00 765.56 91.13

Очень важно отметить, что обобщающие функции могут использоваться только в списке предложения SELECT и в составе предложения HAVING. Во всех других случаях использование этих функций недопустимо. Если список в предложении SELECT содержит обобщающие функции, а в тексте запроса отсутствует фраза GROUP BY, обеспечивающая объединение данных в группы, то ни один из элементов списка предложения SELECT не может включать каких-либо ссылок на колонки, за исключением случая, когда эта колонка используется как аргумент обобщающей функции. Например, следующий запрос является некорректным:

select orderno, count(*)
from orders

Ошибка состоит в том, что в данном запросе отсутствует фраза GROUP BY, а обращение к полю ORDNO выполняется без применения обобщающей функции.

Группирование результатов

Приведенные выше примеры сводных данных подобны итоговым строкам, обычно размещаемым в конце отчётов. В итогах все детальные данные отчёта сжимаются в одну обобщающую строку. Однако очень часто в отчётах требуется формировать и промежуточные итоги. Для этой цели в операторе SELECT может указываться фраза GROUP BY. Запрос, в котором присутствует фраза GROUP BY, называется группирующим запросом, поскольку в нём группируются данные, полученные в результате выполнения операции SELECT, после чего для каждой отдельной группы создается единственная суммарная строка. Поля, перечисленные во фразе GROUP BY, называются группируемыми полями. Стандарт ISO требует, чтобы предложение SELECT и фраза GROUP BY были тесно связаны между собой. При использовании в операторе SELECT фразы GROUP BY каждый элемент списка в предложении SELECT должен иметь единственное значение для всей группы. Более того, предложение SELECT может включать только следующие типы элементов:

  • имена полей;
  • обобщающие функции;
  • константы;
  • выражения, включающие комбинации перечисленных выше элементов.

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

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

Например, необходимо определить количество заказов, оформленных в определённый день:

select dateorder, count(*)
from orders
group by dateorder

Результат:

DATEORDER COUNT
17.10.2004 0:00:00 1
01.09.2005 0:00:00 2
16.09.2005 0:00:00 3
19.09.2005 0:00:00 2

Ограничения на выполнение группирования (фраза HAVING)

Фраза HAVING предназначена для использования совместно с фразой GROUP BY для задания ограничений, указываемых с целью отбора тех групп, которые будут помещены в результирующую таблицу запроса. Хотя фраза HAVING и предложение WHERE имеют сходный синтаксис, их назначение различно. Предложение WHERE предназначено для фильтрации отдельных строк, используемых для группирования или помещаемых в результирующую таблицу запроса, тогда как фраза HAVING используется для фильтрации групп, помещаемых в результирующую таблицу запроса. Стандарт ISO требует, чтобы имена полей, используемые во фразе HAVING, обязательно присутствовали в списке фразы GROUP BY или применялись в обобщающих функциях. На практике условия поиска во фразе HAVING всегда включают, по меньшей мере, одну обобщающую функцию, в противном случае эти условия поиска должны быть помещены в предложение WHERE и для отбора отдельных строк (Не забывайте, что обобщающие функции не могут использоваться в предложении WHERE..

Например, необходимо определить даты, когда было оформлено более пяти заказов:

select dateorder, count(*)
from orders
group by dateorderdate
having count(*) > 5

Фраза HAVING не является необходимой частью языка SQL — любой запрос, написанный с использованием фразы HAVING, может быть представлен в ином виде, без её применения.

Подзапросы

Рассмотрим использование законченных операторов SELECT, внедренных в тело другого оператора SELECT. Внешний (второй) оператор SELECT использует результат выполнения внутреннего (первого) оператора для определения содержания окончательного результата всей операции. Внутренние запросы могут быть помещены в предложения WHERE и HAVING внешнего оператора SELECT — в этом случае они получают название подзапросов, или вложенных запросов. Кроме того, внутренние операторы SELECT могут использоваться в операторах INSERT, UPDATE и DELETE. Существует три типа подзапросов. Скалярный подзапрос возвращает значение, выбираемое из пересечения одного поля с одной строкой, то есть, единственное значение. В принципе, скалярный подзапрос может использоваться везде, где требуется указать единственное значение.

Определим список фурнитуры ROTO:

select name, price
from orderitems
where orderid =
 (select orderid 
  from orders
  where orderno = 'Order2')

Результат:

NAME PRICE
Order2-1 673.27
Order2-2 0.00
Order2-3 412.34
Order2-4 0.00
Order2-7 1234.38

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

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

К подзапросам применяются следующие правила и ограничения:

  1. В подзапросах не должна использоваться фраза ORDER BY, хотя она может присутствовать во внешнем запросе.
  2. Список в предложении SELECT подзапроса должен состоять из имен отдельных полей или составленных из них выражений — за исключением случая, когда в подзапросе используется ключевое слово EXISTS.
  3. По умолчанию имена полей в подзапросе относятся к таблице, имя которой указано в его предложении FROM. Однако допускается ссылаться и на поля таблицы, указанной во фразе FROM внешнего запроса, для чего используются квалифицированные имена полей.
  4. Если подзапрос является одним из двух операндов, участвующих в операции сравнения, то запрос должен указываться в правой части этой операции.


Ключевые слова ANY и ALL

Ключевые слова ANY и ALL могут использоваться с подзапросами, возвращающими один столбец чисел. Если подзапросу будет предшествовать ключевое слово ALL, условие сравнения считается выполненным только в том случае, если оно выполняется для всех значений в результирующем столбце подзапроса. Если записи подзапроса предшествует ключевое слово ANY, то условие сравнения будет считаться выполненным, если оно выполняется хотя бы для одного из значений в результирующем столбце подзапроса. Если в результате выполнения подзапроса будет получено пустое значение, то для ключевого слова ALL условие сравнения будет считаться выполненным, а для ключевого слова ANY — невыполненным. Согласно стандарту ISO дополнительно можно использовать ключевое слово SOME, являющееся синонимом ключевого слова ANY.

Многотабличные запросы

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

Если необходимо получить информацию более чем из одной таблицы, то можно либо применить подзапрос, либо выполнить соединение таблиц. Если результирующая таблица запроса должна содержать поля из разных исходных таблиц, то целесообразно использовать механизм соединения таблиц. Для выполнения соединения достаточно в предложении FROM указать имена двух и более таблиц, разделив их запятыми, после чего включить в запрос предложение WHERE с определением полей, используемых для соединения указанных таблиц. Кроме того, вместо имен таблиц можно использовать назначенные им в предложении FROM псевдонимы (алиасы). В этом случае имена таблиц и назначаемые им псевдонимы должны разделяться пробелами. Псевдонимы могут использоваться с целью квалификации имен полей во всех тех случаях, когда возможно появление неоднозначности. Кроме того, псевдонимы могут использоваться как сокращения имен таблиц. Если для таблицы определён псевдоним, он может использоваться в любом месте, где требуется указание имени этой таблицы.

Составим список заказчиков:

select cu.customerid, cu.deleted, ca.name, ca.inn
from customers cu, contragents ca
where ca.contragid = cu.customerid

Результат:

CUSTOMERID DELETED CO_NAME INN
3002   ООО «Алиса» 456853753875496
3003 20.09.2004 Сидоров П. В. 753862165135796
3004   Вирта 224951373337954

Чаще всего многотабличные запросы выполняются для двух таблиц, соединенных связью типа 1:М (один ко многим). Пары строк, которые генерируются при выполнении запроса, представляют собой результат всех допустимых комбинаций строк дочерней и родительской таблиц. Таблица, содержащая внешний ключ, обычно является дочерней, как таблица, содержащая первичный ключ, всегда будет родительской. Для использования связи типа «родительская-дочерняя» в SQL-запросе необходимо указать условие поиска, в котором будут сравниваться внешний и первичный ключи.


Изменение содержимого базы данных

Язык SQL является полнофункциональным языком манипулирования данными, который может использоваться не только для выборки данных из базы, но и для изменения её содержимого. Операторы модификации информации в базе данных не столь сложны, как оператор SELECT. Рассмотрим три оператора языка SQL, предназначенных для модификации содержимого базы данных:

  • INSERT — предназначен для добавления данных в таблицу.
  • UPDATE — предназначен для модификации уже помещенных в таблицу данных.
  • DELETE — позволяет удалять из таблицы строки данных.
Добавление новых данных в таблицу (оператор INSERT)

Существует две формы оператора INSERT. Первая предназначена для вставки единственной строки в указанную таблицу. Эта форма оператора INSERT имеет следующий формат:

insert into <имя_таблицы>
[(<список_полей>)]
values (<список_значений>)

Здесь параметр <имя_таблицы> может представлять либо имя таблицы базы данных, либо имя обновляемого представления. Параметр <список_полей> представляет собой список, состоящий из имен одного или более полей, разделенных запятыми. Параметр <список_полей> является необязательным. Если он опущен, то предполагается использование списка из имен всех полей таблицы, указанных в том порядке, в котором они были описаны в операторе CREATE TABLE. Если в операторе INSERT указывается конкретный список имен полей, то любые опущенные в нём поля должны быть объявлены при создании таблицы как допускающие значение NULL, за исключением случаев, когда при описании поля использовался параметр DEFAULT. Параметр <список_значений> (cписок значений данных) должен соответствовать параметру <список_полей>.

  • количество элементов в обоих списках должно быть одинаковым;
  • должно существовать прямое соответствие между позицией одного и того же элемента в обоих списках, поэтому первый элемент списка <список_значений> полагается относящимся к первому элементу списка <список_полей>, второй элемент списка <список_значений> — ко второму элементу списка <список_полей> и т. д.;
  • типы данных элементов списка values должны быть совместимы с типом данных соответствующих столбцов таблицы.

Другая форма оператора INSERT имеет следующий вид:

insert into <имя_таблицы1>
(<список_полей1>)
select <список_полей2>
from <имя_таблицы2>

Здесь параметры <имя_таблицы> и <список_полей> имеют тот же формат и смысл, что и при вставке в таблицу одной строки. Предложение SELECT может представлять собой любой допустимый оператор SELECT. Строки, вставляемые в указанную таблицу, в точности соответствуют строкам результирующей таблицы, созданной при выполнении вложенного запроса. Все ограничения, указанные выше для первой формы оператора INSERT, применимы и в этом случае.

Модификация данных в базе (оператор UPDATE)

Оператор UPDATE позволяет изменять содержимое уже существующих строк указанной таблицы. Этот оператор имеет следующий формат:

update <имя_таблицы>
set <имя_поля1> = <значение1> [, <имя_поля2> = <значение2> ]
[where <условие_отбора>]

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

Удаление данных из базы (оператор DELETE)

Оператор DELETE позволяет удалять строки данных из указанной таблицы. Этот оператор имеет следующий формат:

delete from <имя_таблицы>
[where <условие_отбора>]

Как и в случае операторов INSERT и UPDATE, параметр <имя_таблицы> может представлять собой либо имя таблицы базы данных, либо имя обновляемого представления. Если предложение WHERE присутствует, из таблицы будут удалены только те строки, которые удовлетворяют условию отбора, заданному параметром <условие_отбора>. Но если параметр <условие_отбора> опущен, из таблицы будут удалены все существующие в ней строки.

Например, необходимо удалить группу ветровой нагрузки с идентификатором 1.

delete from orders
where orderid = 1

Сама по себе таблица с помощью оператора DELETE не удаляется. Если необходимо удалить не только содержимое таблицы, но и её определение, следует использовать оператор DROP TABLE.


Дополнительные объекты altAwin

TawModelView (конструкция/изделие)

Данный компонент применяется для вывода изображения конструкций. У компонента имеются следующие свойства:

Свойство Описание
Data: String Источник данных об изображении. Берется из поля PACKINFO таблицы ORDERITEMS; устанавливается только в скрипте.
ModelNo: Integer Указывает, какое изделие конструкции следует выводить. Если указано значение 0, то выводится конструкция целиком.
Colored: Boolean Данный переключатель указывает, делать изображение цветным или нет.
ArrowStatus: TawArrowStatus Тип выводимых размеров.
  • astAxial: осевые, работает только для изделий;
  • astOverall: габаритные, работает только для всей конструкции;
  • astWing: по створкам, работает только для изделий;
  • astWingImp (для наклонных импостов указываются размеры от створки, в остальных случаях — от рамы): по створкам + расстояния до импостов в створках, работает только для изделий;
  • astFill: по заполнениям, работает только для изделий;
  • astFold: фальцевые рамы, работает только для изделий;
  • astHole: до дырок, для стеклопакетов, работает только для изделий;
  • astNone: без размеров.
MultipleArrow (работает только с astAxial и astHole) Рисование размеров «лесенкой».
MarkModel: Boolean Вывод нумерации изделия в конструкции.
MarkBeam: Boolean Вывод маркировки балок.
MarkDrob: Boolean Вывод нумерации дробов.
MarkDropType: TawMarkDrobType Способ маркировки створок.
  • mdtBoth:
  • mdtPart: часть изделия
  • mdtGlass: марк. стеклопакета
SelectedBeam: String Указывает маркировку балки, которую необходимо отрисовывать выделенной (через точку с запятой можно указать несколько балок). Если свойство {{{1}}}, выделенная балка будет заполнятся цветом TWindowPainter.ColorSelect, в противном случае - чёрным.
WithConn: Boolean Вывод изделия с соединителями.

TawWeldingView (сварка)

Свойство Описание
Data: String Источник данных об изображении. Берется из поля ADDITIONAL таблицы ITEMSDETAIL. Задается значением (СВАРКА) поля «Дополнительно» в документе «Значение состава». Устанавливается только в скрипте.
ByFold: Boolean Указывает, рисовать от фальца или нет.

TawNonRectGlassView (непрямоугольное заполнение)

Данный компонент применяется для вывода непрямоугольных заполнений конструкций и изделий со шпросами. У компонента имеются следующие свойства:

Свойство Описание
Data: String Источник данных об изображении. Берется из поля PACKINFO таблицы ORDERITEMS; устанавливается только в скрипте.
ModelNo: Integer Указывает, какое изделие конструкции следует выводить. Если указано значение 0, то выводится конструкция целиком.
NonRectGlassNo: Integer Номер непрямоугольного заполнения.
Colored: Boolean Данный переключатель указывает, делать изображение цветным или нет.
MultipleArrow: Boolean Рисование размеров «лесенкой».
MarkModel: Boolean Вывод нумерации изделия в конструкции.
MarkGlass: Boolean Вывод маркировки заполнений и названий стеклопакета.
DrawSizes: Boolean Рисовать размеры
AngularLines: Boolean Рисовать угловые размеры, по умолчанию True


TawFillingElementView (заполнение)

Свойство Описание
Data: String Строка с запакованной информации о конструкции (PACKINFO)
ElementUID: Integer Идентификатор элемента
Colored: Boolean Отрисовка в цвете
DrawSizes: Boolean Отрисовка размеров
MutipleArrows: Boolean Отрисовка размеров лесенкой
MarkModel: Boolean Отрисовка обозначений изделий в конструкции
MarkGlass: Boolean Отрисовка обозначений заполнений
AngularLines: Boolean Отрисовка размеров углов

TawComplexBendView (сложный изгиб)

Свойство Описание
Data: String Источник данных об изображении. Берется из поля PACKINFO таблицы ORDERITEMS; устанавливается только в скрипте.
ModelNo: Integer Указывает, какое изделие конструкции следует выводить. Если указано значение 0, то выводится конструкция целиком.
BendNo: Integer Номер изгиба в изделии.

TawLayoutCuttingView (карта распила стекла)

Свойство Описание
Data: String Берется из поля DATAPIECE таблицы OPTDATA, устанавливается только в скрипте
Colored: Boolean Данный переключатель указывает, делать изображение цветным или нет.

TawUserRegistry ()

Свойство Описание
function ReadString (const Section, Ident, Default: string): String Возвращает строковое значение ключа Ident из ветки Section, в случае отсутствия - возвращает значение заданное параметром Default
function ReadInteger (const Section, Ident: string; Default: Integer): Integer Возвращает целочисленное значение ключа Ident из ветки Section, в случае отсутствия - возвращает значение заданное параметром Default
function ReadBool (const Section, Ident: string; Default: Boolean): Boolean Возвращает булево значение ключа Ident из ветки Section, в случае отсутствия - возвращает значение заданное параметром Default
procedure WriteInteger (const Section, Ident: string; Value: Integer) Записывает целочисленное значение для ключа Ident из ветки Section, заданное параметром Value
procedure WriteString (const Section, Ident, Value: string) Записывает строковое значение для ключа Ident из ветки Section, заданное параметром Value
procedure WriteBool (const Section, Ident: string; Value: Boolean) Записывает булево значение для ключа Ident из ветки Section, заданное параметром Value
procedure ReadSection (const Section: string; Strings: TStrings) Считывает наименования ключей ветки Section в параметр Strings
procedure ReadSections (Strings: TStrings) Считывает наименования дочерних веток ветки Section в параметр Strings
procedure ReadSectionValues (const Section: string; Strings: TStrings) Считывает значения ключей ветки Section в параметр Strings
procedure EraseSection (const Section: string) Удаляет ветку Section
procedure DeleteKey (const Section, Ident: string) Удяляет ключ Ident из ветки Section

TConstrInfo (информация о конструкции)

Свойство Описание
AreaConstr: Extended Площадь конструкции
AreaModel: Extended Площадь изделия, заданного свойством ModelNo
AreaModelsOnly: Extended Площадь конструкции без учёта соединителей
CurvedBalkaNo: Integer
FurnitureConstr: String Названия систем фурнитуры конструкции, разделенные символом ", "
FurnitureModel: String Название системы фурнитуры изделия, заданного свойством ModelNo
GlassAreaConstr: Extended Площадь заполнения конструкции, заданного свойством GlassNo
GlassAreaModel: Extended Площадь заполнения изделия, заданного свойствами ModelNo и GlassNo
GlassCountConstr: Integer Количество заполнений в конструкции
GlassCountModel: Integer Количество заполнений в изделии, заданного свойством ModelNo
GlassesConstr: String Перечень названий заполнений конструкции, разделенных символом ", "
GlassesModel: String Перечень названий заполнений изделия, заданного свойством ModelNo, разделенных символом ", "
GlassNo: Integer Номер заполнения, начиная с 1
HeightConstr: Extended Габаритная высота конструкции с учётом соединителей/расширителей
HeightModel: Extended Высота изделия, заданного свойством ModelNo
InColorConstr: String Внутренние цвета конструкции, разделенные символом ", "
InColorGroupModel: String Категория внутреннего цвета изделия, заданного свойством ModelNo
InColorModel: String Внутренний цвет изделия, заданного свойством ModelNo
ItemTypeNameModel: String Название типа изделия, заданного свойством ModelNo
Model: String Источник данных о конструкции. Берется из поля PACKINFO таблицы ORDERITEMS.
ModelNo: Integer Номер изделия, начиная с 1
NonRectGlassNo: Integer
OpenType: Integer Тип открывания створки, заданной свойствами ModelNo и WingNo
OutColorConstr: String Внешние цвета конструкции, разделенные символом ", "
OutColorGroupModel: String Категория внешнего цвета изделия, заданного свойством ModelNo
OutColorModel: String Внешний цвет изделия, заданного свойством ModelNo
QtyCurvedBlkConstr: Integer Количество изогнутых балок в конструкции
QtyCurvedBlkModel: Integer Количество изогнутых балок в изделии, заданного свойством ModelNo
QtyJoinImpost: Integer Количество импостов, входящих в балку, определяется из поля Welding, содержащего информацию о сварке.
QtyModelsInConstr: Integer Количество изделий в конструкции
QtyNonRectInConstr: Integer Количество непрямоугольных заполнений в конструкции
QtyNonRectInModel: Integer Количество непрямоугольных заполнений в изделии, заданного свойством ModelNo
SysProfConstr: String Названия систем профиля конструкции, разделенные символом ", "
SysProfModel: String Название системы профиля изделия, заданного свойством ModelNo
SysProfTypeModel: Integer Тип системы профиля изделия, заданного свойством ModelNo
Welding: String Информация о сварке. Берется из поля ADDITIONAL таблицы ITEMSDETAIL.
WidthConstr: Extended Габаритная ширина конструкции с учётом соединителей/расширителей
WidthModel: Extended Ширина изделия, заданного свойством ModelNo
WingCountInModel: Integer Количество створок в изделии, заданного свойством ModelNo
WingHeight: Extended Высота створки по габариту, заданной свойствами ModelNo и WingNo
WingNo: Integer Номер створки в изделии, заданного свойством ModelNo, начиная с 1
WingWidth: Extended Ширина створки по габариту, заданной свойствами ModelNo и WingNo

Дополнительные функции altAwin

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

Математические функции

Функция Описание
Sign(X) Возвращает −1 при отрицательном X, 1 при положительном и 0, если X равен 0.
RoundTo(Value, Digit) Округляет Value до Digit знаков после запятой.
Power(Base, Exponent) Возводит Base в степень Exponent.
Cot(X) Вычисляет котангенс X радиан.
ArcSin(X) Вычисляет арксинус X и возвращает значение в радианах.
ArcCos(X) Вычисляет арккосинус X и возвращает значение в радианах.
ArcCot(X) Вычисляет арккотангенс X и возвращает значение в радианах.
DegToRad(X) Вычисляет значение X градусов в радианах.
RadToDeg(X) Вычисляет значение X радиан в градусы.
Total(A) Вычисляет сумму элементов массива A.
MaxValue(A) Возвращает максимальное значение элемента в массиве A.
MinValue(A) Возвращает минимальное значение элемента в массиве A.
Mean(A) Вычисляет среднее значение элементов в массиве A.


Функции для работы с БД

Функция Описание
IsDatabaseConnected Возвращает true при наличии подключения и прав для работы с БД.
ExecuteSQL(SQL) Выполняет SQL-запрос.
QueryField(SQL) Возвращает первое поле из запроса.
QueryRow(SQL) Возвращает первую запись из запроса (объект типа Record).
QueryTable(SQL) Возвращает результат запроса (объект типа List, содержащий объекты типа Record).
DatabaseType Возвращает тип БД.


Функции для работы со скриптами

Функция Описание
Evaluate(Expression) Вычисляет значение выражения Expression.
Execute(Source) Выполняет код Source. Синтаксис кода Source должен соответствовать синтаксису кода, из которого вызывается функция.


Функции управления altAwin

Функция Описание
function SaveAsAttachment(const Document:IdocDocument): Boolean Сохранение текущего сформированного отчёта как вложения к указанному документу по ClassName.
SaveThumbnail(OrderItemsId, ModelNo, Filename) Сохранение изображения изделия ModelNo в конструкции OrderItemsId в файл Filename. Если ModelNo равно нулю, то сохраняется вся конструкция.
SetOrderState(OrderId, Status) Установка статуса Status заказу OrderId
CheckOrdersWinMails Проверка новых писем с заказами для импорта.
CheckOrdersGlassMails Проверка новых писем с заказами стеклопакетов.
CreateOrderItemStatuses(OrderId) Создание таблицы статусов изделий в заказе.
SetModelItemStatus(ModelItemsId, Status) Установка статуса Status конструкции ModelItemsId.
CreateStorehouseSupply(Storehouse, Folder, WayBill, Status, SupplyDate) Создание приходной накладной. Storehouse — склад, для которого создается накладная, Folder — папка, в которой будет создана запись, WayBill — номер накладной, Status — статус накладной, SupplyDate — дата заведения накладной.
FillStorehouseSupply(SupplyId, OrderId, ElemTypeId, Quantity, Name) Добавление в накладную записи. SupplyId — идентификатор накладной, возвращаемый предыдущей функцией, OrderId — добавляемый заказ, ElemType — тип записи, Quantity — количество, Name — имя записи.
Encrypt(FileName, Data, Key) Шифрует строку Data ключом Key и записывает результат в файл FileName.
Decrypt(FileName, Key) Дешифрует файл FileName ключом Key.
FullDataBaseExport(FileName) Производит полный экспорт БД в файл FileName.
Logoff Завершение работы altAwin
ExportGlassToDXF(OrderItemsId, FileName) Экспорт координат контура стеклопакета в файл FileName

Функции создания объектов

Функция Описание
NewRecord Создание объекта типа Record. У данного объекта можно определять любые свойства, для доступа к ним следует использовать синтаксис <объект>.<свойство>
NewList Создание объекта типа List.
CopyRecord Копирования записей, созданных с помощью NewRecord

У объекта типа List существуют следующие методы и свойства:

Функция Описание
Add(Item) Добавление элемента Item в список List.
AddFrom(OtherList) Добавление всех элементов из другого списка.
Clear Очистка списка.
Delete(Index) Удаление элемента с номером Index.
Insert(Index, Item) Вставка элемента Item под номером Index в списке.
Swap(I, J) Перестановка элементов I и J.
Count Количество элементов в списке.
Items[Index] Элементы списка.

Функции ввода-вывода

Функция Описание
CurrentLanguage Возвращает текущий язык программы altAwin.
DlgBox(Title, Msg, Buttons) Вывод диалогового окна с заголовком Title, сообщением Msg и списком кнопок. Список задается в квадратных скобках через запятую — ['Да', 'Нет']. Возвращает индекс нажатой кнопки в массиве Buttons;
ShellExecute(FileName, Parameters) Выполняет/открывает файл FileName с параметрами Parameters. Возвращает true в случае успеха.
AnsiToUnicode(FileName) Перекодирует указанный файл из кодировки Ansi в кодировку Unicode.
UnicodeToAnsi(FileName) Перекодирует указанный файл из кодировки Unicode в кодировку Ansi.
LoadFileFromDatabase(FileName) Выполняет загрузку файла FileName из документа файлов
LoadFileFromDatabaseByGUID(GUID) Действие функции аналогично предыдущей, только в качестве параметра используется массив GUID


Прочие функции

Функция Описание
ShowMessage(Msg) Выводит окно с сообщением Msg.
InputBox(Caption, Prompt, Default) Выводит окно, в котором нужно указать какое-либо значение. Caption — заголовок окна, Prompt — предложение, Default — значение по умолчанию.
PromptForFileName(FileName, Filter, DefaultExt, Title, InitialDir, SaveDialog) Открывает диалог открытия (если SaveDialog — false) или сохранения (если SaveDialog — true).

FileName — имя файла по умолчанию;

Filter — строка с типами файлов;

DefaultExt — расширение по умолчанию;

Title — заголовок диалога;

InitialDir — директория по умолчанию.

AssignFile(F, FileName) Создает указатель F на файл FileName и ставит его на начало файла.
CloseFile(F) Закрывает файл с указателем F.
Rewrite(F) Открывает файл для записи, стирая существующие данные.
Reset(F) Открывает файл для чтения.
Append(F) Открывает файл для записи, оставляя существующие данные.
WriteLn(F, P) Записывает в файл F данные P и переводит указатель на следующую строку.
Write(F, P) Записывает в файл F данные P.
ReadLn(F, P) Читает из файла F строку и записывает результат в P.
Read(F, P) Читает из файла F слово и записывает результат в P.
Eof(F) Возвращает true, если указатель файла указывает на символ конца файла.
FileExists(FileName) Проверяет, существует ли файл FileName.
DirectoryExists(Directory) Проверяет, существует ли папка Directory.
ForceDirectories(Dir) Создает директорию, указанную в Dir.
ExtractFileName(FileName) Возвращает собственно имя файла из полного имени файла.
ExtractFilePath(FileName) Возвращает полный путь, по которому расположен файл.
ExtractFileDir(FileName) Возвращает имя директории, в которой лежит файл.
ExtractFileExt(FileName) Возвращает расширение файла.
AnsiToUTF8(S) Перекодирует строку S из кодировки ANSI в кодировку UTF8
UTF8ToAnsi(S) Перекодирует строку S из кодировки UTF8 в кодировку ANSI
FastReportExecuteFile(FileName, ShowPreview, const Params: array of Variant) Обеспечивает вызов отчёта FastReport без контекста. Возвращает True в случае успеха
  • FileName — имя файла отчёта
  • ShowPreview — флаг отображения стандартного предпросмотра FastReport.
  • Params - необязательный параметр. Обеспечивает возможность передавать в отчёт пары Имя/Значение в виде локальных переменных отчёта.

Пример вызова: FastReportExecuteFile('C:/report.fr3', True, ['OrderID', 100, 'ItemID', 20]);

FastReportExecuteStream(FileName, ShowPreview, const Params: array of Variant) Поведение функции аналогично предыдущей. В качестве параметра FileName принимается поток данных (TStream)

1. Для наклонных импостов указываются размеры от створки, в остальных случаях — от рамы. 2. Работает только с astAxial и astHole.