前言:SAP ABAP 面向对象编程:如何实现选择屏幕和ALV结果在同一个屏幕上显示。 🦙(工作遇到傻逼,千万要远离。道路千万条,远离傻逼第一条)
选择屏幕:
执行结果:
代码如下:
REPORT zmatinal.
*———————————————————————-*
* Local class for report
*———————————————————————-*
CLASS LCL_REPORT DEFINITION.
PUBLIC SECTION.
"声明数据和方法
DATA: T_DATA TYPE STANDARD TABLE OF SFLIGHT, " 输出数据
R_CARRID TYPE RANGE OF SFLIGHT-CARRID. " 选择选项
METHODS:
GET_DATA, " 获取数据方法
GENERATE_OUTPUT. " 生成输出方法
ENDCLASS. "lcl_report DEFINITION
DATA: LO_REPORT TYPE REF TO LCL_REPORT.
DATA: W_CARRID TYPE SFLIGHT-CARRID.
** Selection Screen
*选择屏幕
SELECTION-SCREEN: BEGIN OF BLOCK BLK1 WITH FRAME TITLE AAA.
SELECT-OPTIONS: S_CARRID FOR W_CARRID. " 选择航空公司代码
SELECTION-SCREEN: END OF BLOCK BLK1.
** Initialization
*初始化
INITIALIZATION.
"设置选择屏幕标题
AAA = '选择屏幕'.
"创建报告对象
CREATE OBJECT LO_REPORT.
"生成输出
LO_REPORT->GENERATE_OUTPUT( ).
** Start of Selection
*开始选择 (公众号:matinal)
START-OF-SELECTION.
"获取数据
LO_REPORT->R_CARRID = S_CARRID[].
LO_REPORT->GET_DATA( ).
*———————————————————————-*
* Local Class Implementation
*———————————————————————-*
CLASS LCL_REPORT IMPLEMENTATION.
METHOD GET_DATA.
"从SFLIGHT表中选择数据
SELECT * FROM SFLIGHT
INTO TABLE ME->T_DATA
WHERE CARRID IN S_CARRID.
"检查是否有数据
IF SY-DBCNT IS INITIAL.
MESSAGE S398(00) WITH '没有您要查询的数据'.
ENDIF.
"将数据导出到内存
EXPORT DATA = ME->T_DATA TO MEMORY ID SY-CPROG.
ENDMETHOD. "get_data
METHOD GENERATE_OUTPUT.
"声明变量和对象
DATA: LO_DOCK TYPE REF TO CL_GUI_DOCKING_CONTAINER,
LO_CONT TYPE REF TO CL_GUI_CONTAINER,
LT_FCAT TYPE LVC_T_FCAT,
GR_GRID_D1001 TYPE REF TO CL_GUI_ALV_GRID.
"从内存导入数据
IMPORT DATA = ME->T_DATA FROM MEMORY ID SY-CPROG.
"释放内存
FREE MEMORY ID SY-CPROG.
"检查数据是否非空
CHECK ME->T_DATA IS NOT INITIAL.
"检查Docking容器是否为空
CHECK LO_DOCK IS INITIAL.
"创建Docking容器
CREATE OBJECT LO_DOCK
EXPORTING
REPID = SY-CPROG
DYNNR = SY-DYNNR
RATIO = 80
SIDE = CL_GUI_DOCKING_CONTAINER=>DOCK_AT_BOTTOM
NAME = 'DOCK_CONT'.
"检查创建是否成功
IF SY-SUBRC <> 0.
MESSAGE 'Error in the Docking control' TYPE 'S'.
ENDIF.
"获取Docking容器对象
LO_CONT ?= LO_DOCK.
"创建ALV网格对象
CREATE OBJECT GR_GRID_D1001
EXPORTING
I_PARENT = LO_CONT.
"合并字段目录
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
I_BUFFER_ACTIVE = SPACE
I_STRUCTURE_NAME = 'SFLIGHT'
I_CLIENT_NEVER_DISPLAY = 'X'
I_BYPASSING_BUFFER = SPACE
CHANGING
CT_FIELDCAT = LT_FCAT
EXCEPTIONS
INCONSISTENT_INTERFACE = 1
PROGRAM_ERROR = 2
OTHERS = 3.
"设置ALV网格的表格和字段目录
CALL METHOD GR_GRID_D1001->SET_TABLE_FOR_FIRST_DISPLAY
EXPORTING
I_BUFFER_ACTIVE = SPACE
I_BYPASSING_BUFFER = SPACE
CHANGING
IT_OUTTAB = ME->T_DATA
IT_FIELDCATALOG = LT_FCAT.
ENDMETHOD. "generate_output
ENDCLASS. "lcl_report IMPLEMENTATION
以下为程序说明:
这段ABAP代码用于从SAP系统中的SFLIGHT表中检索数据,并以ALV(ABAP List Viewer)网格的形式展示出来。下面是对程序各部分的详细解释:
1. **报告定义(Report Definition)**:
- `LCL_REPORT` 是一个局部类(Local Class),用于定义报告的数据结构和方法。
2. **数据和方法声明(Data and Methods Declaration)**:
- `T_DATA` 是一个标准表(Standard Table),用于存储从SFLIGHT表中检索到的数据。
- `R_CARRID` 是一个范围(Range)类型,用于存储用户在选择屏幕上选择的航空公司代码。
- `GET_DATA` 和 `GENERATE_OUTPUT` 是两个方法,分别用于获取数据和生成输出。
3. **选择屏幕(Selection Screen)**:
- 用户可以通过选择屏幕选择一个或多个航空公司代码(`S_CARRID`),这些代码将用于过滤SFLIGHT表中的数据。
4. **初始化(Initialization)**:
- 设置选择屏幕的标题。
- 创建报告对象(`LO_REPORT`)。
- 调用`GENERATE_OUTPUT`方法来生成输出。
5. **选择开始(Start of Selection)**:
- 将用户选择的航空公司代码赋值给`R_CARRID`。
- 调用`GET_DATA`方法来获取数据。
6. **局部类实现(Local Class Implementation)**:
- `GET_DATA` 方法:
- 从SFLIGHT表中选择数据,条件是`CARRID`字段在用户选择的范围内。
- 如果没有数据,显示消息提示用户。
- 将数据导出到内存,以便后续使用。
- `GENERATE_OUTPUT` 方法:
- 创建一个Docking容器(`LO_DOCK`)和一个ALV网格(`GR_GRID_D1001`)。
- 从内存导入数据到ALV网格。
- 合并字段目录(Field Catalog),这通常用于定义ALV网格中显示的列。
- 设置ALV网格的表格和字段目录,以便正确显示数据。
7. **ALV网格设置**:
- 使用`LVC_FIELDCATALOG_MERGE`函数来合并字段目录,这允许你自定义ALV网格的显示方式。
- 使用`SET_TABLE_FOR_FIRST_DISPLAY`方法来设置ALV网格的表格和字段目录。
这个报表程序允许用户通过选择屏幕选择航空公司,然后程序会检索相应的航班数据,并以表格形式展示出来。这种类型的报告在SAP系统中非常常见,用于数据的查询和展示。
在这段ABAP代码中,采用了面向对象(OO)的编程技术,其概念主要体现在以下几个方面:
1. **类定义(Class Definition)**:
- `CLASS LCL_REPORT DEFINITION.`:这行代码定义了一个名为`LCL_REPORT`的局部类。在SAP ABAP中,类是面向对象编程的基础,它封装了数据(属性)和操作这些数据的方法。
2. **数据成员(Data Members)**:
- `DATA: T_DATA TYPE STANDARD TABLE OF SFLIGHT,`:声明了一个名为`T_DATA`的数据成员,它是一个标准表,用于存储`SFLIGHT`表的数据。这个数据成员是类的私有成员,只能在类的内部访问和修改。
- `DATA: R_CARRID TYPE RANGE OF SFLIGHT-CARRID.`:声明了一个名为`R_CARRID`的数据成员,它是一个范围类型,用于存储用户选择的航空公司代码。这个数据成员在类的方法中被用作输入参数。
3. **方法定义(Method Definition)**:
- `METHODS: GET_DATA,` 和 `GENERATE_OUTPUT.`:在类定义中声明了两个方法。方法类似于类的函数,它们可以访问和修改类的私有数据成员。
4. **方法实现(Method Implementation)**:
- `METHOD GET_DATA.`:这是`GET_DATA`方法的实现。它从数据库中检索数据,并将其存储在类的私有数据成员`T_DATA`中。这个方法展示了如何使用类的方法来封装业务逻辑。
- `METHOD GENERATE_OUTPUT.`:这是`GENERATE_OUTPUT`方法的实现。它负责将数据从内存导入到ALV网格,并设置网格的显示属性。这个方法展示了如何使用类的方法来处理数据的输出。
5. **对象创建(Object Creation)**:
- `CREATE OBJECT LO_REPORT.`:在程序的初始化部分,创建了一个名为`LO_REPORT`的对象,它是`LCL_REPORT`类的实例。这个对象将用于执行类的方法。
6. **方法调用(Method Invocation)**:
- `LO_REPORT->GET_DATA( ).` 和 `LO_REPORT->GENERATE_OUTPUT( ).`:这两行代码展示了如何通过对象调用类的方法。在面向对象编程中,对象是类的实例,它包含了类定义的数据成员和方法。通过对象调用方法,可以执行封装在类中的功能。
7. **数据封装(Data Encapsulation)**:
- 类的私有数据成员(如`T_DATA`和`R_CARRID`)只能在类的内部被访问和修改。这种封装性是面向对象编程的一个重要特性,它有助于隐藏内部实现细节,使得代码更加模块化和易于维护。
8. **多态性(Polymorphism)**:
- 在这段代码中,虽然没有直接展示多态性,但在面向对象编程中,多态性允许不同的对象对同一消息(方法调用)做出不同的响应。在SAP ABAP中,这通常通过继承和接口实现。
总结来说,这段ABAP代码通过类的定义、数据成员的声明、方法的实现以及对象的创建和使用,体现了面向对象编程的核心概念。这些概念使得程序更加结构化、易于理解和维护。
怎么样,在了解此篇文章有何感想?