sap abap 批量导出表结构字段

REPORT ztable_field_export.

*&---------------------------------------------------------------------*

*& 选择屏幕定义

*&---------------------------------------------------------------------*

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.

PARAMETERS: p_file TYPE rlgrap-filename OBLIGATORY DEFAULT 'C:\temp\table_fields.xlsx'.

SELECTION-SCREEN END OF BLOCK b1.

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.

PARAMETERS: p_hdr TYPE c AS CHECKBOX DEFAULT 'X' USER-COMMAND hdr.

SELECTION-SCREEN END OF BLOCK b2.

SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE TEXT-003.

SELECT-OPTIONS: s_table FOR dd02l-tabname.

SELECTION-SCREEN END OF BLOCK b3.

*&---------------------------------------------------------------------*

*& 类型定义

*&---------------------------------------------------------------------*

TYPES: BEGIN OF ty_table_info,

tabname TYPE dd02l-tabname,

ddtext TYPE dd02t-ddtext,

contflag TYPE dd02l-contflag,

END OF ty_table_info.

TYPES: BEGIN OF ty_field_info,

tabname TYPE dd03l-tabname,

fieldname TYPE dd03l-fieldname,

position TYPE dd03l-position,

keyflag TYPE dd03l-keyflag,

rollname TYPE dd03l-rollname,

datatype TYPE dd03l-datatype,

leng TYPE dd03l-leng,

decimals TYPE dd03l-decimals,

ddtext TYPE dd04t-ddtext,

reftable TYPE dd03l-reftable,

reffield TYPE dd03l-reffield,

END OF ty_field_info.

*&---------------------------------------------------------------------*

*& 数据声明

*&---------------------------------------------------------------------*

DATA: gt_tables TYPE TABLE OF ty_table_info,

gs_table TYPE ty_table_info,

gt_fields TYPE TABLE OF ty_field_info,

gs_field TYPE ty_field_info.

DATA: go_excel TYPE ole2_object,

go_workbook TYPE ole2_object,

go_worksheets TYPE ole2_object,

go_worksheet TYPE ole2_object,

go_range TYPE ole2_object,

go_cells TYPE ole2_object,

go_hyperlink TYPE ole2_object.

DATA: gv_row TYPE i,

gv_col TYPE i,

gv_sheet_no TYPE i,

gv_filename TYPE string.

DATA: lv_field_count TYPE i,

lv_sheet_name TYPE string,

lv_link TYPE string,

lv_row_str TYPE string,

lv_col_str TYPE string,

lv_error TYPE string,

lv_fullpath TYPE string,

lv_sheet_count TYPE i,

lv_index TYPE i,

lv_col_char TYPE char2,

lv_first TYPE c,

lv_value TYPE string.

DATA: lt_ddtext TYPE TABLE OF dd02t,

ls_ddtext TYPE dd02t.

DATA: lx_error TYPE REF TO cx_root.

*&---------------------------------------------------------------------*

*& 初始化

*&---------------------------------------------------------------------*

INITIALIZATION.

TEXT-001 = '文件设置'.

TEXT-002 = '导出选项'.

TEXT-003 = '选择表名'.

*&---------------------------------------------------------------------*

*& 主程序

*&---------------------------------------------------------------------*

START-OF-SELECTION.

PERFORM get_table_data.

PERFORM create_excel_file.

PERFORM write_table_list_sheet.

PERFORM write_field_sheets.

PERFORM save_excel_file.

*&---------------------------------------------------------------------*

*& 获取表数据

*&---------------------------------------------------------------------*

FORM get_table_data.

CLEAR: gt_tables, gt_fields.

" 获取表信息

IF s_table[] IS NOT INITIAL.

SELECT a~tabname

a~contflag

b~ddtext

FROM dd02l AS a

LEFT JOIN dd02t AS b

ON a~tabname = b~tabname

AND a~as4local = b~as4local

AND a~as4vers = b~as4vers

AND b~ddlanguage = sy-langu

INTO TABLE gt_tables

