Исследование классов в проекте отчета Rave Report
Для работы с отчетами в RunTime потребуется, знание имен подключаемых модулей
в раздел uses, создаваемого проекта. Ниже представлена таблица описания основных
модулей, которые могут понадобятся для работы с отчетом Rave в RunTime.
Примечание: Для разработчиков CLX приложений название модулей почти идентично,
только в имени модуля предшествует символ «Q». Например: QRvCsBars. Все модули
находятся в каталоге «\Rave5\Lib» куда установлена среда программирования Delphi
7. Имя модуля Описание модуля RvClass Этот модуль содержит реализацию базовых классов RvProj В этом модуле набор классов реализующие собственно сам проект отчета и отвечающих за работу с ним RvCsDraw Классы в этом модуле реализуют графические примитивы RvCsBars В этом модуле реализованы штриховые коды RvCsStd В этом модуле реализуются основные элементы оформления отчета RvCsRpt, Набор классов в данном модуле служит для вывода данных из RvCsData баз данных или других источников данных
Примечание: В качестве файла отчета взят уже готовый демонстрационный пример
отчета RaveDemo.rav, поставляемый с генератором отчета Rave Report, который
находится в каталоге «\Rave5\Demos». Поэтому следует указать полный путь к файлу
отчета или скопировать данный файл в каталог с текущим проектом.
И так, осталось выяснить, что далее необходимо для работы с отчетом в
RunTime. Всю работу с проектом отчета обеспечивает класс TRaveProjectManager –
менеджер отчетов. Следовательно, потребуются некоторые знания о свойствах и
методах этого класса.
Примечание: Следует разделять понятие проект отчета и отчет как таковой в
отдельности. Проект отчета – может содержать в себе целую коллекцию отдельных
отчетов. Отчет – это набор страниц, элементов оформления, элементов доступа к
различным источникам данных и т.п., то, что подготовлено или подготавливается
для печати отчета.
Также могут, пригодиться знания по работе с технологией RTTI для извлечения
наименований свойств, событий (методов) и другой информации из объектов
(компонентов) отчета Rave Report. Можно и не изучать принципы работы с
технологией RTTI, ведь наименование доступных свойств интересующего объекта
можно увидеть в среде разработки Rave Report инспектора объектов.
И так, двигаемся далее. Для работы с отчетом в RunTime, конечно, необходимо
знать из набора каких объектов состоит данный отчет и, от каких классов
произошли эти объекты, ведь в справочной системе Rave Report о них нет ни слова.
Для этого необходимо написать процедуру, которая поможет узнать, из каких
объектов состоит отчет, а также поможет выяснить имена классов и объектов. Код
данной процедуры представлен ниже: procedure GetListObjects(ListClass: TStrings; ClassX: TComponent; TabStr: string; AddObjects: Boolean = False); var I: Integer; begin if (ClassX = nil) or (ListClass = nil) then EXIT; for I := 0 to ClassX.ComponentCount - 1 do begin if AddObjects then ListClass.AddObject(TabStr + ClassX.Components[I].Name + ' - ' + ClassX.Components[I].ClassName, ClassX.Components[I]) else ListClass.Add(TabStr + ClassX.Components[I].Name + ' - ' + ClassX.Components[I].ClassName); if ClassX.Components[I].ComponentCount > 0 then GetListObjects(ListClass, ClassX.Components[I], TabStr + '..', AddObjects); end; end;
Как видите, процедура достаточно проста. В цикле процедуры осуществляется
проход по всем дочерним компонентам в компоненте «ClassX» и если дочерний
компонент содержит в себе еще вложенные компоненты, то используется рекурсивный
вызов процедуры GetListObjects. В результате чего будет получен список всех
компонентов. Вполне вероятно, что захочется узнать всех предков исследуемого
объекта, тогда можно воспользоваться приведенной ниже процедурой. procedure GetListParentClassName(ListClass: TStrings; ClassX: TClass; ClearList: Boolean = True); begin if (ClassX = nil) or (ListClass = nil) then EXIT; if ClearList then ListClass.Clear; while ClassX <> nil do begin ListClass.Add(ClassX.ClassName); ClassX := ClassX.ClassParent; end; end;
Пример вызова процедуры
GetListParentClassName: GetListParentClassName(MemoInfo.Lines,
RvProjectRTR.ClassType); или GetListParentClassName(MemoInfo.Lines,
TRvProject);
Как было сказано выше, для доступа к проекту отчета необходим класс
TRaveProjectManager. Чтобы получить к нему доступ, необходимо обратиться к
свойству «ProjMan» класса TRvProject. Как известно в проекте отчета Rave Report
может содержаться несколько отчетов. Работа с отчетом осуществляется через класс
TRaveReport. Для доступа к текущему активному отчету нужно обратиться к свойству
«ActiveReport» класса TRaveProjectManager.
Вот для свойства «ActiveReport» класса TRaveProjectManager и следует
применить выше описанную процедуру GetListObjects для получения списка объектов
из отчета. Для использования процедуры можно использовать, к примеру, такие
строки кода: ... ListObjects.Clear; GetListObjects(ListObjects.Items, RvProjectRTR.ProjMan.ActiveReport, '', True); ...
Посмотрите на результат работы процедуры GetListObjects. Вы наверняка сразу
заметили одну особенность, что все имена классов представленных объектов
начинаются с приставки «TRave…». Ну вот, зная имена классов, работать будет уже
намного легче.
Совет: Если известен некий класс, но неизвестно в каком модуле данный класс
описан, то это можно выяснить с помощью поисковика файлов с поддержкой поиска
текста внутри файлов. В поисковике задать маску для поиска «*.dcu» в папке
«\Rave5\Lib», а в строке для поиска текста указать наименование класса,
например: TRaveControl.
Исследование объектов средствами технологии RTTI
Получив список объектов, не мешало бы поподробнее получить информацию об
интересующем объекте. В этом, безусловно, поможет технология RTTI. Если вы
имеете опыт работы с RTTI, то можете пропустить данный раздел статьи.
Примечание: В данной статье не будет достаточно подробно рассматриваться
принцип работы с RTTI так как эта тема довольно-таки велика по объему. Будет
рассмотрено только то, что поможет в дальнейшей работе. Более подробно с
принципами работы технологии RTTI вы можете познакомиться в книге Стива
Тейксейра и Ксавье Пачеко «DELPHI 5 Руководство разработчика. Том 2. Разработка
компонентов и работа с базами данных». Процедуры, реализованные в этой статье,
основаны на примерах из этой книги, и были несколько доработаны для работы с
проектом, описываемым в данной статье.
Для работы с RTTI в раздел проекта uses необходимо подключить модуль TypInfo.
Для извлечения информации RTTI обычно требуется две структуры: PTypeInfo и
PTypeData. Ниже приведена процедура, которая выводит базовую информацию об
интересующем объекте. // Извлечение базовой информации об объекте procedure GetListClassInfo(ListInfo: TStrings; ClassX: TObject; ClearList: Boolean = True); var // В данные структуры записывается информация об RTTI объекта Class_PTI: PTypeInfo; Class_PTD: PTypeData; begin if (ClassX = nil) or (ListInfo = nil) then EXIT; if ClearList then ListInfo.Clear; // Получение информации об RTTI объекта Class_PTI := ClassX.ClassInfo; Class_PTD := GetTypeData(Class_PTI); // Вывод базовой информации об объекте with ListInfo do begin Add('Базовая информация:'); Add(Format('Имя класса: '#9' %s',[Class_PTI.Name])); Add(Format('Тип класса: '#9' %s', [GetEnumName(TypeInfo(TTypeKind), Integer(Class_PTI.Kind))])); Add(Format('Размер объекта: '#9' %d',[ClassX.InstanceSize])); Add(Format('Описан в модуле: '#9' %s',[Class_PTD.UnitName])); Add(Format('Всего доступно свойств: %d', [Class_PTD.PropCount])); if ClassX is TRaveControl then begin Add('Родительский компонент:'); Add(Format('Тип класса: %s', [TRaveControl(ClassX).Parent.ClassName])); Add(Format('Имя компонента: %s', [TRaveControl(ClassX).Parent.Name])); end; Add('Генеалогическое дерево класса:'); // Вывод информации о предках объекта GetListParentClassName(ListInfo, ClassX.ClassType, False); end; end;
Примечание: Следует помнить, что в RTTI доступны только те свойства и методы,
которые определены в секции published исследуемого объекта, т.е. те которые
видны в инспекторе объ-ектов среды разработки Delphi. Свойства и методы
необъявленные в секции published через технологию RTTI будут недоступны.
Следующая процедура выводит список наименований свойств, свойств-событий
(методы) и тип свойств исследуемого объекта. Также данная процедура выводит
текущие значения, присвоенные свойствам объекта. Для свойств типа tkClass (в
этих свойствах храниться ссылка на некий объект) выводиться имя объекта, на
который ссылается данное свойство. Если же это свойство не ссылается на объект,
то будет выведено значение «NIL». // Извлечение информации о наименовании свойств и событий объекта procedure GetListProperty(ListPropertys: TStrings; ClassX: TObject; AddObjects: Boolean = False; ClearList: Boolean = True); var PropList: PPropList; Class_PTI: PTypeInfo; Class_PTD: PTypeData; I, PropertyCount: Integer; S, StrVal: string; TmpObj: TObject; begin if (ClassX = nil) or (ListPropertys = nil) then EXIT; if ClearList then ListPropertys.Clear; Class_PTI := ClassX.ClassInfo; Class_PTD := GetTypeData(Class_PTI); if Class_PTD.PropCount <> 0 then begin // Выделение памяти под структуры TPropInfo, в зависимости от количества свойств объекта GetMem(PropList, SizeOf(PPropInfo) * Class_PTD.PropCount); try // Заполнение PropList указателями на структуры TPropInfo GetPropInfos(ClassX.ClassInfo, PropList); for I := 0 to Class_PTD.PropCount - 1 do // Добавляются свойства не являющиеся событиями if not (PropList[I]^.PropType^.Kind = tkMethod) then begin // Извлечение текущего значения свойства if PropList[I]^.PropType^.Kind = tkClass then begin TmpObj := GetObjectProp(ClassX, PropList[I]^.Name); if TmpObj = nil then StrVal := 'NIL' else // Если у объекта есть предок TComponent, // то извлекается имя объекта иначе имя класса if TmpObj is TComponent then StrVal := TComponent(TmpObj).Name else StrVal := '(' + TmpObj.ClassName + ')'; end else StrVal := GetPropValue(ClassX, PropList[I]^.Name); S := Format('%s: %s = %s', [PropList[I]^.Name, PropList[I]^.PropType^.Name, StrVal]); if AddObjects then ListPropertys.AddObject(S, TObject(PropList[I]^.PropType^)) else ListPropertys.Add(S); end; // Поиск свойств-событий PropertyCount := GetPropList(ClassX.ClassInfo, [tkMethod], PropList); ListPropertys.Add('*** Свойства-события ***'); // Добавляются свойства-события for i := 0 to PropertyCount - 1 do begin S := Format('%s: %s', [PropList[I]^.Name, PropList[I]^.PropType^.Name]); if AddObjects then ListPropertys.AddObject(S, TObject(PropList[I]^.PropType^)) else ListPropertys.Add(S); end; finally // Освобождение ранее выделенной памяти FreeMem(PropList, SizeOf(PPropInfo) * Class_PTD.PropCount); end; end; end;
Процедур GetListClassInfo и GetListProperty вполне достаточно, чтобы изучить
необходимый объект. Но самой полезной является, конечно, процедура
GetListProperty. Как видите процедура GetListProperty достаточно сложная по
виду. Еще бы, ведь структуры PTypeInfo и особенно PTypeData довольно-таки
«ветвистые» по своему строению. Понимание выше приведенных процедур осложняет
еще и то, что Borland не документирует данную технологию так как, она может
изменяться от одной версии Delphi к другой, вследствие чего это не может
гарантировать работоспособность одного и того же кода в различных версиях
Delphi.
Для просмотра результата работы приведенных выше двух можно применить
следующие строки кода: ... if ListObjects.Items.Objects[ListObjects.ItemIndex] <> nil then begin GetListClassInfo(MemoInfo.Lines, ListObjects.Items.Objects[ListObjects.ItemIndex]);
GetListProperty(ListProperty.Items, ListObjects.Items.Objects[ListObjects.ItemIndex], True); end; ...
Но и это еще не все возможности технологии RTTI. Также есть возможность
получить достаточно полную информацию о свойстве или методе исследуемого
объекта. Для извлечения столь немаловажной информации следует воспользоваться
приведенной ниже процедурой. // Извлечение информации о свойствах и методах объекта
procedure GetPropertyInfo(ListInfo: TStrings; PTI: PTypeInfo; PTD: PTypeData; ClearList: Boolean = True); type // Структура для извлечения информации из методов (свойства-события) PParamRec = ^TParamRec; TParamRec = packed record Flags: TParamFlags; ParamName: ShortStringBase; TypeName: ShortStringBase; end; var I: Integer; S, S2: string; TeStr, RStr: ^ShortStringBase; ParamRec: PParamRec; // Базовая информация для всех свойств procedure Name_Info; begin ListInfo.Add(Format('Тип свойства: %s', [PTI.Name])); ListInfo.Add(Format('Подтип свойства: %s', [GetEnumName(TypeInfo(TTypeKind), Integer(PTI^.Kind))])); end; // Информация для целочисленных, множеств и перечисляемых типов свойств procedure Int_Info; begin ListInfo.Add(Format('Минимальное значение: %d', [PTD^.MinValue])); ListInfo.Add(Format('Максимальное значение: %d', [PTD^.MaxValue])); end;
// Информация для типов свойств с плавающей точкой procedure Float_Info; begin // Определение подтипа свойства case PTD^.FloatType of ftSingle: S := 'ftSingle'; ftDouble: S := 'ftDouble'; ftExtended: S := 'ftExtended'; ftComp: S := 'ftComp'; ftCurr: S := 'ftCurr'; end; ListInfo.Add(Format('Подтип tkFloat: %s', [S])); ListInfo.Add('Минимальное значение: ' + FloatToStr(PTD^.MinInt64Value)); ListInfo.Add('Максимальное значение: ' + FloatToStr(PTD^.MaxInt64Value)); end; // Информация для свойства представленного как класс procedure Class_Info; begin ListInfo.Add(Format('Предок класса свойства: %s', [PTD^.ParentInfo^.Name])); ListInfo.Add(Format('Доступно свойств у объекта: %d', [PTD^.PropCount])); ListInfo.Add(Format('Описан в модуле: %s', [PTD^.UnitName])); end; // Информация для методов (свойства-события) procedure Method_Info; var J: Integer; begin // Определение типа метода case PTD^.MethodKind of mkProcedure: S := 'Procedure '; mkFunction: S := 'Function '; mkConstructor: S := 'Constructor '; mkDestructor: S := 'Destructor '; mkClassProcedure: S := 'ClassProcedure '; mkClassFunction: S := 'ClassFunction '; mkSafeProcedure: S := 'SafeProcedure '; mkSafeFunction: S := 'SafeFunction '; end; // Извлечение информации о передаваемом параметре ParamRec := @PTD^.ParamList; J := 1; ListInfo.Add(Format('Передаваемых параметров: %d', [PTD^.ParamCount])); while J <= PTD^.ParamCount do begin if J = 1 then S := S + '('; // Определение метода передачи параметра if pfVar in ParamRec.Flags then S2 := 'var '; if pfConst in ParamRec.Flags then S2 := 'const '; if pfArray in ParamRec.Flags then S2 := 'array of '; if pfOut in ParamRec.Flags then S2 := 'out '; // Извлечение информации о типе передаваемого параметра TeStr := Pointer(Integer(@ParamRec^.ParamName) + Length(ParamRec^.ParamName) + 1); S := S + S2; S := Format('%s%s: %s', [S, ParamRec^.ParamName, TeStr^]); Inc(J); // Извлечение информации о следующем передаваемом параметре ParamRec := PParamRec(Integer(ParamRec) + SizeOf(TParamFlags) + (Length(ParamRec^.ParamName) + 1) + (Length(TeStr^) + 1)); if J > PTD^.ParamCount then S := S + ')'; // Если метод является функцией, то извлекается информация о возвращаемом параметре if PTD^.MethodKind = mkFunction then begin RStr := Pointer(ParamRec); S := Format('%s: %s;', [S, RStr^]); end else S := S + '; '; end; ListInfo.Add(S); end; // Вывод информации для строковых типов свойств procedure Str_Info; begin ListInfo.Add(Format('Максимальная длина: %d', [PTD^.MaxLength])); end;
begin if (ListInfo = nil) or (PTI = nil) or (PTD = nil) then EXIT; if ClearList then ListInfo.Clear; Name_Info; // Извлечение информации для свойств множеств if PTI^.Kind = tkSet then begin PTI := PTD^.CompType^; PTD := GetTypeData(PTI); Name_Info; end;
case PTI^.Kind of tkInteger: Int_Info; tkFloat: Float_Info; tkString: Str_Info; tkLString: Str_Info; tkWString: Str_Info; // Извлечение информации для перечисляемых свойств tkEnumeration: begin Int_Info; ListInfo.Add('Варианты значений:'); for I := PTD^.MinValue to PTD^.MaxValue do ListInfo.Add(Format('Значение: %s', [GetEnumName(PTI, I)])); end; tkClass: Class_Info; tkMethod: Method_Info; end; end;
Примечание: Для перечисляемых свойств, информацию «Минимальное значение» и
«Максимальное значение» выводимую процедурой GetPropertyInfo следует понимать
как первый и последний индекс элемента перечисляемого свойства.
Использовать процедуру GetPropertyInfo можно так:
procedure TFormRTR.ListPropertyClick(Sender: TObject); var TI: PTypeInfo; TD: PTypeData; begin if ListProperty.Items.Objects[ListProperty.ItemIndex] = nil then EXIT; TI := PTypeInfo(ListProperty.Items.Objects[ListProperty.ItemIndex]); TD := GetTypeData(TI); GetPropertyInfo(MemoInfo.Lines, TI, TD); end;
Имея на вооружении такие замечательные процедуры, наконец, то можно изучить
интересующие классы, узнать свойства и методы, а также тип свойств исследуемых
классов. Получив достаточно подробную информацию с помощью технологии RTTI
теперь, наконец, можно перейти к работе с проектом отчета Rave Report в режиме
RunTime, но сначала ознакомимся с основными классами, которые встречаются в
проекте отчета Rave Report.
Описание классов TRaveXXX
В этом разделе статьи содержится описание классов, из которых в основном
состоит проект отчета. Проект отчета формируют три основных класса:
TRaveProjectManager, TRaveReport, TRavePage. Для работы с источниками данных
могут использоваться классы TRaveDataView, TRaveDataField, а так же TRaveRegion
и TRaveDataBand. Разберем эти основные классы более конкретно.
Как описывалось выше, класс TRaveProjectManager обеспечивает всю базовую
работу с проектом отчета Rave. Осуществляет такие основные задачи как:
чтение/сохранение проекта отчета, работа с коллекцией отчетов и глобальными
страницами, поиск необходимого отчета и компонентов TRaveXXX и многое другое.
Ниже приведено описание основных свойств класса TRaveProjectManager.
Примечание: * – предположительное описание свойства, ввиду того, что в
справочной системе Rave не предоставлена информация по данному свойству.
(скрытый) – данное свойство доступно через технологию RTTI, но скрыто в
инспекторе объектов среды разработки Rave Report.
TRaveProjectManager
- AdminPassword Пароль для доступа к проекту отчета *
- Categories Хранит список наименования категорий. Далее отдельному отчету
можно указать тип категории, что помогает организовать более удобную работу и
произвести поиск отчетов по категориям
- CompileNeeded Необходима компиляция (скрытый) *
- Description Сюда записывается более подробная информация о компоненте
- DevLocked Блокировка компонента от случайных изменений его свойств
- FullName Альтернативное наименование компонента
- Locked Блокировка компонента от случайных изменений его свойств
- Name Имя компонента
- Parameters Описание параметров, которые могут использоваться для сохранения
временных вычислений или другой информации
- PIVars По назначению подобны Parameters, но присваиваются значения, которые
определены после передачи команды на печать (After Print)
- SecurityControl Определяет параметры доступа к серверам баз данных для ввода
имени и пароля пользователя
- Tag Тег, хранит целое число, которое используется разработчиком для
собственных нужд
- Units Определяет единицу измерения для всех отчетов
- UnitsFactor Коэффициент для перевода текущей единицы измерения в дюймы
- OnBeforeReport Обработчик события перед генерацией отчета
- OnAfterReport Обработчик события после генерации отчета
- OnBeforePrint Обработчик события пред посылкой задания на печать
- OnAfterPrint Обработчик события после завершения печати
Примечание: Если вы исследовали, какой либо класс TRaveXXX средствами RTTI,
то наверно обратили внимание, что события OnBeforeReport, OnAfterReport,
OnBeforePrint, OnAfterPrint не являются методами как в VCL Delphi, а являются
ссылками на класс TRaveSimpleEvent.
Теперь познакомимся с классом TRaveReport. Данный класс представляет собой
отдельный отчет, который является контейнером, хранящим в себе страницы отчета.
Описание основных свойств класса TRaveReport приведены ниже.
TRaveReport
- AlwaysGenerate Перед печатью отчета заполняет переменные типа TotalPages,
чтобы их значение было известно перед печатью первой страницы
- Category Позволяет установить принадлежность отчета к заданной категории.
Список доступных категорий задается в свойстве «Categories» менеджера отчетов
TRaveProjectManager
- Collate Определяет тип упорядочивания задания на печать
- CompileNeeded Необходима компиляция (скрытый) *
- Copies Хранит количество копий, после печати отчета
- Description Сюда записывается более подробная информация о компоненте
- DevLocked Блокировка компонента от случайных изменений его свойств
- Duplex Установка типа дуплексной печати для принтера (не для всех принтеров)
- FirstPage Первая страница отчета
- FullName Альтернативное наименование компонента
- Locked Блокировка компонента от случайных изменений его свойств
- MaxPages Ограничивает число генерируемых страниц при генерации отчета после
вызова метода Execute, 0 – генерируются все страницы
- Name Имя компонента
- PageList Список страниц для печати. Здесь можно задать какие страницы
печатать и в каком порядке
- Parameters Описание параметров, которые могут использоваться для сохранения
временных вычислений или другой информации
- PIVars По назначению подобны Parameters, но присваиваются значения, которые
определены после передачи команды на печать (After Print)
- Printer Задается имя принтера, на который выводится печать. Если поле
пустое, то вывод данных осуществляется на текущий принтер
- Resolution Установка качества печати
- SecurityControl Определяет параметры доступа к серверам баз данных для ввода
имени и пароля пользователя
- Tag Тег, хранит целое число, которое используется разработчиком для
собственных нужд
- OnAfterPrint Обработчик события после завершения печати
- OnAfterReport Обработчик события после генерации отчета
- OnBeforePrint Обработчик события пред посылкой задания на печать
- OnBeforeReport Обработчик события перед генерацией отчета
Переходим к классу TRavePage. Данный класс реализует страницу отчета и также
является контейнером, в который помещаются различные элементы оформления отчета,
а также вспомогательные не визуальные элементы, например как TRaveFontMaster.
Рассмотрим свойства класса TRavePage в приведенной ниже таблице.
TRavePage
- Bin Указывается тип лотка для подачи бумаги
- BinCustom Если в представленном списке Bin нет необходимого типа лотка, то
указывается пользовательская константа лотка, поддерживаемая принтером
- CompileNeeded Необходима компиляция (скрытый) *
- Description Сюда записывается более подробная информация о компоненте
- DevLocked Блокировка компонента от случайных изменений его свойств
- FullName Альтернативное наименование компонента
- GotoMode Определяет метод перехода по страницам «GotoPage» при печати
- GotoPage Печать указанной страницы после печати текущей страницы
- GridLines Определяет шаг видимой линии в координатной сетке
- GridSpacing Размер шага между линиями в координатной сетке
- Locked Блокировка компонента от случайных изменений его свойств
- Name Имя компонента
- Orientation Вид ориентации страницы (книжная/альбомная)
- PageHeight Высота страницы
- PageWidth Ширина страницы
- PaperSize Выбор формата страницы поддерживаемый текущим принтером
- Parameters Описание параметров, которые могут использоваться для сохранения
временных вычислений или другой информации
- PIVars По назначению подобны Parameters, но присваиваются значения, которые
определены после передачи команды на печать (After Print)
- Tag Тег, хранит целое число, которое используется разработчиком для
собственных нужд
- WasteFit Запрещает или разрешает при генерации отчета, пропорционально
располагать элементы оформления на всю рабочую область страницы
- OnAfterPrint Обработчик события после завершения печати
- OnAfterReport Обработчик события после генерации отчета
- OnBeforePrint Обработчик события пред посылкой задания на печать
- OnBeforeReport Обработчик события перед генерацией отчета
TRaveDataView – данный класс-посредник обеспечивает работу и связь между
источниками данных и отчетом (данное назначение класса предположительно ввиду
отсутствия справочной информации о нем). Описан он в модуле RvDirectDataView.
TRaveDataView
- CompileNeeded Необходима компиляция *
- ConnectionName Хранит имя подключенного источника данных
- Description Сюда записывается более подробная информация о компоненте
- DevLocked Блокировка компонента от случайных изменений его свойств
- FullName Альтернативное наименование компонента
- Locked Блокировка компонента от случайных изменений его свойств
- Name Имя компонента
- Tag Тег, хранит целое число, которое используется разработчиком для
собственных нужд
- OnBeforeReport Обработчик события перед генерацией отчета
- OnAfterReport Обработчик события после генерации отчета
- OnBeforePrint Обработчик события пред посылкой задания на печать
- OnAfterPrint Обработчик события после завершения печати
TRaveDataField – данный класс представляет собой поле данных и предоставляет
вывод информации из источника данных. Этот класс расположен в модуле
RvDataField.
TRaveDataField
- Calculated Вычисляемое поле или нет *
- Description Сюда записывается более подробная информация о компоненте
- DevLocked Блокировка компонента от случайных изменений его свойств
- FieldName Имя поля
- FullName Альтернативное наименование компонента
- Locked Блокировка компонента от случайных изменений его свойств
- Name Имя компонента
- NullText Текст, выводимый по умолчанию (если нет данных в источнике данных)
- Size Размер поля
- Tag Тег, хранит целое число, которое используется разработчиком для
собственных нужд
- OnBeforeReport Обработчик события перед генерацией отчета
- OnAfterReport Обработчик события после генерации отчета
- OnBeforePrint Обработчик события пред посылкой задания на печать
- OnAfterPrint Обработчик события после завершения печати
Ниже в таблице приведено описание классов, которые можно встретить в палитре
компонентов среды разработки отчетов Rave Report. Визуальные компоненты – это те
самые элементы оформления отчетов, такие как: линия, текст, штриховые коды и др.
Не визуальные компоненты выполняют вспомогательные функции в оформлении отчета
(TRaveFontMaster, TRavePageNumInit), или выполняют вычисления при генерации
отчета, такие компоненты как TRaveCalcController, TRaveCalcOp и другие. Также к
не визуальным элементам отчетов относятся компоненты TRaveRegion, TRaveBand,
TRaveDataBand и компоненты доступа к источникам данных. В заголовке таблицы
приведено имя модуля, где данные классы реализованы.
RvCsDraw
- TRaveGraphicBase Является базовым классом для всех классов данного модуля.
Произошел данный класс от TRaveControl.
- TRaveSurface Происходит от класса TRaveGraphicBase и уже содержит в себе
свойства реализующие базовые элементы оформления и стилей.
- TRaveLine Элемент оформления – линия.
- TRaveHLine Элемент оформления – горизонтальная линия.
- TRaveVLine Элемент оформления – вертикальная линия
- TRaveRectangle Элемент оформления – прямоугольник
- TRaveSquare Элемент оформления – квадрат.
- TRaveEllipse Элемент оформления – эллипс.
- TRaveCircle Элемент оформления – окружность.
RvCsBars
- TRaveBaseBarCode Базовый класс штрихового кода.
- TRavePostNetBarCode Постсетевой штриховой код (PostNet), используется
американской почтовой службой в доставке почты.
- TRaveI2of5BarCode Числовой штриховой код (I2of5).
- TRaveCode39BarCode Алфавитно-цифровой штриховой код (Code39). Символ может
хранить кодируемые данные. Разработан, чтобы кодировать 26 прописных букв, 10
цифр и 7 специальных символов.
- TRaveCode128BarCode Алфавитно-цифровой штриховой код с высокой плотностью
(Code128). Символ может хранить кодируемые данные. Разработан, чтобы кодировать
первые 128 ASCII символов.
- TRaveUPCBarCode Универсальный штриховой код изделия (UPC).
- TRaveEANBarCode Европейский международный номер, штриховой код подобен
штриховому коду UPC (EAN).
RvCsStd
- TRaveText Элемент оформления – текст.
- TRaveMemo Элемент оформления – текстовое поле MEMO.
- TRaveSection Вспомогательный элемент оформления, реализующий группировку
объектов.
- TRaveBitmap Элемент оформления для вывода растрового изображения.
- TRaveMetaFile Элемент оформления для вывода метафайла.
- TRaveFontMaster Вспомогательный элемент оформления, для установки свойства
шрифта у текстовых компонентов. Компоненты позволяющие работать с компонентом
TRaveFontMaster содержат свойство «FontMirror».
- TRavePageNumInit Вспомогательный элемент оформления позволяющий производить
нумерацию страниц.
RvCsRpt
- TRaveRegion Компонент-контейнер, размещающий в себе элементы оформления
отчета. Также позволяет создать печать отчета в несколько столбцов. Используется
для работы с источниками баз данных.
- TRaveBand Компонент-контейнер, также размещающий в себе элементы оформления
отчета. В основном используется для создания верхних и нижних колонтитулов или
других сносок.
- TRaveDataBand Компонент-контейнер, размещающий в себе элементы оформления
отчета для вывода информации из баз данных.
- TRaveDataCycle Используется для вычислений, сортировки или фильтрации.
RvCsData
- TRaveDataText Элемент оформления отчета, для вывода однострочных данных из
источника баз данных.
- TRaveDataMemo Элемент оформления отчета, для вывода многострочных данных из
источника баз данных.
- TRaveDataMirrorSection Компонент-контейнер, размещающий в себе элементы
оформления отчета для доступа к источникам баз данных и объединяющий их в одну
группу.
- TRaveCalcText Элемент оформления отчета, позволяющий производить вычисления
по указанному полю источника данных.
- TRaveCalcOp Вспомогательный элемент, позволяющий производить вычисления по
двум указанным полям источника данных.
- TRaveCalcTotal Вспомогательный элемент, позволяющий производить вычисления
по указанному полю источника данных и имеет возможность передать вычисленное
значение какому либо элементу оформления отчета.
- TRaveCalcController Вспомогательный элемент, позволяющий задать параметры
вычислений. Также данный класс выполняет все заданные функции вычислений.
Доступ к объектам проекта отчета Rave Report в режиме RunTime
Ну вот, когда проведена большая работа по исследованию классов в проекте
отчета Rave Report, наконец, можно приступить непосредственно к работе с отчетом
в режиме RunTime. Еще раз напомню порядок доступа к активному (текущему) отчету
Rave:
- Для доступа к проекту отчета необходимо обратиться к классу
TRaveProjectManager.
- Для доступа к классу TRaveProjectManager следует обратиться к свойству
«ProjMan» класса TRvProject.
- Чтобы получить доступ к активному отчету, следует обратиться к свойству
«ActiveReport» класса TRaveProjectManager.
- То есть последовательность такого типа: TRvProject.ProjMan.ActiveReport.
Как вы уже знаете в отчете содержаться еще и страницы. К сожалению,
разработчики не предоставили методов для навигации по страницам отчета
(представлено только одно свойство «FirstPage» – первая страница), но это
проблема вполне решаема. Ниже приведена процедура, которая возвращает список
указателей на объекты (если таковые имеются), порожденных от указанного класса.
// Возвращает список указателей на объекты, порожденных от указанного класса FindClass procedure GetObjectList(RootComponent: TComponent; FindClass: TClass; var PageList: TList); var I: Integer; begin PageList.Clear; if (RootComponent = nil) or (PageList = nil) then EXIT; for I := 0 to RootComponent.ComponentCount - 1 do if RootComponent.Components[I] is FindClass then PageList.Add(RootComponent.Components[I]); end;
Пример вызова процедуры: GetObjectList(RvProjectRTR.ProjMan.ActiveReport, TRavePage, RavePageList);
Данный вызов процедуры заполняет список RavePageList указателями на все
найденные страницы в текущем отчете. Теперь используя список RavePageList можно
удобно осуществлять навигацию по страницам отчета, точно так же, как по списку
отчетов представленный менеджером отчетов TRaveProjectManager. Список отчетов
можно получить, обратившись к свойству «ReportList» класса TRaveProjectManager.
Используя процедуру GetObjectList можно получить список и других объектов
произошедших от определенного класса, что облегчает навигацию по объектам
определенного типа.
Примечание: У класса TRaveReport в наличии есть свойство «PageList». Данное
свойство определяет порядок страниц при печати. Допустим, в отчете имеется 10
страниц, а в «PageList» указанно печатать 3-ю и 8-ю страницу. Тогда свойство
«PageList.Count», будет равным 2-ум, и доступ вы сможете получить только к 3-й и
8-й странице отчета. Если же в свойстве «PageList» нет ссылок на страницы отчета
(PageList = NIL), то при попытке обратиться к данному свойству будет получено
сообщение об ошибке. Поэтому не следует забывать специфику данного свойства.
Примечание: TRaveReport также предоставляет свойство «Page» доступное только
для чтения. Можно было бы предположить, что данное свойство хранит ссылку на
активную страницу текущего отчета, но по каким то причинам в данном свойстве все
время присутствует значение равное NIL. Так что назначение данного свойства для
меня пока неизвестно.
Слов сказано уже много, но на практике еще мало чего сделано. Думаю, настало
время перейти к практической части. За основу, как оговаривалось в начале
статьи, взят демонстрационный проект отчета «RaveDemo.rav», вот над ним и будут
производиться все опыты на практике. Для экспериментов возьмем, к примеру, отчет
«Mirror Report».
Попробуем изменить заголовок первой страницы у отчета «Mirror Report». Для
оттого необходимо:
- Найти и активизировать отчет «Mirror Report» средством вызова метода
«SelectReport» класса TRvProject.
- Произвести поиск текстового элемента оформления TRaveText на первой странице
отчета TRavePage. Для этого можно воспользоваться методом «FindRaveComponent»
класса TRaveProjectManager, который в случае успешного поиска в качестве
возвращаемого параметра вернет найденный объект, в противном случае возвратится
NIL.
- Убедиться, что искомый объект произошел от нужного класса.
- Если искомый объект найден, то произвести с ним все необходимые манипуляции.
- После внесенных изменений сгенерировать отчет методом «Execute» или
«ExecuteReport» класса TRvProject.
Ниже представлен пример реализации всего выше изложенного. ... var I: Integer; TmpRaveComponent: TRaveComponent; begin // Поиск и активизация необходимого отчета. Метод вернет false если отчет не найден if not RvProjectRTR.SelectReport('Mirror Report', true) then EXIT; // Поиск компонента с именем 'Text1' на первой странице отчета TmpRaveComponent := RvProjectRTR.ProjMan.FindRaveComponent('Text1', RvProjectRTR.ProjMan.ActiveReport.FirstPage); // Если объект найден, и он произошел от класса TRaveText if (TmpRaveComponent <> nil) and (TmpRaveComponent is TRaveText) then begin // Замена выводимого текста TRaveText(TmpRaveComponent).Text := 'Это мой новый заголовок'; // Изменение стиля шрифта TRaveText(TmpRaveComponent).Font.Style := [fsItalic]; end; // Генерация активного отчета RvProjectRTR.Execute; end; ...
|