abap 动态内表,附例子

来源:互联网 发布:淘宝寄生虫 编辑:程序博客网 时间:2024/04/30 12:02

参考http://www.cnblogs.com/panjun-Donet/archive/2011/01/04/1925885.html

 

在一些配置表操作中,可以根据用户的选择的表名,做不同的操作。这里只做显示的演示,即根据用户在选择屏幕上输入的表名,来用alv或write显示表的内容。

下面的例子是用oo显示如果,也可以修改代码 PERFORM write_out. 将write输出的这部分代码的注释回来,再注释掉 cal screen 100. 就可以直接在你的机器上运行而不用创建屏幕100了。

 

 

代码如下:

TYPE-POOLS : abap.
FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
               <dyn_wa>,
               <dyn_field>.
DATA: dy_table TYPE REF TO data,
      dy_line TYPE REF TO data.

*oo alv show
DATA:
  g_container_100    TYPE scrfname VALUE 'ALV_CONT',           "容器的名称
  grid_100           TYPE REF TO cl_gui_alv_grid,              "用来画ALV的网格
  g_custom_container TYPE REF TO cl_gui_custom_container,      "屏幕的一个容器
  xfc                TYPE lvc_s_fcat,
  ifc                TYPE lvc_t_fcat,                          "alv fieldcat
  ih_layout          type lvc_s_layo
.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS: p_table(30) TYPE DEFAULT 'YZGZ_DB_001'.
SELECTION-SCREEN END OF BLOCK b1.

START-OF-SELECTION.
  PERFORM get_structure1.
*  PERFORM get_structure2.
*  PERFORM get_structure3.
  PERFORM create_dynamic_itab.
  PERFORM get_data.
  PERFORM write_out.


*---------------------------------------------------------------------*
*       FORM get_structure                                            *
*方法一、
*这种方法是如果某个字段没有创建DE,则这个字段的描述是不可带出的
*---------------------------------------------------------------------*
FORM get_structure1.

  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name = p_table
    CHANGING
      ct_fieldcat      = ifc.

ENDFORM.                    "get_structure

*&---------------------------------------------------------------------*
*&      Form  GET_STRUCTURE2
*&---------------------------------------------------------------------*
*方法二、
*这种方法是调用cl_abap_typedescr类的static方法,缺点是没有描述
*----------------------------------------------------------------------*
FORM get_structure2 .
  DATA : idetails TYPE abap_compdescr_tab,
         xdetails TYPE abap_compdescr.
  DATA : ref_table_des TYPE REF TO cl_abap_structdescr.

  ref_table_des ?=
          cl_abap_typedescr=>describe_by_name( p_table ).
  idetails[] = ref_table_des->components[].

  LOOP AT idetails INTO xdetails.
    CLEAR xfc.
    xfc-fieldname = xdetails-name .
*    xfc-datatype = xdetails-type_kind.
    xfc-inttype = xdetails-type_kind.
    xfc-intlen = xdetails-length + xdetails-decimals.
    xfc-decimals = xdetails-decimals.
    APPEND xfc TO ifc.
  ENDLOOP.
ENDFORM.                    " GET_STRUCTURE2

*&---------------------------------------------------------------------*
*&      Form  GET_STRUCTURE3
*&---------------------------------------------------------------------*
* 方法三、
*此方法是通过读取,sap三张表类取fieldcat,优点是即使某个字段没有DE,
*也能带出描述
*----------------------------------------------------------------------*
FORM get_structure3 .

  DATA:idd03l LIKE TABLE OF dd03l WITH HEADER LINE,
     idd04t LIKE TABLE OF dd04t WITH HEADER LINE,
     idd03t LIKE TABLE OF dd03t WITH HEADER LINE.

  SELECT *
      INTO CORRESPONDING FIELDS OF TABLE idd03l
      FROM dd03l
     WHERE tabname =  p_table ."'ZTMT110'.
* 查找所有的有DE的field
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE
    idd04t
    FROM dd04t FOR ALL ENTRIES IN idd03l
   WHERE ddlanguage = sy-langu
     AND rollname = idd03l-rollname
     AND as4local = 'A'.