WHERE a~tabname IN s_table

AND a~as4local = 'A'

AND a~as4vers = '0000'.

IF gt_tables IS INITIAL.

MESSAGE '没有找到符合条件的表' TYPE 'E'.

ENDIF.

" 获取字段信息

SELECT a~tabname

a~fieldname

a~position

a~keyflag

a~rollname

a~datatype

a~leng

a~decimals

a~reftable

a~reffield

b~ddtext

FROM dd03l AS a

LEFT JOIN dd04t AS b

ON a~rollname = b~rollname

AND a~as4local = b~as4local

AND a~as4vers = b~as4vers

AND b~ddlanguage = sy-langu

INTO TABLE gt_fields

FOR ALL ENTRIES IN gt_tables

WHERE a~tabname = gt_tables-tabname

AND a~as4local = 'A'

AND a~as4vers = '0000'

AND a~fieldname NOT LIKE '.%'

ORDER BY a~tabname, a~position.

ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*

*& 创建Excel文件

*&---------------------------------------------------------------------*

FORM create_excel_file.

DATA: lv_subrc TYPE sy-subrc.

TRY.

CREATE OBJECT go_excel 'Excel.Application'.

SET PROPERTY OF go_excel 'Visible' = 0.

SET PROPERTY OF go_excel 'DisplayAlerts' = 0.

CALL METHOD OF go_excel 'Workbooks' = go_workbook.

CALL METHOD OF go_workbook 'Add'.

CALL METHOD OF go_excel 'Worksheets' = go_worksheets.

CATCH cx_sy_create_object_error INTO lx_error.

lv_error = lx_error->get_text( ).

MESSAGE lv_error TYPE 'E'.

ENDTRY.

ENDFORM.

*&---------------------------------------------------------------------*

*& 写入表清单页签

*&---------------------------------------------------------------------*

FORM write_table_list_sheet.

DATA: lt_temp_fields TYPE TABLE OF ty_field_info,

lv_temp_count TYPE i.

FIELD-SYMBOLS: <fs_field> LIKE LINE OF gt_fields.

" 激活第一个工作表

CALL METHOD OF go_worksheets 'Item' = go_worksheet

EXPORTING

#1 = 1.

SET PROPERTY OF go_worksheet 'Name' = '表清单'.

" 写入标题行

IF p_hdr = 'X'.

PERFORM write_cell USING 1 1 '表名'.

PERFORM write_cell USING 1 2 '描述'.

PERFORM write_cell USING 1 3 '表类型'.

PERFORM write_cell USING 1 4 '字段数量'.

" 设置标题样式

CALL METHOD OF go_worksheet 'Range' = go_range

EXPORTING

#1 = 'A1'

#2 = 'D1'.

SET PROPERTY OF go_range 'Font.Bold' = 1.

SET PROPERTY OF go_range 'Interior.ColorIndex' = 15. " 灰色背景

ENDIF.

" 写入表数据

gv_row = 2.

LOOP AT gt_tables INTO gs_table.

" 表名

PERFORM write_cell USING gv_row 1 gs_table-tabname.

" 描述

PERFORM write_cell USING gv_row 2 gs_table-ddtext.

" 表类型

CASE gs_table-contflag.

WHEN 'C'. " 自定义表

PERFORM write_cell USING gv_row 3 '自定义表'.

WHEN 'G'. " 池表

PERFORM write_cell USING gv_row 3 '池表'.

WHEN 'S'. " 簇表

PERFORM write_cell USING gv_row 3 '簇表'.

WHEN 'E'. " 扩展表

PERFORM write_cell USING gv_row 3 '扩展表'.

WHEN OTHERS.

PERFORM write_cell USING gv_row 3 '其他'.

ENDCASE.

" 字段数量

CLEAR: lt_temp_fields, lv_temp_count.

LOOP AT gt_fields INTO gs_field WHERE tabname = gs_table-tabname.

lv_temp_count = lv_temp_count + 1.

ENDLOOP.

