Реализация потока данных |
Поток данных представляет из себя совокупность элементов потока, возможно вложенных.
Элементы потока бывают трёх разновидностей. Первая разновидность - элемент потока "нулевого уровня" для передачи переменных и т.д. Вторая разновидность реализуется с использованием ключевого слова table, третья - с применением ключевого слова dataset. Различие заключается в способе навигации по элементам потока.
Количество и последовательность записей в элементе типа table определяется текущей подцепкой таблицы.
Записи в элементе типа dataset создаются программистом. Для управления потоком используется процедура ContinueDataset. Следует иметь в виду, что событие cmOnProcess возникает после выборки записи. Таким образом, текущая запись попадает в отчет независимо от того, был вызов ContinueDataset или нет. Вызов ContinueDataset в cmOnProcess означает, что текущая запись не последняя.
Вложенность описываемых потоков используется для наглядности описания. Реальная вложенность потоков определяется подцепками в логической таблице.
Ниже приведён синтаксис реализации потоков данных:
<реализация-потока-данных> = datastream <имя-потока-данных> [ <элемент-потока> { <элемент-потока> } ] [ <обработчик> { <обработчик> } ]
Начиная с Атлантис 5.3.08 имеется возможность автоматического создания datastream по логической таблице:
<реализация-потока-данных> = datastream <имя-потока-данных> auto [(<имя-лог-таблицы>)] [<список-узлов>];
<имя-потока-данных> - идентификатор.
<имя-лог-таблицы> - имя логической таблицы. Если не указано, поток строится по главной логической таблице.
<список-узлов> - имена узлов логической таблицы, по которым необходимо построить datastream. Имена перечисляются через запятую. Список узлов может отсутствовать, тогда поток будет построен по всей логической таблице.
<элемент-потока> - элемент потока нулевого уровня, элемент потока table или элемент потока dataset.
<элемент-потока> = [ [ <имя-поля> ] ] <выражение> ; | table <имя-таблицы> [ onClick ( <ключевое-поле> ) ] ( <элемент-потока> {, <элемент-потока> } ) ; | dataset <имя-датасета> [ onClick ( <ключевое-поле> ) ] ( <элемент-потока> {, <элемент-потока> } ) ;
<имя-поля> - уникальное для элемента потока имя поля, доступное в генераторе отчётов и т.д. В случае, если имя не указано - полю будет автоматически присвоено сгенерированное имя и компилятор выдаст предупреждение.
<выражение> - вычисляемое выражение в текущем контексте.
<имя-таблицы> - уникальное в пределах потока данных имя элемента потока. Должно соответствовать имени одной из таблиц интерфейса. Для использования в генераторе отчётов и т.д.
<имя-датасета> - уникальное в пределах потока данных имя элемента потока. Для использования в генераторе отчётов и т.д.
<ключевое-поле> - поле элемента потока, значение которого используется для навигации. При обработке событий номер поля можно взять из переменной Target, а значение ключевого поля - из переменной ExprFieldValue. По значению ключевого поля можно выяснить текущую запись элемента потока. Ключевое поле должно быть соответствующим образом описано.
Начиная с Атлантис 5.3.03 конструкция onClick ( <ключевое-поле> ) игнорируется. Вместо нее в обработчике события OnPreviewClick формы отчета (в дизайнере ) необходимо сделаеть вызов метода GalaxyOnClick.
<обработчик> - конструкция, позволяющая назначать обработчики событий, возникающих при обработке потока данных.
<обработчик> = <обработчик-потока> | <обработчик-элемента-потока>
<обработчик-потока> - конструкция, позволяющая назначать обработчики событий на уровне всего потока данных.
Конструкция <обработчик-потока> доступна начиная с Атлантис 5.1.31.
В целом обработчик потока похож на обработчик элемента потока, но имя таблицы не указывается. В обработчике потока возникают два события: cmPreProcess и cmPostProcess.
Событие cmPreProcess возникает перед началом всего расчета один раз независимо от того, сколько бендов находится в форме. Событие cmPostProcess возникает после окончания расчета формы.
В обработчике потока выполняются действия, относящиеся к потоку в целом. В т.ч. для вызова визуализации необходимо в cmPreProcess вызвать функцию StartNewVisual, для остановки визуализации необходимо в cmPostProcess вызвать StopVisual.
Если функцию визуализации StartNewVisual вызывать в обработчике cmPreProcess для таблицы или dataset'а (т.е. по сути для бенда), то визуализация будет стартовать каждый раз, когда внутри Fast Report'а будет вызван метод GetFirst для таблицы или dataset'a. В этом случае для вложенных бендов (Master-Detail-Subdetail) визуализация стартует многократно.
Для прерывания формирования отчета нужно вызвать функцию BreakProcess или AbortProcess в обработчиках событий для таблиц или dataset'ов.
<обработчик-потока> = handleEvent <событие> : <оператор> { <событие> : <оператор> } end;
<обработчик-элемента-потока> - конструкция, позволяющая назначать обработчики, выполняющиеся при навигации по элементам потока данных.
<обработчик-элемента-потока> = handleEvent <имя-таблицы-или-датасета> <событие> : <оператор> { <событие> : <оператор> } end;
<имя-таблицы-или-датасета> - имя, идентифицируещее элемент потока, для которого задаются обработчики. Соответствующий элемент потока должен существовать. Перед именем ставится тип элемента потока (table или dataset). Если тип элемента не указан, предполагается table.
<имя-таблицы-или-датасета> = table <имя-таблицы> | dataset <имя-датасета>
<событие> - одна из констант cmPreProcess, cmOnProcess, cmPostProcess или cmOnClick.
<событие> = cmPreProcess | cmOnProcess | cmPostProcess | cmOnClick
cmPreProcess - генерируется перед выборкой первой записи из элемента потока. Другими словами, это событие генерируется каждый раз, когда FastReport запрашивает блок информации для Master или Detail данных.
В обработчике следует инициализировать ограничения для последующего построения выборки, установить флаги типа isFirstRec (признак начала выборки) и выполнить другие необходимые действия по организации обработки выборки.
cmOnProcess - генерируется перед выборкой каждой новой записи данных. Следует отметить, что событие cmOnProcess возникает как перед выборкой первой записи, так и перед выборкой каждой последующей записи.
В обработчике события cmOnProcess допустимо использовать функцию ContinueDataset, которая служит для управления элементом потока типа dataset. Вызов ContinueDataset в cmOnProcess означает, что текущая запись не последняя.
cmPostProcess - генерируется после выборки последней записи. Следует отметить, что cmPostProcess генерируется не всегда, а только в тех случаях, когда все записи таблицы были запрошены генератором отчета. В некоторых случаях (например, когда печатается только одна строка, или фиксированное количество строк, или когда отчет был прерван) событие cmPostProcess уровня table и dataset не возникает. В отличии от события cmPostProcess уровня datastream, которое возникает всегда (даже при наличии ошибок в форме).
cmOnClick - генерируется при щелчке в отчёте, если в конструкции datastream было задано onClick поле.
<оператор> - любой валидный оператор программы, включая блок begin..end.
Пример 1. Реализация потока данных
// -- dstream.vip -- #include dstream.vih interface SampleInterface; create view as select * from x$files; var i : integer; datastream SampleStream ( i; table x$files ( xf$code; [ SMPLNAME ] "(" + xf$name + ")"; ); ) end; end.
Поток данных SampleStream содержит два элемента потока.
Первый элемент потока содержит одно поле с именем SMPLVAR и значением переменной i. Такой элемент потока (элемент потока нулевого уровня) служит для передачи в отчёты переменных и других вычисляемых выражений, по которым не требуется навигация.
Второй элемент потока содержит два поля - SMPLCODE и SMPLNAME. Количество записей этого элемента потока данных равно количеству записей в таблице x$files.
Пример 2. Использование обработчиков потока данных
Существует возможность производить специальную обработку (например, при выборке данных из потока данных).
// -- dstream.vip -- #include dstream.vih interface SampleInterface; create view as select * from x$files; var counter : integer; datastream SampleStream ( table x$files ( [ SMPLCNTR ] counter; [ SMPLCODE ] xf$code; [ SMPLNAME ] "(" + xf$name + ")"; ); ) handleEvent cmPreProcess: StartNewVisual(vtRotateVisual, vfTimer+vfBreak+vfConfirm, 'Формируется отчет', 0); cmPostProcess: StopVisual('', 0); end; handleEvent x$files cmPreProcess: counter := 0; cmOnProcess: { counter := counter + 1; if( not NextVisual ) BreakProcess; } end; end; end.
В данном примере в поток данных включается поле с именем SMPLCNTR, в котором находится всегда порядковый номер записи.
Пример 3. Реализация потока данных с dataset
Возможно создание элементов потока данных с произвольным количеством записей, не связанных с таблицами. Для этого используется ключевое слово dataset. Количество записей контролируется программистом с использованием процедуры ContinueDataset.
// -- dstream.vip -- #include dstream.vih interface SampleInterface; create view as select * from x$files; var counter : integer; datastream SampleStream ( dataset SampleDataset ( [ SMPLCNTR ] counter; ); ) handleEvent dataset SampleDataset cmPreProcess : { counter := 0; } cmOnProcess : { counter := counter + 1; if (counter < 6) then ContinueDataset; } end; end; end.
В приведённом примере элемент потока данных SampleDataset будет содержать пять записей.
Пример 4. Использование переменных Target и ExprFieldValue
// -- dstream.vip -- #include dstream.vih interface SampleInterface; create view as select * from x$files; var counter : integer; datastream SampleStream ( dataset SampleDataset onclick(counter) ( [ SMPLTEXT ] 'Просто текст'; ); ) handleEvent dataset SampleDataset cmOnClick: { case Target of #SMPLTEXT: message('Событие для SMPLTEXT. ' + 'Значение ключевого поля: ' + ExprFieldValue, mfInformation); end; } cmPreProcess: { counter := 0; } cmOnProcess: { counter := counter + 1; if (counter < 6) then ContinueDataset; } end; end; end.
Пример 5. Автоматическая реализация потока данных по логической таблице
datastream DS0 auto (v_test) X$Users, X$RESOURCES; datastream DS1 auto (v_test1); datastream DS2 auto X$Users, X$RESOURCES; datastream DS3 auto;
Начиная с Атлантис 5.3.03 конструкция onClick ( <ключевое-поле> ) игнорируется.
Автоматическое создание datastream по логической таблице доступно начиная с Атлантис 5.3.08.
Конструкция <обработчик-потока> доступна начиная с Атлантис 5.1.31.
Атлантис 5.1.2x.