我们都知道 ABAP Object 比传统的 ABAP 非常强大。在这里,我想分享我使用 ABAP 对象克服 SALV mdoel 限制的最佳实验之一。
起源
最初,我在 SCN 上发布了这篇文章 – ABAP 对象的强大功能:克服 SALV 模型的限制,它也受到了很多批评和赞扬。当 SCN 迁移到新系统时,代码片段格式丢失。所以,我决定将其与格式一起移动到此处。
背景
我正在阅读 CL_SALV_TABLE
上的帮助,以更深入地了解如何有效地使用这个新的 SALV 模型。当我看到 Recommendation and Restriction 部分时,我惊讶地读到“Tables displayed with ALV are not ready for input”。
我很难理解这个限制,因为:新的 SALV 模型是统一的面向对象模型,它有某种包装类,最终将 FM 称为 REUSE_ALV_GRID_DISPLAY
或 REUSE_ALV_LIST_DISPLAY
;类 GL_GUI_ALV_GRID
等。那么,如果使用 CL_GUI_ALV_GRID
创建的 ALV 可以准备好输入,为什么使用 SALV 模型创建的 ALV 不能是“准备好输入”呢?这促使我分析如何将 ALV 全屏设置为“Set ready for Input”。
寻找解决方案的旅程
通过设置断点和调试,我了解到,当我尝试生成全屏 ALV 时,它会调用 FM REUSE_ALV_GRID_DISPLAY
,而该 FM 反过来使用类 CL_GUI_ALV_GRID
来生成 ALV。
几个月前,我遇到了一个非常强大的函数模块 GET_GLOBALS_FROM_SLVC_FULLSCR
它为我们提供了 GL_GUI_ALV_GRID
类型的对象,该对象是为了生成全屏 ALV 而创建的。我已经在几个程序中使用了这个 FM 来实现一些使用 FM REUSE_ALV_GRID_DISPLAY
无法实现的功能。包括了如下这些:
基本上,为了实现全屏 ALV 的这种无法实现的功能,我使用 FM GET_GLOBALS_FROM_SLVC_FULLSCR
获取对象,并使用 CL_GUI_GRID_DISPLAY
中可用的方法,然后使用 refresh
方法来刷新 ALV。
基于假设 – 如果我从 SALV 模型获取 ALV 对象,那么我可以将 SALV 模型 ALV 设置为“Set Ready for input” – 我已开始在 SALV 模型中搜索 ALV 对象。在 SALV 模型 CL_SALV_MODEL
的最顶层节点,我得到了可以为我提供 ALV Grid 对象的方法 (GET_GRID
)。
UML 图包含 SALV 层次结构和R_CONTROLLER的可见性:
类 CL_SALV_MODEL
有一个 protected 属性 R_CONTROLLER
它包含我访问 GRID 对象所需的一切。所以,我尝试直接访问该属性,但显然我没有工作,因为我没有 CL_SALV_MODEL
的对象引用。到这个时候,我已经尝试了所有正常的方法来访问R_CONTROLLER
- 比如 Feild 符号从内存中访问对象,但这也不起作用。
解决方法
我知道我必须以不同的方式思考,我尝试从 CL_SALV_MODEL_LIST
类继承该类,将 ALV 模型传递给该类,并尝试访问 R_CONTROLLER
和 BINGO
——我能够访问我继承的类中的 R_CONTROLLER
。
UML 图显示了 iherited 类以及现有的 SALV 模型:
要遵循的步骤:
- 从
CL_SALV_MODEL_LIST
继承到本地类LCL_SALV_MODEL
- 生成 SALV 模型以生成 ALV 对象
- 使 narrow casting 从 ALV 对象获取
CL_SALV_MODEL
对象 - 将此
CL_SALV_MODEL
对象传递给继承的类LCL_SALV_MODEL
。由于LCL_SALV_MODEL
是从CL_SALV_MODEL_LIST
继承的,因此它允许我访问CL_SALV_MODEL
的R_CONTROLLER
。 - 从对象
MODEL -> Controller -> Adapter -> Grid
获取 GRID 对象。 - 为 EDIT 设置布局并刷新 ALV。
当我们运行报告时,ALV 不会直接进入输入模式:
一旦我们按下“My Function”按钮,ALV 就会变成可编辑的 ALV。此 ALV 将具有其单独的 GUI 状态,其中包含可编辑 ALV 所需的所有按钮。
UML 图
代码片段的 UML 图:
以下是我用于从 SALV 模型获取 GRID 对象访问权限并使 ALV 可编辑的代码。在这里,我使用了报告程序 SALV_DEMO_TABLE_EVENTS
中提供的 PF-STATUS,以便轻松运行此演示报表。
*&---------------------------------------------------------------------*
*& Report ZTEST_NP_EDIT_SALV
*& Overcome the restriction of the SALV model using the power of the
*& Object Oriented ABAP
*&---------------------------------------------------------------------*
REPORT ztest_np_edit_salv.
*----------------------------------------------------------------------*
* Define the Local class inheriting from the CL_SALV_MODEL_LIST
* to get an access of the model, controller and adapter which inturn
* provides the Grid Object
*----------------------------------------------------------------------*
CLASS lcl_salv_model DEFINITION INHERITING FROM cl_salv_model_list.
PUBLIC SECTION.
DATA: o_control TYPE REF TO cl_salv_controller_model,
o_adapter TYPE REF TO cl_salv_adapter.
METHODS:
grabe_model
IMPORTING
io_model TYPE REF TO cl_salv_model,
grabe_controller,
grabe_adapter.
PRIVATE SECTION.
DATA: lo_model TYPE REF TO cl_salv_model.
ENDCLASS. "LCL_SALV_MODEL DEFINITION
*----------------------------------------------------------------------*
* Event handler for the added buttons
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS:
on_user_command FOR EVENT added_function OF cl_salv_events
IMPORTING e_salv_function.
ENDCLASS. "lcl_event_handler DEFINITION
*----------------------------------------------------------------------*
* Local Report class - Definition
*----------------------------------------------------------------------*
CLASS lcl_report DEFINITION.
PUBLIC SECTION.
TYPES: ty_t_sflights TYPE STANDARD TABLE OF sflights.
DATA: t_data TYPE ty_t_sflights.
DATA: o_salv TYPE REF TO cl_salv_table.
DATA: o_salv_model TYPE REF TO lcl_salv_model.
METHODS:
get_data,
generate_output.
ENDCLASS. "lcl_report DEFINITION
*----------------------------------------------------------------------*
* Global data
*----------------------------------------------------------------------*
DATA: lo_report TYPE REF TO lcl_report.
*----------------------------------------------------------------------*
* Start of selection
*----------------------------------------------------------------------*
START-OF-SELECTION.
CREATE OBJECT lo_report.
lo_report->get_data( ).
lo_report->generate_output( ).
*----------------------------------------------------------------------*
* Local Report class - Implementation
*----------------------------------------------------------------------*
CLASS lcl_report IMPLEMENTATION.
METHOD get_data.
* test data
SELECT * FROM sflights
INTO TABLE me->t_data
UP TO 30 ROWS.
ENDMETHOD. "get_data
METHOD generate_output.
*...New ALV Instance ...............................................
TRY.
cl_salv_table=>factory(
EXPORTING
* r_container = w_alv1
list_display = abap_false
IMPORTING
r_salv_table = o_salv
CHANGING
t_table = t_data ).
CATCH cx_salv_msg. "#EC NO_HANDLER
ENDTRY.
*...PF Status.......................................................
* Add MYFUNCTION from the report SALV_DEMO_TABLE_EVENTS
o_salv->set_screen_status(
pfstatus = 'SALV_STANDARD'
report = 'SALV_DEMO_TABLE_EVENTS'
set_functions = o_salv->c_functions_all ).
*...Event handler for the button.....................................
DATA: lo_events TYPE REF TO cl_salv_events_table,
lo_event_h TYPE REF TO lcl_event_handler.
* event object
lo_events = o_salv->get_event( ).
* event handler
CREATE OBJECT lo_event_h.
* setting up the event handler
SET HANDLER lo_event_h->on_user_command FOR lo_events.
*...Get Model Object ...............................................
DATA: lo_alv_mod TYPE REF TO cl_salv_model.
* Narrow casting
lo_alv_mod ?= o_salv.
* object for the local inherited class from the CL_SALV_MODEL_LIST
CREATE OBJECT o_salv_model.
* grabe model to use it later
CALL METHOD o_salv_model->grabe_model
EXPORTING
io_model = lo_alv_mod.
*...Generate ALV output ...............................................
o_salv->display( ).
ENDMETHOD. "generate_output
ENDCLASS. "lcl_report IMPLEMENTATION
*----------------------------------------------------------------------*
* LCL_SALV_MODEL implementation
*----------------------------------------------------------------------*
CLASS lcl_salv_model IMPLEMENTATION.
METHOD grabe_model.
* save the model
lo_model = io_model.
ENDMETHOD. "grabe_model
METHOD grabe_controller.
* save the controller
o_control = lo_model->r_controller.
ENDMETHOD. "grabe_controller
METHOD grabe_adapter.
* save the adapter from controller
o_adapter ?= lo_model->r_controller->r_adapter.
ENDMETHOD. "grabe_adapter
ENDCLASS. "LCL_SALV_MODEL IMPLEMENTATION
*----------------------------------------------------------------------*
* Event Handler for the SALV
*----------------------------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_user_command.
DATA: lo_grid TYPE REF TO cl_gui_alv_grid,
lo_full_adap TYPE REF TO cl_salv_fullscreen_adapter.
DATA: ls_layout TYPE lvc_s_layo.
CASE e_salv_function.
* Make ALV as Editable ALV
WHEN 'MYFUNCTION'.
* Contorller
CALL METHOD lo_report->o_salv_model->grabe_controller.
* Adapter
CALL METHOD lo_report->o_salv_model->grabe_adapter.
* Fullscreen Adapter (Down Casting)
lo_full_adap ?= lo_report->o_salv_model->o_adapter.
* Get the Grid
lo_grid = lo_full_adap->get_grid( ).
* Got the Grid .. ?
IF lo_grid IS BOUND.
* Editable ALV
ls_layout-edit = 'X'.
* Set the front layout of ALV
CALL METHOD lo_grid->set_frontend_layout
EXPORTING
is_layout = ls_layout.
* refresh the table
CALL METHOD lo_grid->refresh_table_display.
ENDIF.
ENDCASE.
ENDMETHOD. "on_user_command
ENDCLASS. "lcl_event_handler IMPLEMENTATION
标签:lo,模型,克服,SALV,ALV,model,MODEL,salv
From: https://blog.csdn.net/SAP_yu/article/details/143715018