ABAP简单报表
使用 REUSE_ALV_GRID_DISPLAY_LVC 实现
代码与上一篇 《ABAP简单ALV报表实现 FUNCTION ALV 01》基本相同,主要不同的地方在于两个FM之间传值的内表结构不同。
另外,在此篇增加了FM使用事件的方法,例子中使用的是DATA CHANGED事件,个人认为这个事件比较重要。
最后,代码比较乱,但是能直接CV执行,使用的同学可以自行整理一下。
TABLES: SFLIGHT.
TYPES: BEGIN OF TY_OUTPUT.
INCLUDE TYPE SFLIGHT.
TYPES: ZBOX TYPE C,
ROW_COLOR TYPE C LENGTH 4, "行颜色
CELL_COLOR TYPE LVC_T_SCOL, "单元格颜色
SEATSOCC_O TYPE SFLIGHT-SEATSOCC.
TYPES: END OF TY_OUTPUT.
DATA: GT_OUTPUT TYPE TABLE OF TY_OUTPUT,
GS_OUTPUT TYPE TY_OUTPUT.
DATA: GT_FCAT TYPE LVC_T_FCAT. "字段属性内表
DATA: GS_FCAT TYPE LVC_S_FCAT. "字段属性结构
DATA: GS_LAYOUT TYPE LVC_S_LAYO. "布局属性
DATA: GT_SORT TYPE LVC_T_SORT. "排序内表
DATA: GS_SORT TYPE LVC_S_SORT. "排序结构
DATA: GT_FILTER TYPE LVC_T_FILT. "过滤器内表
DATA: GS_FILTER TYPE LVC_S_FILT. "过滤器结构
DATA: GT_EVENTS TYPE SLIS_T_EVENT. "事件内表
DATA: GS_EVENTS TYPE SLIS_ALV_EVENT. "事件结构
DATA: GV_COL TYPE I. "字段的列号
DATA: LS_SCOL TYPE LVC_S_SCOL. "单元格颜色内表
DATA: LT_SCOL TYPE LVC_T_SCOL. "单元格颜色结构
DATA: GS_GLAY TYPE LVC_S_GLAY. "回车回调
"定义事件接收类
CLASS LCL_EVENT_RECEIVER DEFINITION.
PUBLIC SECTION.
"数据改变事件
METHODS DATA_CHANGED FOR EVENT DATA_CHANGED OF CL_GUI_ALV_GRID
IMPORTING ER_DATA_CHANGED.
ENDCLASS.
"接收类的实现
CLASS LCL_EVENT_RECEIVER IMPLEMENTATION.
METHOD DATA_CHANGED.
PERFORM FRM_DATA_CHANGED USING ER_DATA_CHANGED.
ENDMETHOD.
ENDCLASS.
"给屏幕定义一个对象
DATA: G_ALV_GRID TYPE REF TO CL_GUI_ALV_GRID.
"接收类定义对象
DATA: G_CL_EVENT_RECEIVER TYPE REF TO LCL_EVENT_RECEIVER.
SELECTION-SCREEN BEGIN OF BLOCK BLK1 WITH FRAME.
SELECT-OPTIONS: S_CARRID FOR SFLIGHT-CARRID.
SELECTION-SCREEN END OF BLOCK BLK1.
START-OF-SELECTION.
"取值
SELECT *
INTO CORRESPONDING FIELDS OF TABLE GT_OUTPUT
FROM SFLIGHT
WHERE CARRID IN S_CARRID.
LOOP AT GT_OUTPUT ASSIGNING FIELD-SYMBOL(<FW_OUTPUT>).
IF <FW_OUTPUT>-CARRID EQ 'LH'.
<FW_OUTPUT>-ROW_COLOR = 'C300'. "行颜色
ENDIF.
<FW_OUTPUT>-SEATSOCC_O = <FW_OUTPUT>-SEATSMAX - <FW_OUTPUT>-SEATSOCC.
IF <FW_OUTPUT>-SEATSOCC EQ 0 .
CLEAR LS_SCOL.
LS_SCOL-FNAME = 'SEATSOCC'.
LS_SCOL-COLOR-COL = '3'.
LS_SCOL-COLOR-INT = '1'.
LS_SCOL-COLOR-INV = '0'.
APPEND LS_SCOL TO LT_SCOL.
ENDIF.
"单元格颜色
IF <FW_OUTPUT>-SEATSOCC_B EQ 0 .
CLEAR LS_SCOL.
LS_SCOL-FNAME = 'SEATSOCC_B'.
LS_SCOL-COLOR-COL = '3'.
LS_SCOL-COLOR-INT = '1'.
LS_SCOL-COLOR-INV = '0'.
APPEND LS_SCOL TO LT_SCOL.
ENDIF.
IF <FW_OUTPUT>-SEATSOCC_F EQ 0.
CLEAR LS_SCOL.
LS_SCOL-FNAME = 'SEATSOCC_F'.
LS_SCOL-COLOR-COL = '3'.
LS_SCOL-COLOR-INT = '1'.
LS_SCOL-COLOR-INV = '0'.
APPEND LS_SCOL TO LT_SCOL.
ENDIF.
IF LT_SCOL IS NOT INITIAL.
<FW_OUTPUT>-CELL_COLOR = LT_SCOL.
FREE LT_SCOL.
ENDIF.
ENDLOOP.
END-OF-SELECTION.
CLEAR GS_LAYOUT.
* GS_LAYOUT-KEY_HOTSPOT = 'X'.
GS_LAYOUT-COL_OPT = 'X'.
GS_LAYOUT-ZEBRA = 'X'.
GS_LAYOUT-BOX_FNAME = 'ZBOX'.
GS_LAYOUT-INFO_FNAME = 'ROW_COLOR'.
GS_LAYOUT-CTAB_FNAME = 'CELL_COLOR'.
DEFINE M_FIELDCAT.
CLEAR GS_FCAT.
GS_FCAT-FIELDNAME = &1.
GS_FCAT-REF_TABLE = &2.
GS_FCAT-REF_FIELD = &3.
GS_FCAT-SCRTEXT_L = &4.
GV_COL = GV_COL + 1.
GS_FCAT-COL_POS = GV_COL.
IF &1 EQ 'CARRID'.
GS_FCAT-HOTSPOT = 'X'.
ENDIF.
IF &1 EQ 'PRICE'.
GS_FCAT-EMPHASIZE = 'C710'.
ENDIF.
IF &1 = 'SEATSMAX'.
GS_FCAT-EDIT = 'X'.
ENDIF.
APPEND GS_FCAT TO GT_FCAT.
END-OF-DEFINITION.
REFRESH GT_FCAT.
CLEAR GV_COL.
M_FIELDCAT 'CARRID' 'SFLIGHT' 'CARRID' '航线'.
M_FIELDCAT 'CONNID' 'SFLIGHT' 'CONNID' '航班'.
M_FIELDCAT 'FLDATE' 'SFLIGHT' 'FLDATE' '航班日期'.
M_FIELDCAT 'PRICE' 'SFLIGHT' 'PRICE' '航空运费'.
M_FIELDCAT 'CURRENCY' 'SFLIGHT' 'CURRENCY' '价格'.
M_FIELDCAT 'PLANETYPE' 'SFLIGHT' 'PLANETYPE' '飞机类型'.
M_FIELDCAT 'SEATSMAX' 'SFLIGHT' 'SEATSMAX' '经济舱位'.
M_FIELDCAT 'SEATSOCC' 'SFLIGHT' 'SEATSOCC' '经济舱占据位'.
M_FIELDCAT 'SEATSOCC_O' 'SFLIGHT' 'SEATSOCC' '经济舱剩余位'.
M_FIELDCAT 'PAYMENTSUM' 'SFLIGHT' 'PAYMENTSUM' '当前预定总数'.
M_FIELDCAT 'SEATSMAX_B' 'SFLIGHT' 'SEATSMAX_B' '商务舱位'.
M_FIELDCAT 'SEATSOCC_B' 'SFLIGHT' 'SEATSOCC_B' '商务舱占据位'.
M_FIELDCAT 'SEATSMAX_F' 'SFLIGHT' 'SEATSMAX_F' '头等舱位'.
M_FIELDCAT 'SEATSOCC_F' 'SFLIGHT' 'SEATSOCC_F' '头等舱占据位'.
CLEAR GS_SORT.
GS_SORT-SPOS = '1'.
GS_SORT-FIELDNAME = 'FLDATE'.
GS_SORT-DOWN = 'X'.
APPEND GS_SORT TO GT_SORT.
CLEAR GS_SORT.
GS_SORT-SPOS = '2'.
GS_SORT-FIELDNAME = 'CONNID'.
GS_SORT-UP = 'X'.
APPEND GS_SORT TO GT_SORT.
CLEAR GS_FILTER.
GS_FILTER-FIELDNAME = 'CONNID'.
GS_FILTER-SIGN = 'E'.
GS_FILTER-OPTION = 'EQ'.
GS_FILTER-LOW = '2407'.
* GS_FILTER-VALUT = 'AA'.
APPEND GS_FILTER TO GT_FILTER.
"事件输入ALV
CLEAR GS_EVENTS.
GS_EVENTS-NAME = 'CALLER_EXIT'.
GS_EVENTS-FORM = 'FRM_EVENTS'.
APPEND GS_EVENTS TO GT_EVENTS.
GS_GLAY-EDT_CLL_CB = 'X'. "回车回调数据到内表
"调用FM生成ALV
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
* I_INTERFACE_CHECK = ' '
* I_BYPASSING_BUFFER =
* I_BUFFER_ACTIVE =
I_CALLBACK_PROGRAM = SY-CPROG
I_CALLBACK_PF_STATUS_SET = 'FRM_PF_STATUS'
I_CALLBACK_USER_COMMAND = 'FRM_USER_COMMAND'
I_CALLBACK_TOP_OF_PAGE = 'FRM_TOP_OF_PAGE'
* I_CALLBACK_HTML_TOP_OF_PAGE = 'FRM_HTML_TOP_OF_PAGE'
* I_CALLBACK_HTML_END_OF_LIST = ' '
* I_STRUCTURE_NAME =
* I_BACKGROUND_ID = ' '
* I_GRID_TITLE =
I_GRID_SETTINGS = GS_GLAY
IS_LAYOUT_LVC = GS_LAYOUT
IT_FIELDCAT_LVC = GT_FCAT
* IT_EXCLUDING =
* IT_SPECIAL_GROUPS_LVC =
IT_SORT_LVC = GT_SORT
IT_FILTER_LVC = GT_FILTER
* IT_HYPERLINK =
* IS_SEL_HIDE =
I_DEFAULT = 'X'
I_SAVE = 'A'
* IS_VARIANT =
IT_EVENTS = GT_EVENTS
* IT_EVENT_EXIT =
* IS_PRINT_LVC =
* IS_REPREP_ID_LVC =
* I_SCREEN_START_COLUMN = 0
* I_SCREEN_START_LINE = 0
* I_SCREEN_END_COLUMN = 0
* I_SCREEN_END_LINE = 0
* I_HTML_HEIGHT_TOP =
* I_HTML_HEIGHT_END =
* IT_ALV_GRAPHICS =
* IT_EXCEPT_QINFO_LVC =
* IR_SALV_FULLSCREEN_ADAPTER =
* IMPORTING
* E_EXIT_CAUSED_BY_CALLER =
* ES_EXIT_CAUSED_BY_USER =
TABLES
T_OUTTAB = GT_OUTPUT
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
FORM FRM_PF_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB.
SET PF-STATUS 'ZSTATUS'.
ENDFORM.
FORM FRM_USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
DATA: LV_MSG TYPE STRING.
CASE R_UCOMM.
WHEN '&IC1'. "如果字段设置HOTSPOT,这里就单击触发。否则,双击触发
READ TABLE GT_OUTPUT ASSIGNING FIELD-SYMBOL(<FW_OUTPUT>) INDEX RS_SELFIELD-TABINDEX.
IF SY-SUBRC EQ 0.
CONCATENATE '您选择了' <FW_OUTPUT>-FLDATE <FW_OUTPUT>-CARRID '航线' <FW_OUTPUT>-CONNID '号航班' INTO LV_MSG SEPARATED BY SPACE.
MESSAGE LV_MSG TYPE 'S'.
ENDIF.
WHEN ''.
WHEN OTHERS.
ENDCASE.
RS_SELFIELD-COL_STABLE = 'X'.
RS_SELFIELD-ROW_STABLE = 'X'.
RS_SELFIELD-REFRESH = 'X'.
ENDFORM.
FORM FRM_TOP_OF_PAGE.
DATA: LT_HEADER TYPE SLIS_T_LISTHEADER.
DATA: LS_HEADER TYPE SLIS_LISTHEADER.
DATA: LV_DATE TYPE C LENGTH 14.
CLEAR LS_HEADER.
LS_HEADER-TYP = 'H'.
* LS_HEADER-TYP = 'H'.
LS_HEADER-INFO = '今日航班表'.
APPEND LS_HEADER TO LT_HEADER.
WRITE SY-DATUM TO LV_DATE USING EDIT MASK '____年__月__日'.
CLEAR LS_HEADER.
LS_HEADER-TYP = 'S'.
LS_HEADER-KEY = '当前日期'.
LS_HEADER-INFO = LV_DATE.
APPEND LS_HEADER TO LT_HEADER.
CLEAR LS_HEADER.
LS_HEADER-TYP = 'A'.
* LS_HEADER-KEY = '当前日期'.
LS_HEADER-INFO = '感谢您的光临'.
APPEND LS_HEADER TO LT_HEADER.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
IT_LIST_COMMENTARY = LT_HEADER
* I_LOGO =
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.
FORM FRM_HTML_TOP_OF_PAGE USING PR_DOCUMENT TYPE REF TO CL_DD_DOCUMENT..
CALL METHOD PR_DOCUMENT->ADD_TEXT
EXPORTING
TEXT = '今日航班表'
SAP_FONTSIZE = CL_DD_DOCUMENT=>LARGE
SAP_COLOR = CL_DD_DOCUMENT=>LIST_HEADING.
CALL METHOD PR_DOCUMENT->NEW_LINE.
CALL METHOD PR_DOCUMENT->NEW_LINE.
CALL METHOD PR_DOCUMENT->ADD_TEXT
EXPORTING
TEXT = 'LINK'
SAP_FONTSIZE = CL_DD_DOCUMENT=>MEDIUM.
CALL METHOD PR_DOCUMENT->ADD_GAP
EXPORTING
WIDTH = 5.
CALL METHOD PR_DOCUMENT->ADD_LINK
EXPORTING
NAME = '123'
TOOLTIP = '百度'
URL = 'https://www.baidu.com/'
TEXT = 'BAIDU'.
ENDFORM.
FORM FRM_EVENTS USING FU_GRID TYPE SLIS_DATA_CALLER_EXIT.
"我把这个FM理解为 Function alv 的实例化
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = G_ALV_GRID.
************"data changed事件特殊的点,需要注册一个可编辑的方法
CALL METHOD G_ALV_GRID->REGISTER_EDIT_EVENT
EXPORTING
I_EVENT_ID = CL_GUI_ALV_GRID=>MC_EVT_MODIFIED "数据发送改变时触发data changed事件
* I_EVENT_ID = CL_GUI_ALV_GRID=>MC_EVT_ENTER "同上,不过这个是回车触发
EXCEPTIONS
ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
"实例化接收对象
CREATE OBJECT G_CL_EVENT_RECEIVER.
***为alv注册事件
SET HANDLER G_CL_EVENT_RECEIVER->DATA_CHANGED FOR G_ALV_GRID.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DATA_CHANGED
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> ER_DATA_CHANGED
*& --> E_ONF4
*& --> E_ONF4_BEFORE
*& --> E_ONF4_AFTER
*& --> E_UCOMM
*&---------------------------------------------------------------------*
FORM FRM_DATA_CHANGED USING P_DATA_CHANGED TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
DATA: LT_MOD TYPE LVC_T_MODI. "被修改的单元格的信息
DATA: LS_MOD TYPE LVC_S_MODI.
LOOP AT P_DATA_CHANGED->MT_MOD_CELLS INTO LS_MOD.
IF LS_MOD-FIELDNAME EQ 'SEATSMAX'.
READ TABLE GT_OUTPUT ASSIGNING FIELD-SYMBOL(<GS_OUTPUT>) INDEX LS_MOD-ROW_ID.
IF SY-SUBRC EQ 0.
<GS_OUTPUT>-SEATSMAX = LS_MOD-VALUE.
<GS_OUTPUT>-SEATSOCC_O = <GS_OUTPUT>-SEATSMAX - <GS_OUTPUT>-SEATSOCC.
ENDIF.
ENDIF.
ENDLOOP.
"刷新才能看到数据改变的效果
PERFORM FRM_REFRESH_TABLE.
ENDFORM.
FORM FRM_REFRESH_TABLE.
DATA: LS_STBL TYPE LVC_S_STBL.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = G_ALV_GRID.
LS_STBL-ROW = 'X'.
LS_STBL-COL = 'X'.
"刷新屏幕
CALL METHOD G_ALV_GRID->REFRESH_TABLE_DISPLAY
EXPORTING
IS_STABLE = LS_STBL
* I_SOFT_REFRESH = 'X'
EXCEPTIONS
FINISHED = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM.
OVER。