Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Расширенные компоненты

01.01.2007

Компонент FontMaster

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

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

Как замечено ранее, главное назначение FontMaster это установка шрифтов. Он имеет очень мало свойств. Как большинство других компонент, он имеет свойства DevLocked, Locked, Name и Tag. Он также содержит наиболее важное свойство Font.

Для установки свойств FontMaster, используйте свойство Font на панели свойств, нажмите на кнопку эллипса для вызова диалога Font и выберите шрифт и размер. Нажмите OK, когда закончите. Как только компонент FontMaster настроен, связать его с текстом весьма просто. В отчете выберите компонент Text/Memo, затем используя кнопки стрелок вверх/вниз на свойстве FontMirror в панели свойств для выбора связи FontMaster. Любые компоненты, которые имеют установленное свойство FontMirror на FontMaster, будут отрабатывать изменения в сделанные в свойстве Font компоненты FontMaster. Это позволяет пользователю изменять шрифты различных текстовых компонент за раз и в то же самое время хранить однообразность по всему отчету (когда требуется).

Важно заметить, что свойство FontMirror, свойство Font перекрывается свойством Font компонента FontMaster. Это означает, что если текстовый объект имеет свойство Font установленное на Font A, назначение ему FontMaster со шрифтом Font B, текстовый компонент автоматически назначает Font B и его свойство Font игнорируется. Другой побочный эффект использования FontMaster это то, что панель шрифтов запрещается при использовании свойства FontMirror.

Может быть, более одного FontMaster для страницы, хорошей практикой является давать значимые имена для FontMaster. Дерево проектов, показанное ранее, имело три компоненты FontMaster на странице. Две из них начинались с FM, для FontMaster, и далее имя и размер шрифта, которое они представляют. Это одно из соглашений, которое может использоваться для того, чтобы сделать имя описательным для пользователя.

Компонент PageNumInit

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

Примером использования PageNumInit является отчет CustomerStatement Report при сверке счета. Отчет о состоянии, который клиент получает каждый месяц, может иметь переменное количество страниц. Месячный отчет, первая страница может содержать итоговые данные, вторая может данные по кредиту и депозитам, а третья содержать возвраты и дебиты. Первые две могут быть одной страницей, но если активность счета высокая, то секция дебит может занимать несколько страниц. Если пользователь производит отчет то, возможно, он захочет, что бы каждая секция нумеровалась индивидуально, итоги и депозиты маркировались как «1 из 1». А третья часть, может иметь три страницы. Поскольку это отдельная секция отчета, то она может быть маркирована так «1 из  3», «2 из  3» и «3 из 3». При использовании такого типа нумерации страниц PageNumInit может оказаться полезным.

Есть несколько шагов, которые должны быть выполнены, что бы использовать данный компонент эффективно. Сначала определите страницы как обычно. Добавьте компонент DataText из панели отчета на страницу, поместите туда, где должен появиться номер страницы.

После того, как Вы поместили компонент в панели свойств компонента DataText, нажмите на кнопку эллипса в свойстве DataField.

Это откроет редактор DataText. Нажмите на кнопке Report Variables и выберите Relative Page и нажмите кнопку Insert Report Var для использования переменной в отчете. В области DataText, должно появится «Report.RelativePage». После этого введите текст « + ' of ' +».

Из выпадающего списка ReportVariables выберите TotalPages (выберите и нажмите кнопку Insert Report Var). Это добавит оставшийся текст «Report.TotalPages» к области редактирования  Data Text. По окончанию нажмите OK.

Панель свойств теперь показывает текст, введенный в редакторе Data Text.

Расширьте компонент DataText, что бы появился текст из  редактора.

Для инициализации страницы требуемым номером, выберите PageNumInit из дерева проекта. На панели свойств, введите требуемый номер и свойство InitValue.

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

Компонент DataCycle

Компонент

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

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

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