PERFORM write_cell USING gv_row 4 lv_temp_count.

" 创建超链接到对应的工作表

gv_sheet_no = sy-tabix + 1. " 第一个工作表是表清单

" 创建工作表名称

CONCATENATE '字段_' gs_table-tabname INTO lv_sheet_name.

" 工作表名称限制处理

PERFORM escape_sheet_name CHANGING lv_sheet_name.

" 创建超链接

CALL METHOD OF go_worksheet 'Cells' = go_cells

EXPORTING

#1 = gv_row

#2 = 1.

CONCATENATE '#' lv_sheet_name '!A1' INTO lv_link.

CALL METHOD OF go_worksheet 'Hyperlinks' = go_hyperlink

EXPORTING

#1 = go_cells

#2 = ''

#3 = ''

#4 = ''

#5 = lv_link.

FREE OBJECT: go_cells, go_hyperlink.

gv_row = gv_row + 1.

ENDLOOP.

" 自动调整列宽

PERFORM autofit_columns USING 4.

ENDFORM.

*&---------------------------------------------------------------------*

*& 写入字段清单页签

*&---------------------------------------------------------------------*

FORM write_field_sheets.

DATA: lv_first TYPE c.

LOOP AT gt_tables INTO gs_table.

gv_sheet_no = sy-tabix + 1. " 第一个工作表是表清单

" 添加新的工作表

IF sy-tabix = 1.

CALL METHOD OF go_worksheets 'Item' = go_worksheet

EXPORTING

#1 = gv_sheet_no.

ELSE.

CALL METHOD OF go_workbook 'Worksheets' = go_worksheets.

CALL METHOD OF go_worksheets 'Add'.

CALL METHOD OF go_worksheets 'Item' = go_worksheet

EXPORTING

#1 = gv_sheet_no.

ENDIF.

" 设置工作表名称

CONCATENATE '字段_' gs_table-tabname INTO lv_sheet_name.

PERFORM escape_sheet_name CHANGING lv_sheet_name.

TRY.

SET PROPERTY OF go_worksheet 'Name' = lv_sheet_name.

CATCH cx_ole_exception.

" 如果名称重复,添加后缀

CONCATENATE lv_sheet_name(28) '_' sy-tabix INTO lv_sheet_name.

SET PROPERTY OF go_worksheet 'Name' = lv_sheet_name.

ENDTRY.

" 写入表头信息

PERFORM write_cell USING 1 1 '表名:'.

PERFORM write_cell USING 1 2 gs_table-tabname.

PERFORM write_cell USING 2 1 '描述:'.

PERFORM write_cell USING 2 2 gs_table-ddtext.

" 写入字段标题

gv_row = 4.

IF p_hdr = 'X'.

PERFORM write_cell USING gv_row 1 '字段名'.

PERFORM write_cell USING gv_row 2 '位置'.

PERFORM write_cell USING gv_row 3 '主键'.

PERFORM write_cell USING gv_row 4 '数据元素'.

PERFORM write_cell USING gv_row 5 '数据类型'.

PERFORM write_cell USING gv_row 6 '长度'.

PERFORM write_cell USING gv_row 7 '小数位'.

PERFORM write_cell USING gv_row 8 '字段描述'.

PERFORM write_cell USING gv_row 9 '参考表'.

PERFORM write_cell USING gv_row 10 '参考字段'.

" 设置标题样式

CALL METHOD OF go_worksheet 'Range' = go_range

EXPORTING

#1 = 'A4'

#2 = 'J4'.

SET PROPERTY OF go_range 'Font.Bold' = 1.

SET PROPERTY OF go_range 'Interior.ColorIndex' = 15.

gv_row = gv_row + 1.

ENDIF.

" 写入字段数据

LOOP AT gt_fields INTO gs_field WHERE tabname = gs_table-tabname.

PERFORM write_cell USING gv_row 1 gs_field-fieldname.

PERFORM write_cell USING gv_row 2 gs_field-position.

" 主键标识

IF gs_field-keyflag = 'X'.

