Обработка событий заполнения
Существует два типа событий заполнения: для набора данных и для буфера временной таблицы набора данных. Соответственно эти события автоматически возникают во время операций заполнения набора данных или временной таблицы. Для каждого из них можно написать собственный обработчик.
В следующей таблице описаны события, которые срабатывают во время операции заполнения набора данных.
|
Событие |
Когда возникает |
Возможное применение |
| 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.
