ФМ предназначен для вывода модальных и не модальных окон с ABAP листингом (это который write-ми рисуется)
позволяет нарисовать произвольный листинг в модальном и не модальном окне, есть возможности для обработки событий листинга at line-selection, at user-commsnd есть приятные фишки для обновления листинга без изменения Scroll позиции листинга. Вся функциональность листинга собирается в одной подпрограмме - на мой взгляд это удобно в плане читабельности/редактируемости программы
Условия использования: копирайтик мой не затирайте . Доработки приветствуются, но копирайт не трогайте (можете свой рядом дописать, если очень хочется).
Использую ФМ уже несколько лет - думаю ошибок в нём не осталось
TOP:Code:
FUNCTION-POOL YDKLIST NO STANDARD PAGE HEADING.
*----------------------------------------------------------------------*
*& Группа функций для вывода модальных и не модальных ABAP листингов.
*& Автор: Киянов Дмитрий Евгеньевич
*& E-mail: DKiyanov@mail.ru
*----------------------------------------------------------------------*
INCLUDE YDKLIST.
INCLUDE <%_LIST>.
DATA: RCALLBACK_PROGRAM LIKE SY-REPID,
RCALLBACK_FORM(30) TYPE C.
DATA: GCALL_MODE TYPE C.
FIELD-SYMBOLS: <GVAR>,
<GTAB> TYPE STANDARD TABLE.
FORM CALLEVENT USING AEVENT ACTIVE.
DATA: EVENT LIKE SY-UCOMM.
DATA: PAGEINDEX LIKE SY-CPAGE,
LINEINDEX LIKE SY-STARO,
COLUMNIND LIKE SY-STACO,
CURSORCOL LIKE SY-CUCOL,
CURSORROW LIKE SY-CUROW,
CURSOR_SET TYPE C,
LIN TYPE I.
IF ACTIVE = 'X'.
PAGEINDEX = SY-CPAGE.
LINEINDEX = SY-STARO.
COLUMNIND = SY-STACO.
GET CURSOR LINE CURSORROW OFFSET CURSORCOL.
IF SY-SUBRC = 0.
CURSOR_SET = 'X'.
ENDIF.
CURSORCOL = SY-CUCOL.
CURSORROW = SY-CUROW.
ENDIF.
EVENT = AEVENT.
PERFORM XCALLEVENT USING EVENT.
CASE EVENT.
WHEN EV_CANC.
SY-SUBRC = 4.
LEAVE LIST-PROCESSING.
WHEN EV_OKAY.
CLEAR SY-SUBRC.
LEAVE LIST-PROCESSING.
ENDCASE.
CHECK ACTIVE = 'X'.
CASE EVENT.
WHEN EV_RESTART.
PERFORM XCALLEVENT USING: EV_START, EV_LIST.
SUBTRACT 1 FROM SY-LSIND.
WHEN EV_NEW.
PERFORM XCALLEVENT USING EV_LIST.
WHEN EV_RENEW.
PERFORM XCALLEVENT USING EV_LIST.
SUBTRACT 1 FROM SY-LSIND.
WHEN EV_REFRESH.
PERFORM XCALLEVENT USING EV_LIST.
IF SY-LINNO < LINEINDEX.
* lineindex = 0.
* lineindex = sy-linno - 2.
ENDIF.
SCROLL LIST INDEX SY-LSIND TO PAGE PAGEINDEX
LINE LINEINDEX.
SCROLL LIST INDEX SY-LSIND TO COLUMN COLUMNIND.
IF CURSOR_SET = 'X'.
SET CURSOR CURSORCOL CURSORROW.
ENDIF.
SUBTRACT 1 FROM SY-LSIND.
ENDCASE.
ENDFORM.
FORM XCALLEVENT USING EVENT.
CASE GCALL_MODE.
WHEN 'X'.
PERFORM (RCALLBACK_FORM)
IN PROGRAM (RCALLBACK_PROGRAM)
TABLES <GTAB>
USING EVENT <GVAR>
IF FOUND.
WHEN 'T'.
PERFORM (RCALLBACK_FORM)
IN PROGRAM (RCALLBACK_PROGRAM)
TABLES <GTAB>
USING EVENT
IF FOUND.
WHEN 'V'.
PERFORM (RCALLBACK_FORM)
IN PROGRAM (RCALLBACK_PROGRAM)
USING EVENT <GVAR>
IF FOUND.
WHEN ' '.
PERFORM (RCALLBACK_FORM)
IN PROGRAM (RCALLBACK_PROGRAM)
USING EVENT
IF FOUND.
ENDCASE.
ENDFORM.
MODULE LIST OUTPUT.
LEAVE TO LIST-PROCESSING.
PERFORM CALLEVENT USING: EV_START ' ', EV_LIST ' '.
SET SCREEN 0. LEAVE SCREEN.
ENDMODULE. " LIST OUTPUT
TOP-OF-PAGE.
PERFORM CALLEVENT USING EV_TOP ' '.
TOP-OF-PAGE DURING LINE-SELECTION.
PERFORM CALLEVENT USING EV_TOPD ' '.
AT LINE-SELECTION.
PERFORM CALLEVENT USING EV_LINE 'X'.
AT USER-COMMAND.
PERFORM CALLEVENT USING SY-UCOMM 'X'.
ФМ YDK_List:Code:
FUNCTION YDK_LIST.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(CALLBACK_PROGRAM) TYPE SY-REPID OPTIONAL
*" REFERENCE(CALLBACK_FORM)
*" REFERENCE(COL) DEFAULT 5
*" REFERENCE(ROW) DEFAULT 5
*" REFERENCE(WIDTH) OPTIONAL
*" REFERENCE(HEIGHT) OPTIONAL
*" CHANGING
*" VALUE(VAR) OPTIONAL
*" VALUE(TAB) OPTIONAL
*" EXCEPTIONS
*" CANCEL
*"----------------------------------------------------------------------
DATA: RCOL TYPE I,
BROW TYPE I.
DATA: LCALLBACK_PROGRAM LIKE SY-REPID,
LCALLBACK_FORM(30) TYPE C.
DATA: LCALL_MODE TYPE C.
DATA: SUBRC LIKE SY-SUBRC.
FIELD-SYMBOLS: <LVAR>,
<LTAB> TYPE ANY TABLE.
LCALLBACK_PROGRAM = RCALLBACK_PROGRAM.
LCALLBACK_FORM = RCALLBACK_FORM.
LCALL_MODE = GCALL_MODE.
RCALLBACK_PROGRAM = CALLBACK_PROGRAM.
IF RCALLBACK_PROGRAM IS INITIAL.
CALL 'AB_GET_CALLER' ID 'PROGRAM' FIELD RCALLBACK_PROGRAM.
ENDIF.
RCALLBACK_FORM = CALLBACK_FORM.
IF <GVAR> IS ASSIGNED. ASSIGN <GVAR> TO <LVAR>. ENDIF.
IF <GTAB> IS ASSIGNED. ASSIGN <GTAB> TO <LTAB>. ENDIF.
UNASSIGN <GVAR>.
UNASSIGN <GTAB>.
IF VAR IS REQUESTED. ASSIGN VAR TO <GVAR>. ENDIF.
IF TAB IS REQUESTED. ASSIGN TAB TO <GTAB>. ENDIF.
IF <GVAR> IS ASSIGNED
AND <GTAB> IS ASSIGNED. GCALL_MODE = 'X'.
ELSEIF <GTAB> IS ASSIGNED. GCALL_MODE = 'T'.
ELSEIF <GVAR> IS ASSIGNED. GCALL_MODE = 'V'.
ELSE. GCALL_MODE = ' '.
ENDIF.
IF WIDTH IS INITIAL AND HEIGHT IS INITIAL.
CALL SCREEN 0100.
ELSE.
RCOL = COL + WIDTH.
BROW = ROW + HEIGHT.
CALL SCREEN 0110 STARTING AT COL ROW
ENDING AT RCOL BROW.
ENDIF.
SUBRC = SY-SUBRC.
RCALLBACK_PROGRAM = LCALLBACK_PROGRAM.
RCALLBACK_FORM = LCALLBACK_FORM.
UNASSIGN <GVAR>.
UNASSIGN <GTAB>.
IF <LVAR> IS ASSIGNED. ASSIGN <LVAR> TO <GVAR>. ENDIF.
IF <LTAB> IS ASSIGNED. ASSIGN <LTAB> TO <GTAB>. ENDIF.
GCALL_MODE = LCALL_MODE.
IF SUBRC <> 0.
RAISE CANCEL.
ENDIF.
ENDFUNCTION.
Забыл сразу написать про экраны, спасибо
Besa и
Silence1 - напомнили
Надо созадать в группе функций два экрана
0100 - обычный
0110 - модальный (в свойствах экрана поставить галку "Модальное диалоговое окно")
в экранах ничего рисовать не надо, экранная логика у них одинаковая
Экранная логикаCode:
PROCESS BEFORE OUTPUT.
MODULE LIST.
PROCESS AFTER INPUT.
В PAI ничего указывать не надо
Инклюд с константамиCode:
*** INCLUDE YDKlist.
*----------------------------------------------------------------------*
*& Инклюд с константами для группы функций YDKLIST
*& Автор: Киянов Дмитрий Евгеньевич
*& E-mail: DKiyanov@mail.ru
*----------------------------------------------------------------------*
CONSTANTS:
* Входящие события
EV_START(5) VALUE 'START', " Выполняется один раз при вызове или .
EV_LIST(4) VALUE 'LIST', " Отрисовка списка (Write...)
EV_TOP(3) VALUE 'TOP', " Top-Of-Page
EV_TOPD(4) VALUE 'TOPD', " Top-Of-Page DURING LINE-SELECTION
EV_LINE(4) VALUE 'LINE', " At Line-Selection
* Прочие события " At User-Command (sy-ucomm)
* Исходящие комманды
EV_NEW(3) VALUE 'NEW', " Отрисовка нового списка
EV_RENEW(5) VALUE 'RENEW', " Повторная отрисовка списка
EV_REFRESH(7) VALUE 'REFRESH', " Повт. отрисовка списка с сохр. поз.
EV_RESTART(7) VALUE 'RESTART', " Повтор события START и NEW
EV_CANC(4) VALUE 'CANC', " Отмена - выход из модального сост.
EV_OKAY(4) VALUE 'OKAY'. " Выполн. - выход из модального сост.
** Пример использования
* CALL FUNCTION 'YDK_LIST'
* EXPORTING
** CALLBACK_PROGRAM = SY-CPROG
* CALLBACK_FORM = 'LIST'
** COL = 5
** ROW = 5
** WIDTH =
** HEIGHT =
* EXCEPTIONS
* CANCEL = 1
* OTHERS = 2.
*
*FORM LIST USING EVENT.
* CASE EVENT.
* WHEN EV_START.
** например: Готовим данные
* WHEN EV_LIST.
** Рисуем листинг
* SET PF-STATUS 'xxx'. " Устанавливаем статус
* SET TITLEBAR 'xxx'. " Устанавливаем заголовок
* NEW-PAGE LINE-SIZE nnn. " Устанавливаем ширину списка
* WRITE ....
* WHEN EV_TOP OR EV_TOPD.
** Рисуем заголовок
* WHEN EV_LINE.
** Реакция на щелчёк мышью (AT LINE-SELECTION)
** WHEN ... Реакция на кнопки (AT USER-COMMAND -> event = sy-ucomm)
* ENDCASE.
*ENDFORM.
Пример использованияCode:
REPORT ytest_ydklist.
INCLUDE ydklist.
CALL FUNCTION 'YDK_LIST'
EXPORTING
* CALLBACK_PROGRAM = " Не обязательный - если не указан то равен текущей программе
callback_form = 'LIST'
* COL = 5
* ROW = 5
width = 15 " Если указан то листинг будет модальным (в окошке)
height = 5 " Если указан то листинг будет модальным (в окошке)
* CHANGING
* VAR = " Переменная передаваемая в подпрограмму - влияет на набор параметров подпрограммы
* TAB = " Таблица передаваемая в подпрограмму - влияет на набор параметров подпрограммы не забываем указывать [] если таблица с заголовком
EXCEPTIONS
cancel = 1 " генерируется если event = ev_canc
OTHERS = 2.
FORM LIST USING EVENT. " на набор параметров подпрограммы влияют параметры ФМ: VAR и TAB
CASE EVENT.
WHEN EV_START.
* например: Готовим данные
WHEN EV_LIST.
* Рисуем листинг
* SET PF-STATUS 'xxx'. " Устанавливаем статус
* SET TITLEBAR 'xxx'. " Устанавливаем заголовок
* NEW-PAGE LINE-SIZE nnn. " Устанавливаем ширину списка
write: / 'Hello world!'.
WHEN EV_TOP OR EV_TOPD.
* Рисуем заголовок
WHEN EV_LINE.
* Реакция на щелчёк мышью (AT LINE-SELECTION)
* WHEN ... Реакция на кнопки (AT USER-COMMAND -> event = sy-ucomm)
ENDCASE.
ENDFORM.
В событиях EV_LINE и AT USER-COMMAND можно возвращать значение переменной event
например можно написать:
event = ev_refresh.
это приведёт повторной отрисовке листинга.. генерация события ev_list...