PERFORM write_cell USING gv_row 3 'X'.

ELSE.

PERFORM write_cell USING gv_row 3 ''.

ENDIF.

PERFORM write_cell USING gv_row 4 gs_field-rollname.

PERFORM write_cell USING gv_row 5 gs_field-datatype.

PERFORM write_cell USING gv_row 6 gs_field-leng.

PERFORM write_cell USING gv_row 7 gs_field-decimals.

PERFORM write_cell USING gv_row 8 gs_field-ddtext.

PERFORM write_cell USING gv_row 9 gs_field-reftable.

PERFORM write_cell USING gv_row 10 gs_field-reffield.

gv_row = gv_row + 1.

ENDLOOP.

" 自动调整列宽

PERFORM autofit_columns USING 10.

" 添加返回链接

CALL METHOD OF go_worksheet 'Cells' = go_cells

EXPORTING

#1 = 1

#2 = 12.

SET PROPERTY OF go_cells 'Value' = '返回表清单'.

CALL METHOD OF go_worksheet 'Hyperlinks' = go_hyperlink

EXPORTING

#1 = go_cells

#2 = ''

#3 = ''

#4 = ''

#5 = '#' & '表清单!A1'.

FREE OBJECT: go_cells, go_hyperlink, go_range.

ENDLOOP.

" 删除多余的工作表

PERFORM delete_extra_sheets.

ENDFORM.

*&---------------------------------------------------------------------*

*& 保存Excel文件

*&---------------------------------------------------------------------*

FORM save_excel_file.

lv_fullpath = p_file.

" 确保文件扩展名正确

IF lv_fullpath CS '.xlsx' OR lv_fullpath CS '.xls'.

" 已有扩展名

ELSE.

CONCATENATE lv_fullpath '.xlsx' INTO lv_fullpath.

ENDIF.

TRY.

CALL METHOD OF go_workbook 'SaveAs'

EXPORTING

#1 = lv_fullpath

#2 = 51. " xlOpenXMLWorkbook

CALL METHOD OF go_workbook 'Close'.

CALL METHOD OF go_excel 'Quit'.

PERFORM cleanup_ole_objects.

MESSAGE s398(00) WITH 'Excel文件已生成:' lv_fullpath.

CATCH cx_ole_exception INTO lx_error.

MESSAGE lx_error->get_text( ) TYPE 'E'.

ENDTRY.

ENDFORM.

*&---------------------------------------------------------------------*

*& 写入单元格

*&---------------------------------------------------------------------*

FORM write_cell USING iv_row TYPE i iv_col TYPE i iv_value TYPE any.

lv_value = iv_value.

CALL METHOD OF go_worksheet 'Cells' = go_cells

EXPORTING

#1 = iv_row

#2 = iv_col.

SET PROPERTY OF go_cells 'Value' = lv_value.

FREE OBJECT go_cells.

ENDFORM.

*&---------------------------------------------------------------------*

*& 自动调整列宽

*&---------------------------------------------------------------------*

FORM autofit_columns USING iv_col_count TYPE i.

DATA: lv_end TYPE string.

gv_col = iv_col_count.

" 将列号转换为Excel列标

IF gv_col <= 26.

lv_col_char = cl_abap_conv_out_ce=>uccp( gv_col + 64 ).

ELSE.

lv_col_char = cl_abap_conv_out_ce=>uccp( ( gv_col - 1 ) DIV 26 + 64 ).

CONCATENATE lv_col_char cl_abap_conv_out_ce=>uccp( MOD( gv_col - 1, 26 ) + 65 ) INTO lv_col_char.

ENDIF.

CONCATENATE 'A1:' lv_col_char '1000' INTO lv_end.

CALL METHOD OF go_worksheet 'Range' = go_range

EXPORTING

#1 = lv_end.

CALL METHOD OF go_range 'EntireColumn' = go_range.

CALL METHOD OF go_range 'AutoFit'.

FREE OBJECT go_range.

ENDFORM.