Главная таблица содержит список ID клиентов, допустим, она называется MasterDataView. В панели свойств, это имя главной таблицы должно быть выбрано в свойстве называемом MasterDataView. После выбора, мы должны сообщить Rave, какой ключ будет использован для связи таблиц. Этот ключ называется DetailKey. DetailKey, в нашем примере будет CustomerID. Затем, таблица, которая будет просматриваться в цикле, это таблица, содержащая заказы, это будет таблица DataView. MasterDataView (главная таблица) и DataView (детальная таблица) соединяются по Detail Key (общий уникальный ключ в каждой таблице).

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

Установка MasterKey делается нажатием на кнопку эллипса (…) в свойстве в панели свойств. Будет вызван редактор Data Text. В области Data View, выберите радио кнопку «Selected» и затем выберите нужную MasterDataView таблицу, которая будет главной в нашем примере, и помощью выпадающего меню. Как только закончите, затем выберите поле, которое будет использоваться как фильтр в главной Master Table или MasterDataView таблице. После этого нажмите на кнопку Insert Field, которая покажет выпадающее меню Data Field. Это поместит должный текст в область Data Text, внизу редактора. Теперь в Data Text напечатайте «='AZ'» для ограничения данного поля только клиентами из Аризоны. Нажмите OK, когда будете готовы, это исключит прочих клиентов, не из Аризоны.

Компонент DataMirrorSection

Компонент

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

Пример использует компонент «DataMirrorSection» включенный в RaveDemo файл проекта. Данный пример показывает, как иметь один отчет, производящий различные форматы конвертов при посылке по международным или американским адресам. Шаблон для международных адресов имеет строку страны и центруется на конверте, тогда как американский формат не имеет строки страны и смещен вправо от центра и ниже на конверте.

Данный пример показывает несколько приемов, как использовать зеркальное отражение секции. На странице 2 есть три секции. Секция 3 имеет общих строки адреса в обоих шаблонах. Секция 1 и 2 содержат зеркальное отражение в секцию три. Международная секция имеет дополнительную строку страны, добавленную к своему шаблону. Заметим, что «remarks» было добавлено к странице 2, и оно не является частью, какой либо секции. "US Template" и "International Template" только текстовые примечания, предназначенные для помощи в показе каждой секции.

Для понимания как сделан главный шаблон, перейдите на страницу 1, и выберите "DataMirrorSection". Заметим что, свойства "DataView" и "DataField" были установлены к полю, которое используется для выбора, какой шаблон отражать. Для проверки этой логики, перейдите в свойство "DataMirrors" и нажмите кнопку эллипса для открытия редактора Data Mirror. Выберите каждый элемент "DataMirror" и обратите внимание на установки в нижней части диалога. Данный пример имеет два шаблона "templates", но чувствуйте себя свободно и добавляйте больше для создания сложных требований отчета.

Примечание:

Обычно одна из настроек определяется как «Default». Если «Default» равно NOT и поле не соотносится ни с одной из других установок, тогда формат используется, как если бы был нормальным содержимым компонента DataMirrorSection.

Компонент CalcOp

