|
Раздичные объекты в системе отчета "AKReport"
поддерживают перехват основных событий, оброботка которых позволяет функционально
расширить возможности отчета, динамично реагировать на то или иное состояние
отчета. Таким образом, в зависимости от задачи, можно использовать как
высокий уровень управления отчетом, так и незкий.
Список событий:
| Объект/событие |
Описание |
Отчет |
|
| OnStartReport |
Событие происходит по запуску отчета до запроса пользовательских
параметров. |
| OnEndReport |
Событие происходит по завершению отчета. |
Параметры |
|
| OnBeforeQueryParams |
Событие происходит перед открытием окна запроса пользовательских
параметров. |
| OnAfterQueryParams |
Событие происходит по закрытию окна запроса пользовательских параметров. |
Группа |
|
| OnFirstPrintBand (Band:
TDBBandInfo) |
Событие происходит один раз во всем документе при первом формировании
банда. |
| OnBeforePrintBand (Band:
TDBBandInfo) |
Событие происходит после формирования мастер-банда перед формированием
деталь-бандов. Cобытие происходит один раз для каждого мастер-банда. |
| OnAfterPrintBand (Band:
TDBBandInfo) |
Событие происходит после формирования последнего деталь-банда перед
формированием следующего мастер-банда. Cобытие происходит один раз
для каждого мастер-банда. |
| OnBeforePrintRec (Band:
TDBBandInfo) |
Событие происходит перед формированием банда. |
| OnAfterPrintRec (Band:
TDBBandInfo) |
Событие происходит после формирования банда |
| OnGetFieldData (Field:
TDBFieldInfo) |
Событие происходит перед каждым формированием параметра в банде |
| OnAfterOpenDataSet(ds:
TpFibDataSet) |
Событие происходит после открытия датасета связанного с группой
(бандом) |
| OnBeforeOpenDataSet(ds:
TpFibDataSet) |
Событие происходит перед открытием датасета связанного с группой
(бандом) |
| OnAfterCreateDataSet(ds:
TpFibDataSet) |
Событие происходит после создания датасета связанного с группой
(бандом) |
Структура событий документа
Рассмотрим структуру событий на примере несложного мастер-детального
отчета:
Шаблон.
~Begin dsMasterBand~
~поле_A~ ~поле_B~
~Begin dsDetailBand~
~поле_A~
~поле_B~
~End dsDetailBand~
~поле_С~
~End dsMasterBand~ |
Здесь первые поля "поле_A","поле_B"
и поле "поле_С" относятся к
"dsMasterBand", а вторые поля "поле_A","поле_B"
- к "dsDetailBand".
Структуру событий.
В результате выполнения запроса сформируется документ:
поле_A(1) поле_B(1)
поле_A(1.1) поле_B(1.2)
поле_A(1.2) поле_B(1.2)
поле_С(1)
поле_A(2) поле_B(2)
поле_A(2.1) поле_B(2.1)
поле_A(2.2) поле_B (2.2)
поле_С(2) |
Где вместо "поле_A(1)", "поле_B(1)",
"поле_A(1.1)" и т.д. будут значения
полей из базы данных.
Описание событий
| Объект |
Отчет |
| Событие |
OnStartReport |
| Описание |
нет. |
| Параметр проц. |
Нет. |
| Пример |
нет. |
| Объект |
Отчет |
| Событие |
OnEndReport |
| Описание |
Событие происходит по завершению отчета. |
| Параметр проц. |
Нет. |
| Пример |
procedure OnEndReport;
begin
Report.ShowType := 7; //ShowReport
+ ShowMessage + UpdateFields
end;
procedure OnEndReport;
begin
ShowMessage('Отчет завершен успешно!');
end; |
| Объект |
Параметры |
| Событие |
OnBeforeQueryParams |
| Описание |
Событие происходит перед оптрытием окна с запросом пользовательских
параметров. Событие происходит даже если нет параметров. По этому
событию можно динамически создавать пользовательские парметры. |
| Параметр проц. |
Нет. |
| Пример |
// Процедура в параметрах предлагает пользователю ввести (текущую
по умолчанию)
// дату - дату начала срока действия документа, и
// дату окончания срока действия документа, срок по умолчанию 3 дня
исключая выходные
procedure OnBeforeQueryParams;
Var DC : TDateTime;
i : Integer;
begin
DC := Date;
Report.UserParams.Item('CurDate').Value
:= DC;
i := 0;
Repeat
DC
:= DC + 1;
If
(DayOfWeek(DC) in [2..6]) Then
Inc(i);
Until
(i >= 3);
Report.UserParams.Item('ToDate').Value
:= DC;
end; |
| Объект |
Параметры |
| Событие |
OnAfterQueryParams |
| Описание |
Событие происходит после закрытия окна с запросом пользовательских
параметров. Событие не происходит, если ниодин параметр не определен. |
| Параметр проц. |
Нет. |
| Пример |
procedure OnAfterQueryParams;
Var
M,D : Word;
CurYear : Word;
begin
DecodeDate(StrToDate(Params.Item('ToDate').Value),
CurYear, M, D);
Params.Item('CurYear').Value :=
CurYear;
end;
// Создается отчет в файле, определенном пользователем в параметре
'FileName'. Документ не отображается Report.ShowType := 0;
procedure OnAfterQueryParams;
begin
Report.ShowType := 0;
Report.DestinationDoc := Params.Item('FileName').Value;
end;
// Создание Excel отчета из скрипта, прямой доступ к отчету
procedure OnAfterQueryParams;
Var
App : Variant;
sheet, range : Variant;
dsL : TpFibDataSet;
Row,Col : Integer;
LStudentID : Variant;
SL : TStringList;
j : Integer;
//************************************
Function
GetCol(Discipline:String):Integer;
Var
i : Integer;
Begin
Result
:= -1;
For
i := 0 to SL.Count-1 do
begin
If
(SL[i] = Discipline) then
Begin
Result
:= i;
Break;
End;
end;
If
(Result = -1) then
Begin
Result
:= SL.Add(Discipline);
End;
Result
:= Result + 4;
End;
//************************************
begin
SL := TstringList.Create;
Try
App
:= CreateOleObject('Excel.Application');
App.Visible
:= True;
App.WorkBooks.Add(Report.TemplateDoc);
Report.TemplateDoc
:= '';
Sheet
:= App.ActiveSheet;
Sheet.Cells(1,1).Value
:= Params.Item('Semester').Value;
Sheet.Cells(2,1).Value
:= Params.Item('EduYear_EDUYEARSTR').Value;
dsL := FindDataSet('dsList');
Params.Item('StudentsID').Value
:= HostAppl.Data.GetSelectedList('STUDENTID');
dsL.Active
:= True;
dsL.First;
Row
:= 2;
LStudentID
:= 0;
While
not dsL.Eof do Begin
If
(LStudentID <> dsL.FieldByName('STUDENTID').Value) Then
Begin
Inc(Row);
Sheet.Cells(Row,3).Value
:= dsL.FieldByName('FIO').Value;
Sheet.Cells(Row,2).Value
:= '''' + IntToStr(Row-2) + '.';
End;
Col
:= GetCol(dsL.FieldByName('DISCIPLINE').Value + ' (' + dsL.FieldByName('FORMREPORT').Value
+ ')');
If
(VarToStr(Sheet.Cells(Row,Col).Value) <> '') Then
Sheet.Cells(Row,Col).Value
:= VarToStr(Sheet.Cells(Row,Col).Value) + '; ' + dsL.FieldByName('MARKNAME').Value
Else
Sheet.Cells(Row,Col).Value
:= dsL.FieldByName('MARKNAME').Value;
LStudentID
:= dsL.FieldByName('STUDENTID').Value;
dsL.Next;
End;
//*************************
For
j := 0 to SL.Count-1 do
begin
Sheet.Cells(2,j+4).Value
:= SL[j];
end;
range
:= Sheet.Range(Sheet.Cells(2,2), Sheet.Cells(Row, SL.Count + 3));
range.Borders(7).LineStyle
:= 1; //xlContinuous
range.Borders(8).LineStyle
:= 1; //xlContinuous
range.Borders(9).LineStyle
:= 1; //xlContinuous
range.Borders(10).LineStyle
:= 1; //xlContinuous
range.Borders(11).LineStyle
:= 1; //xlContinuous
range.Borders(12).LineStyle
:= 1; //xlContinuous
Finally
SL.Free;
end;
end; |
| Объект |
Группа |
| Событие |
OnFirstPrintBand |
| Описание |
Событие происходит при первом формировании банда. |
| Параметр проц. |
Band: TDBBandInfo |
| Пример |
// Не создавать первый банд по условию...
procedure GroupHeader_OnFirstPrintBand(Band: TDBBandInfo);
begin
Band.Stop := (Params.Item('Position_INDEX').Value
= 0);
end; |
| Объект |
Группа |
| Событие |
OnBeforePrintBand |
| Описание |
Событие происходит после формирования мастер-банда перед формированием
деталь-бандов. Cобытие происходит один раз для каждого мастер-банда. |
| Параметр проц. |
Band: TDBBandInfo |
| Пример |
// Если группа 'Group3' пустая, не создавать банд 'Group4'
// Группа 'Group4' - мастер, 'Group3' - деталь
procedure Group4_OnBeforePrintBand(Band:
TDBBandInfo);
var
ds: TpFIBDataSet;
begin
ds := FindDataSet('Group3');
if
not ds.Active then ds.Active := True;
Band.Stop := ds.IsEmpty;
end; |
| Объект |
Группа |
| Событие |
OnAfterPrintBand |
| Описание |
Событие происходит после формирования последнего деталь-банда перед
формированием следующего мастер-банда. Cобытие происходит один раз
для каждого мастер-банда. |
| Параметр проц. |
Band: TDBBandInfo |
| Пример |
нет. |
| Объект |
Группа |
| Событие |
OnBeforePrintRec |
| Описание |
Событие происходит перед формированием банда. |
| Параметр проц. |
Band: TDBBandInfo |
| Пример |
procedure dsNK1_1_OnBeforePrintRec(Band:
TDBBandInfo);
begin
Band.Visible :=
(Band.DataSet.FieldByName('C4').AsInteger +
Band.DataSet.FieldByName('C9').AsInteger
+
Band.DataSet.FieldByName('C10').AsInteger)
> 0;
end; |
| Объект |
Группа |
| Событие |
OnAfterPrintRec |
| Описание |
Событие происходит после формирования банда |
| Параметр проц. |
Band: TDBBandInfo |
| Пример |
нет. |
| Объект |
Группа |
| Событие |
OnGetFieldData |
| Описание |
Событие происходит перед каждым формированием параметра в банде.
Используется для модификации параметров перед выводом их в документ. |
| Параметр проц. |
Field: TDBFieldInfo |
| Пример |
procedure grInInnerReason_OnGetFieldData(Field:
TDBFieldInfo);
Var
S : String;
begin
If
Field.FieldName = 'CHANGES' Then
Begin
S
:= '';
with
field.dataset do
Begin
If
(FieldByName('SPECIALITY').asString <>
FieldByName('SPECIALITY1').asString)
Then
S := S + FieldByName('SPECIALITY1').asString + ' -> '
+
FieldByName('SPECIALITY').asString + '; ';
If
(FieldByName('EDUBASIS').asString <>
FieldByName('EDUBASIS1').asString)
Then
S := S + FieldByName('EDUBASIS1').asString + ' -> '
+
FieldByName('EDUBASIS').asString + '; ';
If
( Params.Item('Department_DEPARTMENT').Value <>
FieldByName('DEPARTMENT1').asString)
Then
S := S + FieldByName('DEPARTMENT1').asString + ' -> '
+
Params.Item('Department_DEPARTMENT').Value + '; ';
End;
SetLength(S,
Length(S)-2);
Field.Value
:= S;
End;
end;
//В Excel считаются суммы по столбцам, чтобы формулы правильно работали
в пустые ячейки прописываем "0"
procedure dsIn_OnGetFieldData(Field:
TDBFieldInfo);
begin
If (not validint(Field.Value))
and (Field.FieldName <> 'SPECIALITY') Then Field.Value := 0;
end;
// Не создавать последний разрыв страницы
procedure grTestList_OnGetFieldData(Field:
TDBFieldInfo);
begin
if
Field.FieldName = 'NewPage' then
begin
if
Field.DataSet.RecNo < Field.DataSet.RecordCount
then Field.Value := '\page';
end;
end; |
| Объект |
Группа |
| Событие |
OnAfterOpenDataSet |
| Описание |
Событие происходит после открытия датасета связанного с группой
(бандом). |
| Параметр проц. |
ds: TpFibDataSet |
| Пример |
нет. |
| Объект |
Группа |
| Событие |
OnBeforeOpenDataSet |
| Описание |
Событие происходит перед открытием датасета связанного с группой
(бандом). |
| Параметр проц. |
ds: TpFibDataSet |
| Пример |
нет. |
| Объект |
Группа |
| Событие |
OnAfterCreateDataSet |
| Описание |
Событие происходит после создания датасета связанного с группой
(бандом) |
| Параметр проц. |
ds: TpFibDataSet |
| Пример |
// SQL запрос формируется динамически из приложения
ds.SelectSQL.Text := HostAppl.Data.GetSQL('STUDENTID, FIO, SEX, FACULTY,
SPECIALITY') +
'
where S.STUDENTID in (@@StudentsID%0@) order by 2';
Params.Item('StudentsID').Value := HostAppl.Data.GetSelectedList('STUDENTID'); |
Описание параметров процедур
| Band:TDBBandInfo |
Описание класса:
TDBBandInfo = class(TBandInfo)
published
property
Name: String;
property
Stop: Boolean read FStop write
FStop;
property
Visible: Boolean read FVisible
write FVisible;
property
DataSet: TpFIBDataSet read FDataSet;
end; |
Описание свойств:
| Свойство |
Описание |
| Band.Name : String |
Имя банда (группы, для которой призошло событие). |
| Band.Stop : Boolean |
"True" - прекратить
отображение банда, "False"
- отображать банд. |
| Band.Visible : Boolean |
"True" - отображать
банд, "False" - не
отображать банд. |
| Band.DataSet : TpFIBDataSet |
Указатель на датасет, которому принадлежит банд. |
|
| Field:TDBFieldInfo |
Описание класса:
TDBFieldInfo = class(TFieldInfo)
published
property
FieldName: string read
FFieldName;
property
Value: OleVariant read FValue
write FValue;
property
Visible: Boolean read FVisible
write FVisible;
property
Format: string read
FFormat write FFormat;
property
DataSet: TpFIBDataSet read FDataSet;
end; |
Описание свойств:
| Свойство |
Описание |
| Field.FieldName |
Имя поля (параметра). |
| Field.Value : OleVariant |
Значение поля (параметра). |
| Field.Visible : Boolean |
"True" - отображать
поле (параметр), "False"
- не отображать поле (параметр). |
| Field.Format |
Получить формат параметра. Форматом считается все, что стоит
в параметре после знака "@".
Например: "~SEX@[м#ж][мужской#женский]~",
здесь форматом является текст: "[м#ж][мужской#женский]".
В данном примере в формате параметра заложено условие, реагирующее
на значение параметра "SEX". Если "SEX
= 'м'" в документе отобразится "мужской",
если "SEX = 'ж'" в
документе отобразится "женский".
Форматом может быть какой-либо еще текст и через "Field.Format"
к нему можно получить доступ. |
| Field.DataSet : TpFIBDataSet |
Указатель на датасет, которому принадлежит поле (параметр). |
|
| ds:TpFibDataSet |
Описание основных свойств:
| Свойство |
Описание |
| ds.Name : String |
Имя датасета. |
| ds.Active : Boolean |
"True" - открыт
датасет, "False" -
закрыт датасет. Чтобы открыть закрытый датасет следует свойству
присвоить "True". |
| ds.SelectSQL : TStrings |
SQL запрос датасета. Запрос можно задавать динамически только
при закрытом датасете. |
| ds.RecNo : Integer |
Номер текущей записи в датасете начиная с "1".
(работает корректно при ds.UniDirectional
= False) |
| ds.RecordCount : Integer |
Общее число записей в датасете. |
Полный перечень свойств приведен в "AKReport"
в справочнике редактора скрипта.
"TpFibDataSet" является
наследником "TDataSet",
поэтому доступны следующие свойства:
| Свойство |
Описание |
| ds.FieldByName(Const FieldName:string):TField |
Доступ к полям датасета по имени |
| ds.Bof : Boolean |
"True" - курсор
в начале датасета. |
| ds.Eof : Boolean |
"True" - курсор
в конце датасета. |
Полный перечень свойств "TDataSet"
приведен в "AKReport"
в справочнике редактора скрипта. |
|