*&---------------------------------------------------------------------*

*& 删除多余的工作表

*&---------------------------------------------------------------------*

FORM delete_extra_sheets.

DATA: lv_temp TYPE i.

" 获取工作表总数

GET PROPERTY OF go_worksheets 'Count' = lv_sheet_count.

" 只保留需要的工作表

lv_temp = lv_sheet_count.

DO lv_temp TIMES.

lv_index = lv_sheet_count - sy-index + 1.

IF lv_index > lines( gt_tables ) + 1. " 保留表清单和工作表

CALL METHOD OF go_worksheets 'Item' = go_worksheet

EXPORTING

#1 = lv_index.

CALL METHOD OF go_worksheet 'Delete'.

ENDIF.

ENDDO.

ENDFORM.

*&---------------------------------------------------------------------*

*& 处理Excel名称特殊字符

*&---------------------------------------------------------------------*

FORM escape_sheet_name CHANGING cv_name TYPE string.

" Excel工作表名称中不能包含的字符: \ / ? * [ ] :

REPLACE ALL OCCURRENCES OF '\' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF '/' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF '?' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF '*' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF '[' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF ']' IN cv_name WITH '_'.

REPLACE ALL OCCURRENCES OF ':' IN cv_name WITH '_'.

" 工作表名称不能以'开头

IF cv_name(1) = ''''.

cv_name = '_' && cv_name+1.

ENDIF.

" 工作表名称不能超过31个字符

IF strlen( cv_name ) > 31.

cv_name = cv_name(31).

ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*

*& 清理OLE对象

*&---------------------------------------------------------------------*

FORM cleanup_ole_objects.

FREE: go_hyperlink, go_range, go_cells, go_worksheet,

go_worksheets, go_workbook, go_excel.

ENDFORM.

*&---------------------------------------------------------------------*

*& 文件选择对话框

*&---------------------------------------------------------------------*

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

PERFORM f4_file_path.

FORM f4_file_path.

DATA: lt_file_table TYPE filetable,

lv_rc TYPE i,

lv_action TYPE i,

lv_path TYPE string,

lv_fullpath TYPE string.

CALL METHOD cl_gui_frontend_services=>file_save_dialog

EXPORTING

window_title = '保存Excel文件'

default_extension = 'xlsx'

default_file_name = 'table_fields.xlsx'

file_filter = 'Excel文件 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*'

CHANGING

filename = p_file

path = lv_path

fullpath = lv_fullpath

user_action = lv_action

file_table = lt_file_table

EXCEPTIONS

cntl_error = 1

error_no_gui = 2

not_supported_by_gui = 3

OTHERS = 4.

IF sy-subrc = 0 AND lv_action = cl_gui_frontend_services=>action_ok.

p_file = lv_fullpath.

ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*

*& 结束选择

*&---------------------------------------------------------------------*

END-OF-SELECTION.

" 程序结束

相关推荐
sinat_375112262 天前
abap excel上传
excel·上传·sap·abap
旧巷烟火3 天前
PS成长之路⑩:如何通过WBS进行项目人工成本的精准归集
sap·ps·erp
爱喝水的鱼丶6 天前
SAP-ABAP:全面破解SAP与第三方系统集成超时难题:从应急排查到根治方案
开发语言·sap·abap·接口集成·开发交流
乐乐82346 天前
处理大数据用游标 CURSOR
abap
燚㵘䲜7 天前
CL_GUI_FRONTEND_SERVICES常用method
abap
xlxxy_11 天前
abap 批量创建供应商
运维·开发语言·sap·abap·pp·mm
淋了一场太阳雨12 天前
ABAP 使用函数获取替代(Substitution)值
sap·abap·函数·替代·subsititution
爱喝水的鱼丶13 天前
SAP-ABAP:在SAP世界里与特殊字符“斗智斗勇”:一份来自实战的避坑指南
运维·服务器·数据库·学习·sap·abap·特殊字符
淋了一场太阳雨13 天前
SAP VOFM Material determination
sap·abap