Компонент CalcOp это невидимый компонент, который позволяет выполнить операции (определенные свойством Operator) на двух значениях из различных источников (Src#CalcVar, Src#DataField или Src#Value). Результат затем сохраняется в параметре проекта,  подобном CalcTotal (через свойства DestParam и DisplayFormat).

Например, есть два компонента DataText, которые должны быть рассчитаны совместно. Например, A+B=C, где A и B представляют два значения, двух компонент DataText, и C представляет результат. Для этого и может использоваться компонент CalcOp.

Выберите два компонента DataText в выше указанном примере, используйте свойства Src1X и Src2X, где X или CalcVar (переменная расчета), DataField, или DataValue. Эти три типа источников значений, которые могут использоваться в расчете в компоненте CalcOp. Заметим, что Src (источник) может быть только одним из трех доступных типов, и может быть только два источника, Src1 или Src2.

Три типа источников имеют много различных ассоциированных с ними. Для источника CalcVar, выпадающее меню показывает список всех переменных доступных на данной странице для использования. Эти расчетные переменные, только переменные для хранения значений. Эти значения могут быть из другого компонента CalcOp или из другого расчетного компонента. Для источника DataField для получения доступных значений сначала определите, из каких DataView/ DataField они приходят. Другими словами DataField это поле в таблице, которая DataView. Для выбора поля, сначала должен быть выбран DataView. Для источника Value, напечатайте числовое значение, это все что требуется для заполнения данного свойства. Again, напоминаем, что только одно из этих трех источников может быть назначено источнику.

После выбора источников, выберите операцию, которая будет использоваться между ними. Для выбора операции, используйте свойство Operator, с помощью выпадающего меню и сделайте нужный выбор. В примере, A+B=C, оператор должен быть «coAdd».

Бывает много случаев, когда необходимая функция должна быть выполнена на значении, перед обработкой второго значения. Здесь есть свойство SrcYFunction, где Y это 1 или 2 для Src1 или Src2. С помощью SrcYFunction, значение может быть конвертировано (например, из часов в минуты), или быть выполнена тригонометрическая функция над ним (например, взять синус от значения), или другие функции выполнены над этим значением (например, взять корень квадратный из значения, или получить абсолютное значение).

После выбора двух значений, самое время подумать о результате. В примере, A+B=C, C это значение результата. Результат может быть или записан в переменную проекта или просто сохраниться как внутреннее значение. Для записи в параметр, используйте свойство DestParam для выбора должного параметра, в который записать результат. Если результат сохраняется как внутреннее значение, ничего не делать, иначе выберите компонент. Усилено рекомендуется переименовать компонент, так что бы он отражал суть, легче будет использовать в будущем.

После установки значений и установки места для результата, возможно, потребуется форматировать результат или даже выполнить функцию, над результатом. Используйте свойства DisplayType и DisplayFormat для форматирования результата в подходящий формат. Имеются два значения для DisplayType - DateTimeFormat и NumericFormat. DisplayFormat имеет много параметров, которые должны быть указаны в поле редактирования. Что бы найти эти значения смотрите «Приложение A. Форматирование», в конце данного руководства. Подобно двум значениям, A и B, в примере, A+B=C, над результатом C также можно выполнить функцию, перед записью в параметр или сохранить значение. Для выбора функции, используйте выпадающее меню свойства ResultFunction.

Компоненты CalcOp могут подключаться в цепочки для получения более сложных выражений, используя свойства Src#CalcVar, которые могут быть назначены другим CalcOp или CalcTotal компонентам. Например, чтобы создать сложное выражение, показанное на рисунке справа, надо его разделять на шаги с двумя простыми значениями.

Для разделения сложного выражения на четыре простых, надо их создать и сохранить как компоненты CalcOp. Для Z, Y, X и W должно быть четыре промежуточных компоненты CalcOp. Но, как вы видите из диаграммы выражения, Z и Y должны быть выполнены до X, поскольку он зависит от выполнения двух предыдущих операций. И, наконец, W должен быть выполнен после X, для получения правильного конечного результата.

Так как важно выполнять вычисления в должном порядке, важно убедиться в каком порядке они будет в дереве проекта. При выполнении отчета, отчет будет выполнять вычисления в порядке их следования в дереве проекта. Для компонент CalcOp или других расчетных компонент. В примере выше, если Z, Y, X, и W находятся в дерева проекта,  Z должен быть первым в дереве и W должен быть последним в дереве. Это означает, что они должны быть в правильном порядке. Это означает, что Z будет обрабатываться первым, затем Y и так далее. Так же важно отметить, что если Z зависит от других компонент (подобно другим компонентам CalcOp или DataText), эти компоненты должны быть выше в дереве проекта. Убедитесь что компоненты в правильном порядке. Для перемещения компонент вверх/вниз в дереве проекта, используйте панель выравнивания для изменения порядка печати компонент.

Компонент CalcController

Компонент

CalcController это невидимый компонент, который действует как диспетчер, вместе с DataBand, для компонент CalcText и CalcTotal через их свойства Controller. Когда компонент диспетчера печатается, он сигнализирует всем вычисляемым компонентам, что управляет выполнением ими функций суммирования. Это позволяет выполнять итоги для групп, детальных групп или целых страниц,  в зависимости от позиции компонента CalcController. Другой характеристикой компонента CalcController является его способность инициализировать компоненты CalcText или CalcTotal специфическим значением (через свойства InitCalcVar, InitDataField и InitValue). Компонент CalcController только инициализирует значения, если они использованы в свойстве Initializer свойств CalcText или CalcTotal.

Компонент CalcTotal

Компонент

CalcTotal это невидимая версия компонента CalcText. Когда этот компонент печатается, его значения обычно записываются в параметры проекта (определенные в свойстве DestParam) и форматируются согласно свойству DisplayFormat. Это может быть полезным при выполнении итоговых вычислений,  которое будет использовано другими вычислениями прежде, чем напечатано. Оставьте DestParam пустым, если значение CalcTotal будет использовано только компонентами, такими как CalcOp.

Упражнение 25: использование компонента Font Master

1.создайте новую страницу в отчете. Выберите New Report Page в окне проекта;
2.перейдите в дерево проекта и выберите страницу;
3.в панели свойств, введите «FontMaster» в свойстве Name, пока выбрана страница;
4.перейдите в панель стандартных компонент. Найдите компонент FontMaster и нажмите на кнопку. Затем нажмите на страницу;
5.посмотрите в панели дерева проекта и обратите внимание, что появился новый компонент в объекте Page названный FontMaster1. Но, когда Вы посмотрите на страницу, то здесь не будет визуальных компонент. FontMaster это невидимый компонент;
6.убедитесь, что компонент FontMaster выделен, нажав на него в дереве проекта. Компонент будет подсвечен, показывая, что он выделен.;
7.пока компонент FontMaster выбран, посмотрите в панели свойств. В свойстве Font, нажмите на кнопку эллипса (кнопка с тремя точками);
8.после нажатия на кнопку эллипса, появится диалог Font. Сделайте свой выбор, используя кнопки перемещения и поля для отметок. Для первого компонента FontMaster, установите Arial Font, Bold, размер 14 и Underline в Effects;
9.посмотрите в панели свойств, пока компонент еще выбран. Свойство Font отразило ваш выбор сделанный в диалоге Font;
10.теперь, пока свойство Font еще выбрано, переместитесь на свойство Name и установите "FMArial14BldUndrln" в поле ввода имени;
11.следующий взгляд на дерево проекта показывает изменение имени. Полезно и нужно, переименовывать компоненты в дереве проекта, для того, что бы отличать один компонент от другого. Поэтому мы продемонстрировали переименование компонент FontMaster и Page;
12.теперь, три раза повторите шаги с 4 по 11, используя различные имена и установки. FMArial16ItlcUndrln: Arial, 16, Italic и Underlined. FMTimesNwRmn12: Times New Roman, 12. FMCourier12: Courier, 12. для понимания переименуйте компоненты, согласно соглашениям об именовании. В данных примерах мы использовали эти соглашения, для именования FontMaster компонент;
13.Далее, бросить пять компонент Text на страницу, а также один компонент Memo;
14.Мы будем писать «письмо», используя брошенные на страницу компоненты;
15.используем один компонент Text, для поля даты и другие четыре для  адреса. Компонент Memo мы будем использовать для текста письма. Поэтому заполните ваши компоненты соответственно. Более подробно о том, как заполнять компоненты вашим текстом смотрите описание свойства «Description Listing» в «Приложение C. Описание свойств», или смотрите главу «9. Стандартные компоненты». Стремитесь использовать панель выравнивания для корректного выравнивания компонент «письма». Также, возможно потребуется изменить размеры компонент для полного отображения текста;
16.затем, выберите компонент Text, который будет содержать дату. Пока еще выбрано измените свойство FontMirror компонента FMCourier12 с помощью выпадающего меню. Обратите внимание, что шрифт изменился на предустановленный в FMCourier12;
17.затем выберите четыре компоненты Text, которые предназначены для адреса. Панель свойств покажет, что это множественный выбор. В свойстве FontMirror, выберите FMTimesNwRmn12;
18.выберите компонент Memo, который будет содержать текст «письма». Пока выбрано, выберите FMArial16ItlcUndrln в выпадающем меню FontMirror;
19.это заканчивает зеркальное отражение шрифтов на страницу. Последняя вещь объясняет, что нужно сделать, когда Вы пожелаете изменить шрифты;
20.выберите все компоненты для адреса. Измените свойство FontMirror FMArial14BldUndrln. Теперь, это можно использовать для изменения шрифта у многих компонент Text/Memo с одной установки на другую без изменения свойства Font у каждого компонента;
21.Иногда может быть много компонентов связанных с одним компонентом FontMirror, поскольку все они имеют отношение к одной специфической области отчета. В этом примере, мы можем предположить, что все заголовки адреса должны быть связаны с одним свойством FMArial14Bldunderln, через свойство Font Mirror. Так, , чтобы изменять это мы должны переделать только одно свойство FontMirror;
22.выберите FMArial14BldUnderln компонент FontMirror в дереве проекта;
23.в панели свойств, пока компонент выбран, нажмите на кнопку эллипса;
24.измените в диалоге Font следующие свойства: Times New Roman, 10, по other Font Effects;
25.в свойстве Name свойства FontMirror, введите следующее имя: FMTimesNwRmn10.

Упражнение 26: настройка компонента PageNumInit для нумерации

1.сначала создайте новую страницу, или используйте ту, которая осталась от предыдущего примера. Если это новая страница, бросьте несколько компонент Text на нее. Это просто компоненты для примера.
2.перейдите в панель отчета и найдите компонент Data Text. Нажмите на него и затем нажмите на странице.
3.поместите компонент DataText в область, в которой должен быть номер страницы, например, в самом низу страницы.
4.убедитесь, что компонент размещен корректно и выбран. Проверь выбор путем визуального наблюдения, вокруг компонента должна быть рамка с зелеными маркерами, или компонент должен быть подсвечен в дереве проекта.
5.Пока компонент выбран, перейдите в панель свойств и посмотрите свойство DataField. Нажмите на копку эллипса.
6.должен появится редактор Data Text. Посмотрите в редакторе на секцию "Report Variables".
7.теперь, помощью стрелок перейдите в конец Report Variables. Щелкните на нем и посмотрите все доступные элементы. Использую линейку прокрутки, перемещайтесь вверх/вниз по меню.
8.в секции Report Variables, посмотрите на "Relative Page". Выберите ее.
9.затем нажмите на кнопку Insert Report Var, справа от секции Report Variables. Это поместит подходящий текст в области Data Text, внизу редактора Data Text.
10.перейдите в область Data Text и напечатайте следующее: « + 'of' + ». Включая пробелы до и после каждого символа.
11.теперь возвратитесь в выпадающий список Report Variables. Прокрутите, пока не найдете TotalPages. Выберите этот элемент.
12.надмите на кнопку Insert Report Var, для вставки в область Data Text. «Report.TotalPages» будет добавлено в эту область.
13.Нажмите OK, когда будете готовы. Ваша область DataText выглядит следующим образом.
14.после нажатия OK, Вы возвратитесь в панель свойств. Если ВЫ расширите панель свойств и посмотрите на свойство DataField, Вы увидите результат DataText полученный из редактора Data Text.
15.на странице, компонент DataText будет выглядеть как A ниже. Если вы расширите рамки компонента DataText (как в B), Вы увидите, что появится результат из редактора Data Text. В действительности не необходимости расширять компонент; это мы сделали, для того, что бы посмотреть в данном упражнении.
16.Осталась еще одна вещь, для окончания нумерации страницы, мы должны инициализировать страницу требуемым номером. Для этого перейдите в дерево проекта и найдите компонент PageNumInit. Выберите его.
17.пока компонент PageNumInit еще выбран, перейдите в панель свойств и найдите свойство InitValue.
18.в свойстве InitValue введите число, это означает, что нумерация наших страниц начитается с единицы.
19.это все, что нужно для настройки PageNumInit. Отметим, что каждый отчет нумеруется независимо от другого отчета.