* 查找所有没有DE的field
  SELECT *
  INTO CORRESPONDING FIELDS OF TABLE idd03t
  FROM dd03t FOR ALL ENTRIES IN idd03l
 WHERE ddlanguage = sy-langu
   AND tabname = idd03l-tabname
   AND as4local = 'A'.
*     AND ddtext <> ''."这里可以去掉,因为如果这个字段没有维护描述,就找不到这个字段

  SORT idd04t[] BY rollname .
  SORT idd04t[] BY rollname .
  SORT idd03t[] BY fieldname.

  LOOP AT idd03l.
    CLEAR xfc.
    IF idd03l-fieldname = 'MANDT'.
      CONTINUE.
    ENDIF.

    xfc-fieldname = idd03l-fieldname.
    xfc-datatype = idd03l-datatype.
*      xfc-inttype   = idd03l-inttype.
    xfc-intlen    = idd03l-leng + idd03l-decimals.
    xfc-decimals  = idd03l-decimals.
    IF idd03l-rollname <> ''.
      READ TABLE idd04t WITH KEY rollname = idd03l-rollname BINARY SEARCH.
      xfc-coltext = idd04t-ddtext.
    ELSE.
      READ TABLE idd03t WITH KEY fieldname = idd03l-fieldname BINARY SEARCH.
      xfc-coltext = idd03t-ddtext.
    ENDIF.
    APPEND xfc TO ifc.
  ENDLOOP.
ENDFORM.                    " GET_STRUCTURE3

*---------------------------------------------------------------------*
*       FORM create_dynamic_itab                                      *
*---------------------------------------------------------------------*
FORM create_dynamic_itab.

  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = ifc
    IMPORTING
      ep_table        = dy_table.
  ASSIGN dy_table->* TO <dyn_table>.

  CREATE DATA dy_line LIKE LINE OF <dyn_table>.
  ASSIGN dy_line->* TO <dyn_wa>.
ENDFORM.                    "create_dynamic_itab

*---------------------------------------------------------------------*
*       FORM get_data                                                 *
*---------------------------------------------------------------------*
FORM get_data.
  DATA:
      ex TYPE REF TO cx_root,
      err_text TYPE string.
*捕获异常,若上面是用xfc-inttype   = idd03l-inttype 则能捕获到异常
  TRY.
      SELECT INTO CORRESPONDING FIELDS OF TABLE <dyn_table>
                   FROM (p_table).
    CATCH cx_root INTO ex.
      err_text = ex->get_text( ).
      WRITE / err_text.
  ENDTRY.
ENDFORM.                    "get_data
*---------------------------------------------------------------------*
*       FORM write_out                                                *
*---------------------------------------------------------------------*
FORM write_out.
*  LOOP AT <dyn_table> INTO <dyn_wa>.
*    DO.
*      ASSIGN COMPONENT sy-index
*         OF STRUCTURE <dyn_wa> TO <dyn_field>.
*      IF sy-subrc <> 0.
*        EXIT.
*      ENDIF.
*      IF sy-index = 1.
*        WRITE:/ <dyn_field>.
*      ELSE.
*        WRITE: <dyn_field>.
*      ENDIF.
*    ENDDO.
*  ENDLOOP.
*  alv show
  CALL SCREEN 100.
ENDFORM.                    "write_out
*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'YZGZ_031'.
*  SET TITLEBAR 'xxx'.
  IF g_custom_container IS INITIAL.
    CREATE OBJECT g_custom_container "创建容器
      EXPORTING
        container_name = g_container_100.

    CREATE OBJECT grid_100           "创建ALV
      EXPORTING
        i_parent = g_custom_container.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

*--设置layout
    ih_layout-edit = 'X'.       "选择了这个ALV旁边的box选择可以用了
    ih_layout-cwidth_opt = 'X'"优化列宽度

*-------------------ALV显示---------------------------------------------*
    CALL METHOD grid_100->set_table_for_first_display
      EXPORTING
        is_layout                     = ih_layout
      CHANGING
        it_outtab                     = <dyn_table>
        it_fieldcatalog               = ifc
      EXCEPTIONS
        invalid_parameter_combination = 1
        program_error                 = 2
        too_many_lines                = 3
        OTHERS                        4.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDIF.
ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE sy-ucomm.
    WHEN 'BACK' OR 'EXIT' OR 'CANCL'.LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100  INPUT

 

 

原创粉丝点击