需求描述:
- SAP中通过运行事务码FBPM生成付款文件,触发传输将文件写入跳板机,写入跳板机之前,检查文件是否已存在,存在则给出提示无需执行
实现步骤 :
- 文件校验
参照标准函数FI_PAYMEDIUM_SAMPLE_21 创建自定义函数ZFI_PAYMEDIUM_SAMPLE_21_COPY1添加自定义校验逻辑,代码如下
FUNCTION zfi_paymedium_sample_21_copy1 .
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(I_FPAYH) LIKE FPAYH STRUCTURE FPAYH
*" VALUE(I_FPAYHX) LIKE FPAYHX STRUCTURE FPAYHX
*" VALUE(I_FORMAT_PARAMS) TYPE FPM_SELPAR-PARAM
*" VALUE(I_FORMAT_PARAMS_C) TYPE FPM_SELPAR-PARAM
*" VALUE(I_FILENAME) LIKE REGUT-FSNAM
*" VALUE(I_XFILESYSTEM) TYPE DFILESYST
*" TABLES
*" T_FILE_OUTPUT STRUCTURE FPM_FILE
*" CHANGING
*" REFERENCE(C_FILENAME) LIKE REGUT-FSNAM
*"----------------------------------------------------------------------
DATA lv_pwd TYPE text30 .
DATA lv_account TYPE text30 .
DATA lv_host TYPE string VALUE '文件路径'.
DATA lv_port TYPE string.
DATA lv_filename TYPE regut-fsnam VALUE 'MINTH_XMLv3'.
CONSTANTS x_linesize TYPE i VALUE 128.
TYPES x_linetype TYPE x LENGTH x_linesize.
DATA tab_xfile TYPE STANDARD TABLE OF xstring.
DATA lv_in_codepage TYPE regut-codepage.
DATA out_codepage TYPE regut-codepage.
DATA user_codepage TYPE regut-codepage.
DATA lv_laufi TYPE regut-laufi.
DATA lv_dttyp TYPE regut-dttyp.
DATA lv_dtfor TYPE regut-dtfor.
DATA g_function TYPE rs38l_fnam.
DATA tab_x TYPE STANDARD TABLE OF x_linetype.
DATA wa_x TYPE xstring.
DATA wa_xfile LIKE LINE OF tab_xfile.
DATA filename_string TYPE string.
DATA linesize TYPE i.
DATA lines TYPE i.
DATA length TYPE i.
DATA fill_length TYPE i.
DATA last_length TYPE i.
DATA filesize TYPE i.
DATA after_download_length TYPE i.
DATA l_format_cp TYPE cpcodepage.
DATA ls_tfpm042f LIKE tfpm042f.
DATA lv_command(200) TYPE c.
DATA lv_fname TYPE char300.
DATA lt_msg TYPE esp1_message_tab_type.
SELECT SINGLE * FROM ztsd018 INTO @DATA(ls_ztsd018) WHERE ftp_name = 'FBPM_UP'.
lv_host = ls_ztsd018-ftp_ip.
lv_pwd = ls_ztsd018-ftp_pwd.
lv_account = ls_ztsd018-ftp_user.
SELECT SINGLE land1 FROM t042z INTO @DATA(lv_land1) WHERE formi = @i_fpayhx-formi.
lv_filename = |{ lv_filename }_{ lv_land1 }_{ i_fpayh-laufd }_{ i_fpayh-laufi }|.
"加密
lv_pwd = zcl_ftp_connect=>http_scramble( lv_pwd ).
"ftp连接
DATA(lo_ftp) = NEW zcl_ftp_connect( iv_account = lv_account
iv_pass = lv_pwd
iv_host = lv_host
iv_port = lv_port ).
DATA(lv_handle) = lo_ftp->get_handle( ).
IF lv_handle IS INITIAL.
DATA(ls_msg) = lo_ftp->connect( lo_ftp->gc-rfc_dest-sapftpa ).
ENDIF.
lv_handle = lo_ftp->get_handle( ).
IF lv_handle IS INITIAL AND sy-batch IS INITIAL.
MESSAGE TEXT-e01 TYPE 'I' DISPLAY LIKE 'E'.
EXIT.
ENDIF.
"定位到目录
lv_command = |cd { ls_ztsd018-file_path }|.
DATA(lt_result) = lo_ftp->command( EXPORTING iv_cmd = lv_command IMPORTING es_msg = ls_msg ).
IF ls_msg-type EQ 'E' .
MESSAGE TEXT-e02 TYPE 'S' DISPLAY LIKE 'E'.
lo_ftp->disconnect( ).
EXIT.
ENDIF.
" 检查文件已存在,
lv_fname = lv_filename.
CALL FUNCTION 'FTP_SERVER_TO_R3'
EXPORTING
handle = lv_handle
fname = lv_fname
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3.
IF sy-subrc = 0 .
lo_ftp->disconnect( ). " 关闭ftp连接
MESSAGE TEXT-001 TYPE 'I' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
lo_ftp->disconnect( ). " 关闭ftp连接
EXIT.
ENDFUNCTION.
- 文件写入指定路径
参照标准函数FI_PAYMEDIUM_SAMPLE_41创建自定义函数ZFI_PAYMEDIUM_SAMPLE_41_COPY1,自定义函数中添加文件写入逻辑
FUNCTION zfi_paymedium_sample_41_copy1 .
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(I_FPAYH) LIKE FPAYH STRUCTURE FPAYH
*" VALUE(I_FPAYHX) LIKE FPAYHX STRUCTURE FPAYHX
*" TABLES
*" T_FILE_OUTPUT STRUCTURE FPM_FILE
*" CHANGING
*" REFERENCE(C_WAERS) LIKE FPAYH-WAERS
*" REFERENCE(C_SUM) LIKE FPAYH-RWBTR
*"----------------------------------------------------------------------
TYPES:
BEGIN OF ftp_line,
line(200) TYPE c,
END OF ftp_line.
DATA lv_pwd TYPE text30.
DATA lv_account TYPE text30 .
DATA lv_host TYPE string.
DATA lv_host1 TYPE string .
DATA lv_port TYPE string.
DATA lv_filename TYPE regut-fsnam VALUE 'MINTH_XMLv3'.
DATA lv_filename1 TYPE rlgrap-filename.
DATA lv_in_codepage TYPE regut-codepage.
DATA out_codepage TYPE regut-codepage.
DATA user_codepage TYPE regut-codepage.
DATA lv_laufi TYPE regut-laufi.
DATA lv_dttyp TYPE regut-dttyp.
DATA lv_dtfor TYPE regut-dtfor.
DATA lv_command(200) TYPE c.
DATA lv_encoding TYPE abap_encoding.
DATA lr_conv TYPE REF TO cl_abap_conv_out_ce.
DATA lv_buffer TYPE xstring.
DATA lt_blob TYPE STANDARD TABLE OF x255.
DATA lt_text TYPE STANDARD TABLE OF x255.
DATA lv_length TYPE i.
DATA lv_message TYPE string.
DATA lv_fname TYPE char300.
DATA ls_tfpm042f LIKE tfpm042f.
DATA g_function TYPE rs38l_fnam.
DATA l_format_cp TYPE cpcodepage.
DATA lt_data TYPE STANDARD TABLE OF ftp_line.
DATA lx_string TYPE xstring.
DATA ls_encoding_string TYPE string.
DATA lv_answer TYPE c.
DATA ls_msg TYPE bapiret2.
SELECT SINGLE * FROM ztsd018 INTO @DATA(ls_ztsd018) WHERE ftp_name = 'FBPM_UP'.
lv_host = ls_ztsd018-ftp_ip.
lv_pwd = ls_ztsd018-ftp_pwd.
lv_account = ls_ztsd018-ftp_user.
SELECT SINGLE land1 FROM t042z INTO @DATA(lv_land1) WHERE formi = @i_fpayhx-formi.
lv_filename = |{ lv_filename }_{ lv_land1 }_{ i_fpayh-laufd }_{ i_fpayh-laufi }|.
"加密
lv_pwd = zcl_ftp_connect=>http_scramble( lv_pwd ).
"ftp连接
DATA(lo_ftp) = NEW zcl_ftp_connect( iv_account = lv_account
iv_pass = lv_pwd
iv_host = lv_host
iv_port = lv_port ).
DATA(lv_handle) = lo_ftp->get_handle( ).
IF lv_handle IS INITIAL.
ls_msg = lo_ftp->connect( lo_ftp->gc-rfc_dest-sapftpa ).
ENDIF.
lv_handle = lo_ftp->get_handle( ).
IF lv_handle IS INITIAL AND sy-batch IS INITIAL.
MESSAGE TEXT-e01 TYPE 'I' DISPLAY LIKE 'E'.
EXIT.
ENDIF.
"定位到目录
lv_command = |cd { ls_ztsd018-file_path }|.
DATA(lt_result) = lo_ftp->command( EXPORTING iv_cmd = lv_command IMPORTING es_msg = ls_msg ).
IF ls_msg-type EQ 'E' .
MESSAGE TEXT-e02 TYPE 'S' DISPLAY LIKE 'E'.
lo_ftp->disconnect( ).
EXIT.
ENDIF.
" 检查文件已存在,
lv_fname = lv_filename.
CALL FUNCTION 'FTP_SERVER_TO_R3'
EXPORTING
handle = lv_handle
fname = lv_fname
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3.
IF sy-subrc = 0 .
lo_ftp->disconnect( ). " 关闭ftp连接
MESSAGE TEXT-001 TYPE 'I' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
EXIT.
ENDIF.
* 将外部字符集名转换为内部编码
lv_laufi = i_fpayh-laufi.
lv_dtfor = i_fpayhx-formi.
"get dttyp
CALL FUNCTION 'FI_PAYM_FORMAT_READ_FORMATYPE'
EXPORTING
i_formi = i_fpayhx-formi
i_zbukr = i_fpayh-zbukr
i_zlsch = i_fpayh-rzawe
i_hbkid = i_fpayh-hbkid
IMPORTING
e_tfpm042f = ls_tfpm042f.
lv_dttyp = ls_tfpm042f-dttyp.
* " get Codepage lesen
CALL FUNCTION 'FI_PAYM_FORMAT_READ_CODEPAGE'
EXPORTING
i_formi = i_fpayhx-formi
IMPORTING
e_codepage = lv_in_codepage
EXCEPTIONS
not_found = 4.
IF sy-subrc NE 0.
CLEAR lv_in_codepage.
ENDIF.
IF lv_laufi+5(1) = 'M'.
g_function = 'FKK_DME_FDTA_CODEPAGE_GET'.
CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = g_function
EXCEPTIONS
function_not_exist = 1.
IF sy-subrc = 0.
CALL FUNCTION g_function
EXPORTING
i_formi = lv_dtfor
IMPORTING
e_codepage = l_format_cp
EXCEPTIONS
OTHERS = 1.
ENDIF.
ELSEIF lv_dttyp = '90'.
READ TABLE t_file_output INDEX 1 INTO lx_string.
* search for string encoding = ... in file
PERFORM check_encoding_of_xml_file USING lx_string lv_in_codepage
CHANGING ls_encoding_string.
IF ls_encoding_string = 'utf-8' OR ls_encoding_string = 'UTF-8'.
l_format_cp = '4110'.
ELSEIF ls_encoding_string = 'utf-16' OR ls_encoding_string = 'UTF-16'.
* keep in utf-16, no conversion, file stored in Temse
l_format_cp = lv_in_codepage.
ELSE.
CALL FUNCTION 'FI_PAYM_FORMAT_READ_CODEPAGE'
EXPORTING
i_formi = lv_dtfor
IMPORTING
e_codepage = l_format_cp
EXCEPTIONS
not_found = 1
OTHERS = 2.
ENDIF.
* end 2832354
ELSEIF lv_dttyp = '01' OR lv_dttyp = '04' OR lv_dttyp = '06'.
CALL FUNCTION 'FI_PAYM_FORMAT_READ_CODEPAGE'
EXPORTING
i_formi = lv_dtfor
IMPORTING
e_codepage = l_format_cp
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF l_format_cp IS INITIAL AND cl_abap_char_utilities=>charsize > 1 AND
lv_dttyp = '04'.
l_format_cp = '4110'.
ENDIF.
ENDIF.
IF NOT l_format_cp IS INITIAL.
IF lv_in_codepage = l_format_cp.
* file aready converted to codepage assigned in the format configuration
out_codepage = lv_in_codepage.
ELSE.
* old file that was not converted yet: convert it now
out_codepage = l_format_cp.
ENDIF.
ELSE.
* no codepage in customizing specified
GET PARAMETER ID 'DCP' FIELD user_codepage.
IF cl_abap_char_utilities=>charsize > 1.
* unicode system
IF ( lv_in_codepage = '4102' OR lv_in_codepage = '4103' ).
* unicode / system codepage
IF user_codepage IS INITIAL.
out_codepage = '1100'.
ELSEIF user_codepage = 'NONE'.
out_codepage = lv_in_codepage.
ELSE.
out_codepage = user_codepage.
ENDIF.
ELSE.
* ignore DCP parameter, file is already in specific codepage (regut-codepage)
out_codepage = lv_in_codepage.
ENDIF.
ELSE.
* non unicode system
IF user_codepage IS INITIAL.
out_codepage = '1100'.
ELSEIF user_codepage = 'NONE'.
out_codepage = lv_in_codepage.
ELSE.
out_codepage = user_codepage.
ENDIF.
ENDIF.
ENDIF.
lv_encoding = out_codepage.
TRY.
CALL METHOD cl_abap_conv_out_ce=>create
EXPORTING
encoding = lv_encoding
ignore_cerr = abap_true
RECEIVING
conv = lr_conv.
CATCH cx_parameter_invalid_range.
CATCH cx_sy_codepage_converter_init.
ENDTRY.
* DATA(lv_data) = REDUCE string(
* INIT x = ||
* FOR wa IN t_file_output[]
* NEXT x = |{ x }{ wa-line }| ).
DATA lv_data TYPE string.
LOOP AT t_file_output.
CONCATENATE lv_data t_file_output-line(t_file_output-length) INTO lv_data RESPECTING BLANKS.
ENDLOOP.
TRY.
CALL METHOD lr_conv->convert
EXPORTING
data = lv_data
IMPORTING
buffer = lv_buffer.
CATCH cx_sy_codepage_converter_init .
CATCH cx_sy_conversion_codepage .
CATCH cx_parameter_invalid_type .
ENDTRY.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_buffer
TABLES
binary_tab = lt_blob.
lv_length = xstrlen( lv_buffer ).
CALL FUNCTION 'FTP_R3_TO_SERVER'
EXPORTING
handle = lv_handle
fname = lv_fname
blob_length = lv_length
TABLES
blob = lt_blob
text = lt_text
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
lo_ftp->disconnect( ). " 关闭ftp连接
MESSAGE '数据写入失败'(005) TYPE 'S' DISPLAY LIKE 'E'.
ELSE.
lo_ftp->disconnect( ). " 关闭ftp连接
IF sy-batch IS INITIAL.
MESSAGE '数据写入成功'(004) TYPE 'I' DISPLAY LIKE 'S'.
ENDIF.
ENDIF.
ENDFUNCTION.
事务码OBPM3维护配置模版事件模块21和41