为什么需要自定义F4?
实际业务场景经常要使用到,限制权限,可选值啥的,类似地图选项
ALV中怎么实现自定义F4?
1.选择对应的事件的代码,通常使用CALLER EXIT 然后指定对应调用的FORM,代码如下
GS_EVENTS-NAME = 'CALLER_EXIT'.
GS_EVENTS-FORM = 'FRM_CALLER_EXIT'. "指定FORM调用
APPEND GS_EVENTS TO GT_EVENTS.
"附可选的事件
CALLER_EXIT
USER_COMMAND
TOP_OF_PAGE
TOP_OF_COVERPAGE
END_OF_COVERPAGE
FOREIGN_TOP_OF_PAGE
FOREIGN_END_OF_PAGE
PF_STATUS_SET
LIST_MODIFY
TOP_OF_LIST
END_OF_PAGE
END_OF_LIST
AFTER_LINE_OUTPUT
BEFORE_LINE_OUTPUT
REPREP_SEL_MODIFY
SUBTOTAL_TEXT
GROUPLEVEL_CHANGE
2.定义类和实现类,用于事件的处理和拦截
"定义类
CLASS LCL_EVENT_RECEIVER DEFINITION."类名
PUBLIC SECTION.
METHODS HANDLE_F4 FOR EVENT ONF4 OF CL_GUI_ALV_GRID
IMPORTING E_FIELDNAME
E_FIELDVALUE
ES_ROW_NO
ER_EVENT_DATA
ET_BAD_CELLS
E_DISPLAY.
ENDCLASS. "LCL_EVENT_RECEIVER DEFINITION
CLASS LCL_EVENT_RECEIVER IMPLEMENTATION.
METHOD HANDLE_F4.
CASE E_FIELDNAME.
WHEN 'YOURFIELD'. "自定义的字段
PERFORM F4_HELP_DIY USING ET_BAD_CELLS
ES_ROW_NO
ER_EVENT_DATA
E_DISPLAY
E_FIELDNAME .
ENDCASE.
ENDMETHOD. "HANDLE_F4
ENDCLASS. "LCL_EVENT_RECEIVER IMPLEMENTATION
3.注册事件和需要拦截的自定义F4
*FORM FRM_CALLER_EXIT USING LS_DATA TYPE SLIS_DATA_CALLER_EXIT.
CHECK SY-BATCH = ''. "后台执行获取对象失败
DATA : LT_F4 TYPE LVC_T_F4,
LS_F4 TYPE LVC_S_F4.
DATA GT_EVENT_RECEIVER TYPE REF TO LCL_EVENT_RECEIVER.
*获取的全局ALV对象
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = GCL_ALV_GRID.
LS_F4-FIELDNAME = 'YOUFIELD'. "(需要定义F4帮助按钮的字段)
LS_F4-REGISTER = 'X'.
LS_F4-GETBEFORE = 'X'.
LS_F4-CHNGEAFTER = 'X'.
INSERT LS_F4 INTO TABLE LT_F4.
*注册拦截的F4
CALL METHOD GCL_ALV_GRID->REGISTER_F4_FOR_FIELDS
EXPORTING
IT_F4 = LT_F4[].
IF SY-SUBRC <> 0.
* Implement suGT_OUTle error handling here
ENDIF.
*创建类 类似 new OBJ
CREATE OBJECT GT_EVENT_RECEIVER.
*设置拦截
SET HANDLER GT_EVENT_RECEIVER->HANDLE_F4 FOR GCL_ALV_GRID.
ENDFORM. "F_CALLER_EXIT
54.F4时需要执行的逻辑过程
FORM F4_HELP_AGRBU USING ET_BAD_CELLS TYPE LVC_T_MODI
ES_ROW_NO TYPE LVC_S_ROID
ER_EVENT_DATA TYPE REF TO CL_ALV_EVENT_DATA
E_DISPLAY TYPE C
E_FIELDNAME TYPE LVC_FNAME.
DATA: LT_RETURN TYPE STANDARD TABLE OF DDSHRETVAL,
LS_RETURN TYPE DDSHRETVAL.
DATA :LV_EQART TYPE EQART.
FIELD-SYMBOLS: <ITAB> TYPE LVC_T_MODI.
DATA: LS_MODI TYPE LVC_S_MODI.
ASSIGN ER_EVENT_DATA->M_DATA->* TO <ITAB>.
IF E_FIELDNAME = 'YOURFIELD'. "展示内表字段
CLEAR GS_OUT.
READ TABLE GT_OUT INTO GS_OUT INDEX ES_ROW_NO-ROW_ID.
SELECT *
FROM YOURFIELDTAB
INTO LT_ZBGRU.
ENDIF.
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
RETFIELD = 'EQUNR' "筛选内表里面的字段
DYNPPROG = SY-REPID
DYNPNR = SY-DYNNR
DYNPROFIELD = 'GS_OUT-YOURFIELD' "ALV内表字段
VALUE_ORG = 'S'
" CALLBACK_PROGRAM = SY-REPID
TABLES
VALUE_TAB = LT_ZBGRU "需要显示帮助的值内表
RETURN_TAB = LT_RETURN "返回值
EXCEPTIONS
PARAMETER_ERROR = 1
NO_VALUES_FOUND = 2
OTHERS = 3.
IF SY-SUBRC = 0.
****将选的值填入ALV字段中
READ TABLE GT_OUT INTO GS_OUT INDEX ES_ROW_NO-ROW_ID.
IF SY-SUBRC = 0.
READ TABLE LT_RETURN INTO LS_RETURN INDEX 1.
IF LS_RETURN-FIELDVAL IS NOT INITIAL.
LS_MODI-ROW_ID = ES_ROW_NO-ROW_ID.
LS_MODI-FIELDNAME = 'ABGRU'.
LS_MODI-VALUE = LS_RETURN-FIELDVAL.
APPEND LS_MODI TO <ITAB>.
CLEAR LS_MODI.
ENDIF.
*设置事件处理标记,这样就不会走进常规的F4事件
ER_EVENT_DATA->M_EVENT_HANDLED = 'X'.
ENDIF.
ENDIF.
ENDFORM.
5.最后一步啦,将事件放到ALV中、
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
IT_EVENTS = GT_EVENTS"增加这个字段