如何在ABAP随机数据生成程序中显示表列数据类型(附字段名)
问题
我是ABAP初学者,写了一段生成随机数据的程序(代码如下),希望在输出结果的表列中,把数据类型显示在字段名旁边,比如First_Name (CHAR)、ID (CHAR)。请告诉我如何修改程序并附上解释,谢谢。
原代码:
Report Z_THIRD_REPORT. PARAMETERS: p_table TYPE string OBLIGATORY, p_num TYPE i DEFAULT 1. DATA: ls_dd02l TYPE dd02l, lv_message TYPE string. START-OF-SELECTION. SELECT SINGLE tabname FROM dd02l WHERE tabname = @p_table INTO @DATA(lv_thrash). IF sy-subrc NE 0. MESSAGE 'Don`t have table!' TYPE 'E'. ENDIF. DATA(lt_component) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( p_table ) )->get_components( ). DATA(tabletype) = cl_abap_tabledescr=>create( p_line_type = cl_abap_structdescr=>create( p_components = lt_component ) ). DATA lot TYPE REF TO data. CREATE DATA lot TYPE HANDLE tabletype . FIELD-SYMBOLS: <ft> TYPE STANDARD TABLE. ASSIGN lot->* TO <ft>. DATA lv_max TYPE i. DATA lv_ret TYPE string. DO p_num TIMES. APPEND INITIAL LINE TO <ft> ASSIGNING FIELD-SYMBOL(<ls>). LOOP AT lt_component ASSIGNING FIELD-SYMBOL(<ls_comp>). ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls> TO FIELD-SYMBOL(<fv>). DATA(lv_type) = <ls_comp>-type->get_relative_name( ). DATA(lv_length) = <ls_comp>-type->length / 2. CASE <ls_comp>-type->type_kind. WHEN 'C'. CLEAR lv_ret. CALL FUNCTION 'GENERAL_GET_RANDOM_STRING' EXPORTING number_chars = lv_length IMPORTING random_string = lv_ret. <fv> = lv_ret. WHEN 'D' . "暂未实现日期类型随机生成" WHEN 'T' OR 'N' OR 'I'. CLEAR lv_max. DO lv_length TIMES. lv_max = |{ lv_max }9|. ENDDO. DATA(lo_rand) = cl_abap_random_int=>create( EXPORTING seed = conv #( sy-timlo ) min = 0 max = lv_max ). WAIT UP TO '1' SECONDS. <fv> = lo_rand->get_next( ). FREE lo_rand. WHEN 'P'. "暂未实现打包类型随机生成" ENDCASE. ENDLOOP. ENDDO. cl_demo_output=>write_data( <ft> ). cl_demo_output=>display( ). MODIFY (p_table) FROM TABLE <ft>. COMMIT WORK AND WAIT.
解决方案
要实现表头显示字段名(类型)的效果,核心是修改用于输出的内表的结构体字段名称,将原字段名与数据类型拼接后作为新的显示名称,同时保留字段的技术属性(类型、长度等)不影响数据生成和后续的数据库修改操作。
修改步骤及解释
复制原组件列表并修改显示名称
原lt_component保存了表的原始字段属性,我们需要复制一份新的组件列表,将每个组件的name属性修改为原字段名(类型描述)的格式。这样既不影响后续对原始表的MODIFY操作,又能让输出表头显示带类型的名称。
添加代码:"复制原始组件列表,用于生成带类型名称的输出内表 DATA(lt_component_display) = lt_component. LOOP AT lt_component_display ASSIGNING FIELD-SYMBOL(<ls_comp_display>). "拼接字段名和类型名称,比如将'FIRST_NAME'改为'FIRST_NAME(CHAR)' <ls_comp_display>-name = |{ <ls_comp_display>-name }({ <ls_comp_display>-type->get_relative_name( ) })|. ENDLOOP.使用修改后的组件创建内表类型
原代码中是直接用lt_component创建内表类型,现在改为用修改后的lt_component_display创建用于输出的内表类型,而原始的lt_component仍用于后续数据生成时的字段赋值(因为数据库表的字段名还是原始名称)。
修改原内表类型创建代码:DATA(tabletype) = cl_abap_tabledescr=>create( p_line_type = cl_abap_structdescr=>create( p_components = lt_component_display ) "替换为修改后的组件列表 ).
完整修改后的代码
Report Z_THIRD_REPORT. PARAMETERS: p_table TYPE string OBLIGATORY, p_num TYPE i DEFAULT 1. DATA: ls_dd02l TYPE dd02l, lv_message TYPE string. START-OF-SELECTION. SELECT SINGLE tabname FROM dd02l WHERE tabname = @p_table INTO @DATA(lv_thrash). IF sy-subrc NE 0. MESSAGE 'Don`t have table!' TYPE 'E'. ENDIF. DATA(lt_component) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( p_table ) )->get_components( ). "===== 修改部分开始 ===== "复制原始组件列表,用于生成带类型名称的输出内表 DATA(lt_component_display) = lt_component. LOOP AT lt_component_display ASSIGNING FIELD-SYMBOL(<ls_comp_display>). "拼接字段名和类型名称,比如将'FIRST_NAME'改为'FIRST_NAME(CHAR)' <ls_comp_display>-name = |{ <ls_comp_display>-name }({ <ls_comp_display>-type->get_relative_name( ) })|. ENDLOOP. "===== 修改部分结束 ===== DATA(tabletype) = cl_abap_tabledescr=>create( p_line_type = cl_abap_structdescr=>create( p_components = lt_component_display ) "替换为修改后的组件列表 ). DATA lot TYPE REF TO data. CREATE DATA lot TYPE HANDLE tabletype . FIELD-SYMBOLS: <ft> TYPE STANDARD TABLE. ASSIGN lot->* TO <ft>. DATA lv_max TYPE i. DATA lv_ret TYPE string. DO p_num TIMES. APPEND INITIAL LINE TO <ft> ASSIGNING FIELD-SYMBOL(<ls>). LOOP AT lt_component ASSIGNING FIELD-SYMBOL(<ls_comp>). ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls> TO FIELD-SYMBOL(<fv>). DATA(lv_type) = <ls_comp>-type->get_relative_name( ). DATA(lv_length) = <ls_comp>-type->length / 2. CASE <ls_comp>-type->type_kind. WHEN 'C'. CLEAR lv_ret. CALL FUNCTION 'GENERAL_GET_RANDOM_STRING' EXPORTING number_chars = lv_length IMPORTING random_string = lv_ret. <fv> = lv_ret. WHEN 'D' . "暂未实现日期类型随机生成" WHEN 'T' OR 'N' OR 'I'. CLEAR lv_max. DO lv_length TIMES. lv_max = |{ lv_max }9|. ENDDO. DATA(lo_rand) = cl_abap_random_int=>create( EXPORTING seed = conv #( sy-timlo ) min = 0 max = lv_max ). WAIT UP TO '1' SECONDS. <fv> = lo_rand->get_next( ). FREE lo_rand. WHEN 'P'. "暂未实现打包类型随机生成" ENDCASE. ENDLOOP. ENDDO. cl_demo_output=>write_data( <ft> ). cl_demo_output=>display( ). MODIFY (p_table) FROM TABLE <ft>. COMMIT WORK AND WAIT.
关键说明
- 为什么要复制组件列表:因为后续
MODIFY数据库表时,需要使用原始字段名,不能直接修改lt_component的名称,否则会导致字段匹配失败。 get_relative_name()方法:用于获取数据类型的可读名称(比如CHAR、NUMC等),如果需要更简洁的类型标识(比如用C代替CHAR),可以改用type_kind属性(对应CASE语句中的'C'、'D'等),修改拼接逻辑为|{ <ls_comp_display>-name }({ <ls_comp_display>-type_kind })|即可。
内容的提问来源于stack exchange,提问作者Mahmood Hammood
相关产品推荐
相关产品推荐

