欢迎来到萧静默的博客

书山有路勤为径,学海无涯苦作舟。

ABAP中的动态编程–第3部分–示例– ABAP RTTS

在以前博客中,我解释了字段符号和数据引用在动态编程中的重要性。

https://www.cnblogs.com/BruceKing/p/14628217.html

https://www.cnblogs.com/BruceKing/p/14628266.html

 

现在在这里,我们将看到一个动态编程方法的示例,以及ABAP RTTS的简要介绍。

ABAP运行时类型服务(RTTS)包含两个组件:

  • 运行时类型标识(RTTI) –提供在运行时获取数据对象的类型定义的方法。
  • 运行时类型创建(RTTC) –提供在运行时使用任何类型定义创建数据对象的方法。

基本上,ABAP RTTS提供了一组类,其类可用于运行时类型标识和运行时类型创建。要了解有关ABAP RTTS的更多信息,请点击以下链接:

https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=42965

*动态编程的一个例子:
*要求:作为ABAP开发人员,经常会遇到需要将内部表中的数据写入应用程序服务器上的文件的情况。
*解决方案:我们将构建一个类,该类具有一种方法,该方法将任何内部表作为输入并将其内容写入应用程序服务器上的文件中。
*类定义:
CLASS CL_APPSERVER_WRITER DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: WRITE IMPORTING
                           IV_FILENAME  TYPE STRING
                           IT_DATA      TYPE ANY TABLE
                           WRITE_HEADER TYPE ABAP_BOOL DEFAULT SPACE
                         EXPORTING
                           EV_MESSAGE   TYPE STRING.
ENDCLASS.
*在这里,导入参数it_data的类型为ANY TABLE,以便它可以接收任何内部表。
*类的实现:
CLASS CL_APPSERVER_WRITER IMPLEMENTATION.
  METHOD WRITE.
    TYPES: BEGIN OF TY_COMP_DETAIL,
             NAME  TYPE ABAP_COMPNAME,
             DESCR TYPE SCRTEXT_M,
           END OF TY_COMP_DETAIL.
    DATA: LO_TYPE_DEF    TYPE REF TO CL_ABAP_TYPEDESCR.
    DATA: LO_STRUCT_DEF  TYPE REF TO CL_ABAP_STRUCTDESCR.
    DATA: LO_TABLE_DEF   TYPE REF TO CL_ABAP_TABLEDESCR.
    DATA: LO_DATA_DEF    TYPE REF TO CL_ABAP_DATADESCR.
    DATA: LO_ELEMENT_DEF TYPE REF TO CL_ABAP_ELEMDESCR.
    DATA: LT_COMPONENTS  TYPE ABAP_COMPDESCR_TAB.
    DATA: WA_COMPONENTS  LIKE LINE OF LT_COMPONENTS.
    DATA: LV_STR         TYPE STRING.
    DATA: LV_FILEROW     TYPE STRING.
    DATA: LV_COUNTER     TYPE I VALUE 0.
    DATA: LW_FIELD_INFO  TYPE DFIES.
    DATA: LS_COMP_DETAIL TYPE TY_COMP_DETAIL.
    DATA: LT_COMP_DETAIL TYPE TABLE OF TY_COMP_DETAIL.

    FIELD-SYMBOLS: <ROW> TYPE ANY.
    FIELD-SYMBOLS: <FIELD_VALUE> TYPE ANY.

* Using RTTS to get the runtime type information of the internal table
    LO_TYPE_DEF  = CL_ABAP_TABLEDESCR=>DESCRIBE_BY_DATA( IT_DATA ).
    LO_TABLE_DEF ?= LO_TYPE_DEF.
    LO_DATA_DEF = LO_TABLE_DEF->GET_TABLE_LINE_TYPE( ).
    LO_STRUCT_DEF ?= LO_DATA_DEF.

* Get the components of the structure
    LT_COMPONENTS = LO_STRUCT_DEF->COMPONENTS.

    CLEAR: LO_DATA_DEF.

* If the WRITE_HEADER is ABAP_TRUE then fetch the label
* of data element associated to each component of the
* line type structure of internal table, if no data element
* is associated then use component name as the header text
    IF WRITE_HEADER EQ ABAP_TRUE.
      LOOP AT LT_COMPONENTS INTO WA_COMPONENTS.
        LO_DATA_DEF = LO_STRUCT_DEF->GET_COMPONENT_TYPE( WA_COMPONENTS-NAME ).
        LO_ELEMENT_DEF ?= LO_DATA_DEF.
        LW_FIELD_INFO = LO_ELEMENT_DEF->GET_DDIC_FIELD( ).
        LS_COMP_DETAIL-NAME = LW_FIELD_INFO-ROLLNAME.  "Get the data element name

