参考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 c 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