Обработка событий заполнения
Существует два типа событий заполнения: для набора данных и для буфера временной таблицы набора данных. Соответственно эти события автоматически возникают во время операций заполнения набора данных или временной таблицы. Для каждого из них можно написать собственный обработчик.
В следующей таблице описаны события, которые срабатывают во время операции заполнения набора данных.
Событие |
Когда возникает |
Возможное применение |
BEFORE-FILL | Перед извлечением первой записи в операции FILL. Срабатывает один раз для каждой операции FILL. |
|
AFTER-FILL | После извлечения последней записи в операции FILL. Срабатывает один раз для каждой операции FILL. |
|
Примечание: события заполнения не срабатывают если атрибут FILL-MODE для временной таблицы набора данных имеет значение NO-FILL.
Следующий пример показывает обработку события BEFORE-FILL, при срабатывании которого формируется верхнеуровневый запрос для операции FILL.
PROCEDURE preDataSetFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. QUERY qOrder:QUERY-PREPARE("FOR EACH ORDER WHERE ORDER.ORDERNUM = " + STRING(iOrderNum) + ", FIRST CUSTOMER OF ORDER, FIRST SALESREP OF ORDER"). END PROCEDURE.
В этой внутренней процедуре (preDataSetFill) подготавливается запрос (qOrder) для извлечения записей из таблиц Order, Customer и SalesRep на основе значения из переменной (iOrderNum).
Следующий пример показывает обработку события AFTER-FILL, при срабатывании которого выполняется отключение от источников данных всех временных таблиц.
PROCEDURE postDataSetFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. DEFINE VARIABLE iBuff AS INTEGER NO-UNDO. DO iBuff = 1 TO DATASET dsOrderOrderLine:NUM-BUFFERS: DATASET dsOrderOrderLine:GET-BUFFER-HANDLE(iBuff): DETACH-DATA-SOURCE(). END. END PROCEDURE.
Эта процедура использует атрибут NUM-BUFFERS и метод GET-BUFFER-HANDLE для отключения источников в одном вызове процедуры.
В следующей таблице описаны события, которые срабатывают во время операции заполнения буфера временной таблицы из набора данных.
Событие | Когда возникает | Возможное применение |
BEFORE-FILL | Срабатывает один раз перед извлечением первой записи для родительской временной таблицы.
Срабатывает один раз после извлечения записи для родительской таблицы, но перед извлечением записи для дочерней таблицы. |
|
AFTER-FILL | Срабатывает один раз после извлечением последней записи для родительской временной таблицы.
Срабатывает один раз после извлечения всех дочерних записей для родительской записи. |
|
BEFORE-ROW-FILL | Срабатывает перед извлечением каждой записи во время заполнения конкретной временной таблицы. |
|
AFTER-ROW-FILL | Срабатывает после извлечения каждой записи во время заполнения конкретной временной таблицы. |
|
Следующий пример показывает обработку события BEFORE-FILL для родительской временной таблицы ttOrder, при срабатывании которого выполняется подключение к источнику данных.
PROCEDURE preOrderFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. BUFFER ttOrder:ATTACH-DATA-SOURCE(DATA-SOURCE srcOrder:HANDLE). BUFFER ttOrderLine:ATTACH-DATA-SOURCE(DATA-SOURCE srcOline:HANDLE). BUFFER ttItem:ATTACH-DATA-SOURCE(DATA-SOURCE srcItem:HANDLE). END PROCEDURE.
Примечание: если вы хотите заполнить временную таблицу из источников, не связанных с базой данных, например, из JSON, то событие BEFORE-FILL можно использовать для вызова процедуры, которая заполнит временную таблицу.
Следующий пример обработки события AFTER-FILL для временной таблицы ttOrderLine выполняет:
- После заполнения таблицы ttOrderLine для текущего заказа (все записи OrderLines доступны), в переменной dTotal аккумулируются значения из поля ExtendedPrice таблицы ttOrderLine.
- Итоговое значение переменной dTotal присваивается полю OrderTotal таблицы ttOrder.
PROCEDURE postOlineFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. DEFINE VARIABLE dTotal AS DECIMAL NO-UNDO. FOR EACH ttOrderLine WHERE ttOrderLine.OrderNum = ttOrder.OrderNum: dTotal = dTotal + ttOrderLine.ExtendedPrice. END. ttOrder.OrderTotal = dTotal. END PROCEDURE.
Следующий пример обработки события BEFORE-ROW-FILL для временной таблицы ttOrderLine выполняет фильтрацию дочерних записей во время выполнения операции FILL:
- Перед сохранением строки в ttOrderLine проверяется значение поля Discount.
- Если значение поля Discount больше 10, то процедура завершается без добавления строки в таблицу. Иными словами, процедура заполняет временную таблицу ttOrderLine только записями, у которых скидка меньше или равна 10.
PROCEDURE preOrderLineRowFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. IF OrderLine.Discount > 10 THEN RETURN NO-APPLY. END PROCEDURE.
И последний пример. После извлечения и сохранения во временную таблицу каждой записи срабатывает событие AFTER-ROW-FILL.
Следующий код обрабатывает это событие, преобразуя символы из поля ItemName в прописные.
PROCEDURE postItemRowFill: DEFINE INPUT PARAMETER DATASET FOR dsOrderOrderLine. ASSIGN ttItem.ItemName = CAPS(ttItem.ItemName). END PROCEDURE.