* Calling FM to get data element text
        CALL FUNCTION 'WCGW_DATA_ELEMENT_TEXT_GET'
          EXPORTING
            I_DATA_ELEMENT = LW_FIELD_INFO-ROLLNAME
            I_LANGUAGE     = SY-LANGU
          IMPORTING
            E_SCRTEXT_M    = LS_COMP_DETAIL-DESCR
          EXCEPTIONS
            ERROR          = 1.
        IF LS_COMP_DETAIL-DESCR IS INITIAL.
          LS_COMP_DETAIL-DESCR = WA_COMPONENTS-NAME.
        ENDIF.
        APPEND LS_COMP_DETAIL TO LT_COMP_DETAIL.
        CLEAR: LS_COMP_DETAIL.
      ENDLOOP.
    ENDIF.


    OPEN DATASET IV_FILENAME FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
    IF SY-SUBRC EQ 0.
* Writing header text for each column separated by comma
      IF WRITE_HEADER EQ ABAP_TRUE.
        LOOP AT LT_COMP_DETAIL INTO LS_COMP_DETAIL.
          LV_COUNTER = LV_COUNTER + 1.
          IF LV_COUNTER EQ 1.
            LV_FILEROW = LS_COMP_DETAIL-DESCR.
          ELSE.
            CONCATENATE LV_FILEROW ',' LS_COMP_DETAIL-DESCR INTO LV_FILEROW.
          ENDIF.
        ENDLOOP.
        TRANSFER LV_FILEROW TO IV_FILENAME.
        CLEAR: LV_FILEROW, LV_COUNTER.
      ENDIF.

* Writing internal table content separated by comma
      LOOP AT IT_DATA ASSIGNING <ROW>.
        LOOP AT LT_COMPONENTS INTO WA_COMPONENTS.
          LV_COUNTER = LV_COUNTER + 1.
          ASSIGN COMPONENT WA_COMPONENTS-NAME OF STRUCTURE <ROW> TO <FIELD_VALUE>.
          IF <FIELD_VALUE> IS ASSIGNED.
            LV_STR = <FIELD_VALUE>.
            IF LV_COUNTER EQ 1.
              LV_FILEROW = LV_STR.
            ELSE.
              CONCATENATE LV_FILEROW ',' LV_STR INTO LV_FILEROW.
            ENDIF.
            UNASSIGN <FIELD_VALUE>.
          ENDIF.
        ENDLOOP.
        TRANSFER LV_FILEROW TO IV_FILENAME.
        CLEAR: LV_FILEROW, LV_COUNTER.
      ENDLOOP.
      CLOSE DATASET IV_FILENAME.
      EV_MESSAGE = 'Success'.
    ELSE.
      EV_MESSAGE = 'Failure'.
    ENDIF.
  ENDMETHOD.
ENDCLASS.
*ABAP RTTS提供了CL_ABAP_ * DESCR类,用于在运行时获取数据对象的类型定义。我们还使用RTTS类提取了内部表IT_DATA的线型结构的每个组件的数据元素名称。然后,我们使用FM WCGW_DATA_ELEMENT_TEXT_GET获取数据元素标签。如果ABAP_TRUE提供了CLASS的WRITE_HEADER参数,则此标签用于为内部表IT_DATA的每一列写标题。
*使用类–上面设计的类可以用作:

DATA: LT_DATA  TYPE STANDARD TABLE OF MARA.
DATA: LV_FILENAME TYPE STRING.
DATA: LV_MESSAGE  TYPE STRING.
SELECT * FROM MARA INTO TABLE LT_DATA UP TO 5 ROWS.
CL_APPSERVER_WRITER=>WRITE(
EXPORTING
  IV_FILENAME  = 'D:\usr\sap\testdata.csv'
  IT_DATA      = LT_DATA
  WRITE_HEADER = ABAP_TRUE
IMPORTING
  EV_MESSAGE   = LV_MESSAGE
  ).
WRITE: / LV_MESSAGE.
*在这里,我们将结构MARA的一个内部表传递给该类,随后,其内容将作为逗号分隔的值写入应用程序服务器。但是,我们可以传递任何结构的内部表。该文件也可以从应用程序服务器下载到EXCEL电子表格。
*因此,这就是字段符号,数据引用,通用数据类型,RTTS在动态编程方法中的帮助方式。

 

posted @ 2021-04-07 16:19  萧静默  阅读(1494)  评论(0编辑  收藏  举报