Bagging原理深度解析:从Bootstrap采样到鲁棒聚合
2026/10/15 14:24:21
*&---------------------------------------------------------------------* *& Report ZEXPORT_TABLE. *& *&---------------------------------------------------------------------* *& 程序功能:读取ZTMM002表全部数据并下载到本地Excel文件 *& 创建日期:2026-10-14 *&---------------------------------------------------------------------* REPORT zexport_ztmm002 MESSAGE-ID z LINE-SIZE 200 LINE-COUNT 65 NO STANDARD PAGE HEADING. *----------------------------------------------------------------------* * 注:本程序使用RTTS动态创建内表,无需预定义静态类型 * *----------------------------------------------------------------------* * 内表与工作区定义 * *----------------------------------------------------------------------* DATA: gt_data TYPE REF TO data, " 动态内表 - 存储表数据 gs_data TYPE REF TO data, " 动态工作区 gt_fieldcat TYPE lvc_t_fcat, " 字段目录 gs_fieldcat TYPE lvc_s_fcat, gt_excel TYPE STANDARD TABLE OF string, " Excel输出内容 gv_filename TYPE string, " 文件名 gv_filepath TYPE string, " 文件完整路径 gv_tabname TYPE tabname VALUE 'ZTMM002', " 表名 gv_lines TYPE i, " 数据条数 gv_msg TYPE string. " 消息文本 * 字段符号 FIELD-SYMBOLS: <fs_data> TYPE ANY TABLE, <fs_wa> TYPE any, <fs_field> TYPE any. *----------------------------------------------------------------------* * 选择屏幕定义 * *----------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001. PARAMETERS: p_tab TYPE tabname DEFAULT 'Itab' OBLIGATORY, " 表名 p_path TYPE string DEFAULT 'C:\temp\' OBLIGATORY, " 保存路径 p_fname TYPE string DEFAULT 'Export_Table.XLS' OBLIGATORY. " 文件名 SELECTION-SCREEN END OF BLOCK blk1. SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE text-002. PARAMETERS: p_max TYPE i DEFAULT 0. " 最大读取条数,0表示全部 SELECTION-SCREEN END OF BLOCK blk2. *----------------------------------------------------------------------* * 初始化文本元素(可在SE38中通过文本元素维护) * *----------------------------------------------------------------------* INITIALIZATION. *----------------------------------------------------------------------* * AT SELECTION-SCREEN * *----------------------------------------------------------------------* AT SELECTION-SCREEN. " 检查表是否存在 PERFORM check_table_exists USING p_tab. *----------------------------------------------------------------------* * START-OF-SELECTION * *----------------------------------------------------------------------* START-OF-SELECTION. gv_tabname = p_tab. " 1. 动态获取表结构并创建内表 PERform create_dynamic_table USING gv_tabname CHANGING gt_data gt_fieldcat. IF gt_data IS NOT BOUND. MESSAGE '动态创建内表失败' TYPE 'E'. ENDIF. " 2. 读取表数据 PERFORM read_table_data USING gv_tabname p_max CHANGING gt_data gv_lines. " 3. 组装Excel数据(含表头) PERFORM build_excel_data TABLES gt_fieldcat USING gt_data CHANGING gt_excel. " 4. 下载到本地Excel文件 CONCATENATE p_path p_fname INTO gv_filepath. PERFORM download_to_excel USING gv_filepath gt_excel gv_lines. *----------------------------------------------------------------------* * END-OF-SELECTION * *----------------------------------------------------------------------* END-OF-SELECTION. IF gv_lines > 0. WRITE: / '下载成功!', / '表名:', gv_tabname, / '数据条数:', gv_lines, / '保存路径:', gv_filepath. ELSE. WRITE: / '表', gv_tabname, '中无数据。'. ENDIF. *&---------------------------------------------------------------------* *& Form CHECK_TABLE_EXISTS *&---------------------------------------------------------------------* * 检查表是否存在于数据字典中 *----------------------------------------------------------------------* FORM check_table_exists USING iv_tabname TYPE tabname. DATA: lv_tabname TYPE tabname, ls_dd02l TYPE dd02l. lv_tabname = iv_tabname. TRANSLATE lv_tabname TO UPPER CASE. SELECT SINGLE tabname FROM dd02l INTO @ls_dd02l-tabname WHERE tabname = @lv_tabname AND tabclass IN ('TRANSP', 'INTTAB', 'CLUSTER', 'POOL'). IF sy-subrc <> 0. MESSAGE e001(00) WITH '表' lv_tabname '不存在,请检查表名。'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form CREATE_DYNAMIC_TABLE *&---------------------------------------------------------------------* * 根据表名动态创建内表及字段目录 *----------------------------------------------------------------------* FORM create_dynamic_table USING iv_tabname TYPE tabname CHANGING eo_data TYPE REF TO data ct_fieldcat TYPE lvc_t_fcat. DATA: lo_struct_descr TYPE REF TO cl_abap_structdescr, lo_table_descr TYPE REF TO cl_abap_tabledescr, lo_data_descr TYPE REF TO cl_abap_datadescr, lt_dfies TYPE STANDARD TABLE OF dfies, ls_dfies TYPE dfies, lv_tabname TYPE tabname. " 表名转大写 lv_tabname = iv_tabname. TRANSLATE lv_tabname TO UPPER CASE. " 获取表字段信息 CALL FUNCTION 'DDIF_FIELDINFO_GET' EXPORTING tabname = lv_tabname langu = sy-langu TABLES dfies_tab = lt_dfies EXCEPTIONS not_found = 1 internal_error = 2 OTHERS = 3. IF sy-subrc <> 0 OR lt_dfies IS INITIAL. MESSAGE '获取表字段信息失败' TYPE 'E'. ENDIF. " 构建字段目录并创建动态结构 LOOP AT lt_dfies INTO ls_dfies WHERE fieldname <> '.INCLUDE'. " ALV字段目录 CLEAR gs_fieldcat. gs_fieldcat-fieldname = ls_dfies-fieldname. gs_fieldcat-scrtext_l = ls_dfies-fieldtext. gs_fieldcat-inttype = ls_dfies-inttype. gs_fieldcat-intlen = ls_dfies-intlen. gs_fieldcat-decimals = ls_dfies-decimals. APPEND gs_fieldcat TO ct_fieldcat. ENDLOOP. " 通过RTTS创建动态内表 lo_struct_descr ?= cl_abap_typedescr=>describe_by_name( lv_tabname ). lo_table_descr = cl_abap_tabledescr=>create( p_line_type = lo_struct_descr p_table_kind = cl_abap_tabledescr=>tablekind_std p_unique = abap_false ). " 创建数据对象 CREATE DATA eo_data TYPE HANDLE lo_table_descr. ENDFORM. *&---------------------------------------------------------------------* *& Form READ_TABLE_DATA *&---------------------------------------------------------------------* * 读取表数据到动态内表 *----------------------------------------------------------------------* FORM read_table_data USING iv_tabname TYPE tabname iv_max TYPE i CHANGING io_data TYPE REF TO data ev_lines TYPE i. DATA: lv_tabname TYPE tabname, lv_max TYPE i. FIELD-SYMBOLS: <ft_data> TYPE STANDARD TABLE. lv_tabname = iv_tabname. TRANSLATE lv_tabname TO UPPER CASE. " 分配内表到字段符号 ASSIGN io_data->* TO <ft_data>. " 读取数据 IF iv_max > 0. " 有限条数 SELECT * FROM (lv_tabname) INTO TABLE @<ft_data> UP TO @iv_max ROWS. ELSE. " 全部数据 SELECT * FROM (lv_tabname) INTO TABLE @<ft_data>. ENDIF. ev_lines = lines( <ft_data> ). ENDFORM. *&---------------------------------------------------------------------* *& Form BUILD_EXCEL_DATA *&---------------------------------------------------------------------* * 组装Excel数据,第一行为表头(字段描述) *----------------------------------------------------------------------* FORM build_excel_data TABLES it_fieldcat TYPE lvc_t_fcat USING io_data TYPE REF TO data CHANGING ct_excel TYPE STANDARD TABLE. DATA: ls_fieldcat TYPE lvc_s_fcat, lv_line TYPE string, lv_value TYPE string, lv_header TYPE string. FIELD-SYMBOLS: <ft_data> TYPE STANDARD TABLE, <fs_wa> TYPE any, <fv_val> TYPE any. " 清空输出表 REFRESH ct_excel. " 分配内表 ASSIGN io_data->* TO <ft_data>. " ===== 第一行:表头(字段描述) ===== CLEAR lv_header. LOOP AT it_fieldcat INTO ls_fieldcat. IF lv_header IS INITIAL. lv_header = ls_fieldcat-scrtext_l. ELSE. CONCATENATE lv_header ls_fieldcat-scrtext_l INTO lv_header SEPARATED BY cl_abap_char_utilities=>horizontal_tab. ENDIF. ENDLOOP. APPEND lv_header TO ct_excel. " ===== 数据行 ===== LOOP AT <ft_data> ASSIGNING <fs_wa>. CLEAR lv_line. LOOP AT it_fieldcat INTO ls_fieldcat. " 获取字段值 ASSIGN COMPONENT ls_fieldcat-fieldname OF STRUCTURE <fs_wa> TO <fv_val>. IF <fv_val> IS ASSIGNED. lv_value = <fv_val>. ELSE. CLEAR lv_value. ENDIF. " 拼接,使用Tab分隔 IF lv_line IS INITIAL. lv_line = lv_value. ELSE. CONCATENATE lv_line lv_value INTO lv_line SEPARATED BY cl_abap_char_utilities=>horizontal_tab. ENDIF. ENDLOOP. APPEND lv_line TO ct_excel. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form DOWNLOAD_TO_EXCEL *&---------------------------------------------------------------------* * 下载数据到本地Excel文件 *----------------------------------------------------------------------* FORM download_to_excel USING iv_filepath TYPE string it_data TYPE STANDARD TABLE iv_lines TYPE i. DATA: lv_filename TYPE string, lv_path TYPE string, lv_fullpath TYPE string, lv_action TYPE i. " 调用文件保存对话框(可选,如需固定路径可注释此段) * CALL METHOD cl_gui_frontend_services=>file_save_dialog * EXPORTING * default_extension = 'XLS' * default_file_name = 'ZTMM002.XLS' * file_filter = 'Excel文件 (*.XLS)|*.XLS|所有文件 (*.*)|*.*|' * CHANGING * filename = lv_filename * path = lv_path * fullpath = lv_fullpath * user_action = lv_action * EXCEPTIONS * cntl_error = 1 * error_no_gui = 2 * not_supported_by_gui = 3 * OTHERS = 4. * * IF lv_action <> 0. * MESSAGE '用户取消下载' TYPE 'I'. * LEAVE PROGRAM. * ENDIF. " 直接调用GUI_DOWNLOAD函数下载(Tab分隔,Excel可直接打开) CALL FUNCTION 'GUI_DOWNLOAD' EXPORTING filename = iv_filepath filetype = 'DAT' write_field_separator = 'X' TABLES data_tab = it_data EXCEPTIONS file_write_error = 1 no_batch = 2 gui_refuse_filetransfer = 3 invalid_type = 4 no_authority = 5 unknown_error = 6 header_not_allowed = 7 separator_not_allowed = 8 filesize_not_allowed = 9 header_too_long = 10 dp_error_create = 11 dp_error_send = 12 dp_error_write = 13 unknown_dp_error = 14 access_denied = 15 dp_out_of_memory = 16 disk_full = 17 dp_timeout = 18 file_not_found = 19 dataprovider_exception = 20 control_flush_error = 21 OTHERS = 22. IF sy-subrc <> 0. MESSAGE '文件下载失败,错误码:' && sy-subrc TYPE 'E'. ENDIF. ENDFORM.