原文链接:https://code84.com/257785.html
1.确保在系统种实施了note:1605054的代码更正
---------------------关于第一点的报错补充 start----------------------
abap ftp 提示:用户 & 没有访问计算机 & 的权限 或者提示:REC到程序SAPFTP失败
项目中,在没有升级到EHP6 on HANA时,FTP上传程序正常运行,升级后,遇到了以下问题,历经磨难,终于得以解决,分享一下,供用到的兄弟做个参考
升级后,提示:用户 & 没有访问计算机 & 的权限,比较了一下代码:升级后的函数FTP_CONNECT增加了一些校验,需要在透明表SAPFTP_SERVERS中维护ftp地址和端口,上网查了一些资料,说是要打note,basis下载后,最后版本支持到740,而目前用的是750,索性写段代码直接把表给维护了,代码如下:
DATA:lt_sapftp_servers TYPE TABLE OF sapftp_servers WITH HEADER LINE.
lt_sapftp_servers-ftp_server_name = ‘’. "ftp服务器地址
lt_sapftp_servers-ftp_server_port = ‘’. "ftp服务器端口
lt_sapftp_servers-description = ‘’.
APPEND lt_sapftp_servers.
CLEAR lt_sapftp_servers.
MODIFY sapftp_servers FROM TABLE lt_sapftp_servers.
IF sy-subrc EQ 0.
MESSAGE ‘成功’ TYPE ‘I’.
ENDIF.
或者直接SM30去视图 SAPFTP_SERVERS_V 里维护(看下面第三点)
如果你的GUI升级到750,对不起,还可能能遇到一个SAPFTP的问题,SAPFTP.exe必须用最新的,否则,会提示:”RFC 到程序 SAPFTP 失败“的错误
下载地址(要钱的):http://download.csdn.net/download/champaignwolf/10048563
注意:下载到本地后, C:\Program Files (x86)\SAP\FrontEnd\SapGui 下面找到SAPftp.exe 进行替换(解决SAP750客户端REC到程序SAPFTP失败)
---------------------关于第一点的报错补充 end----------------------
2.确保通过SM59创建了RFC连接:可通过执行标准程序RSFTP005,自动创建两个名为SAPFTP和SAPFTPA的TCP/IP的RFC连接
3.确保表SAPFTP_SERVERS允许连接指定FTP;设置*表示允许所有FTP连接:可通过SM30视图:SAPFTP_SERVERS_V维护表SAPFTP_SERVERS
4.确保FTP服务器网络可达,服务端口正常开启并可访问
PARAMETERS: P_FILE TYPE STRING OBLIGATORY,
P_HOST TYPE CHAR30 DEFAULT '10.3.123.140' LOWER CASE,
P_FOLDER TYPE CHAR100 DEFAULT '/sap/' LOWER CASE, "ftp服务器路径;必须/结尾
P_USER TYPE CHAR30 DEFAULT 'user' LOWER CASE,
P_PASSWD TYPE CHAR30 DEFAULT 'a123456' LOWER CASE,
DEST LIKE RFCDES-RFCDEST DEFAULT 'SAPFTP',
COMPRESS TYPE C DEFAULT 'N'. "是否压缩
DATA: PATH TYPE STRING, "用于接收上传文件的路径和名称
FILENAME TYPE STRING.
DATA: HDL TYPE I,
KEY TYPE I VALUE 26101957,
SLEN TYPE I,
CMD(80) TYPE C.
DATA: BEGIN OF RESULT OCCURS 0,
LINE(100) TYPE C,
END OF RESULT.
DATA: ABAP_ENCODING TYPE ABAP_ENCODING VALUE 'UTF-8'.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE.
CALL FUNCTION 'GUI_FILE_LOAD_DIALOG'
EXPORTING
WINDOW_TITLE = '打开文件'
* DEFAULT_EXTENSION =
* DEFAULT_FILE_NAME =
WITH_ENCODING = ABAP_TRUE
* FILE_FILTER =
* INITIAL_DIRECTORY =
IMPORTING
PATH = PATH
FILENAME = FILENAME
FULLPATH = P_FILE
FILE_ENCODING = ABAP_ENCODING.
START-OF-SELECTION.
SLEN = STRLEN( P_PASSWD ).
* "获取加密密码 保存到P_PASSWD
CALL FUNCTION 'HTTP_SCRAMBLE'
EXPORTING
SOURCE = P_PASSWD
SOURCELEN = SLEN
KEY = KEY
IMPORTING
DESTINATION = P_PASSWD.
* 连接ftp服务器
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
USER = P_USER
PASSWORD = P_PASSWD
HOST = P_HOST
RFC_DESTINATION = DEST
IMPORTING
HANDLE = HDL. "连接的句柄
"执行FTP命令 CD 打开目标ftp的文件夹
"now open the target ftp folder
CONCATENATE 'cd' P_FOLDER INTO CMD SEPARATED BY SPACE.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
HANDLE = HDL
COMMAND = CMD
COMPRESS = COMPRESS
TABLES
DATA = RESULT
EXCEPTIONS
COMMAND_ERROR = 1
TCPIP_ERROR = 2.
LOOP AT RESULT.
WRITE AT / RESULT-LINE.
ENDLOOP.
REFRESH RESULT.
* 打开本地需上传文件的路径
CONCATENATE 'lcd' PATH INTO CMD SEPARATED BY SPACE.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
HANDLE = HDL
COMMAND = CMD
COMPRESS = COMPRESS
TABLES
DATA = RESULT
EXCEPTIONS
COMMAND_ERROR = 1
TCPIP_ERROR = 2.
LOOP AT RESULT.
WRITE AT / RESULT-LINE.
ENDLOOP.
REFRESH RESULT.
* 将本地文件放到目标ftp文件夹中
CONCATENATE 'put ' FILENAME INTO CMD SEPARATED BY SPACE.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
HANDLE = HDL
COMMAND = CMD
COMPRESS = COMPRESS
TABLES
DATA = RESULT
EXCEPTIONS
COMMAND_ERROR = 1
TCPIP_ERROR = 2.
LOOP AT RESULT.
WRITE AT / RESULT-LINE.
ENDLOOP.
REFRESH RESULT.
* 断开FTP连接
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
HANDLE = HDL.
* 断开RFC链接
CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
DESTINATION = DEST
EXCEPTIONS
OTHERS = 1.
*&---------------------------------------------------------------------*
*& Report ZCYCLE048
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcycle048.
TYPES:
BEGIN OF struct,
key1 TYPE string,
key2 TYPE string,
col TYPE i,
END OF struct,
itab TYPE STANDARD TABLE OF struct WITH EMPTY KEY.
"发送FTP的内表最好不要包含数字字段,不然在转换成CSV的时候会因为有千分位,被识别成分隔符,我的习惯是全用STRING类型
DATA: l_user(30) TYPE c VALUE 'USER', "用户名
l_pwd(30) TYPE c VALUE 'PASSWORD', "密码
l_host(64) TYPE c VALUE '192.168.1.1 6666', "FTP服务器地址(IP 空格 端口)
l_path(64) TYPE c VALUE 'ftplog/', "FTP路径
l_rc(1),
l_dest TYPE rfcdes-rfcdest . "前端:sapftp 后台运行:sapftpa.
DATA: l_handle TYPE i,
l_command(255) TYPE c,
l_result TYPE TABLE OF txmisporow,
l_filename(50) TYPE c,
l_pwdlength TYPE i,
l_length TYPE i,
l_ftppwd(255) TYPE c,
l_key TYPE i VALUE 26101957,
l_encoding TYPE abap_encoding VALUE '8400'.
DATA: lt_text TYPE truxs_t_text_data. "CSV内表
DATA: l_binary_tab LIKE TABLE OF solix. "二进制内表
DATA: BEGIN OF ls_tab,
tline(4096),
END OF ls_tab.
DATA: lt_tab LIKE TABLE OF ls_tab. "单列内表
PARAMETERS p_da TYPE sy-datum.
START-OF-SELECTION.
IF sy-batch = 'X'.
l_dest = 'SAPFTPA'.
ELSE.
l_dest = 'SAPFTP'.
ENDIF.
"填充内表
DATA(itab) = VALUE itab(
( key1 = `a` key2 = `a` col = 1 )
( key1 = `a` key2 = `b` col = 2 )
( key1 = `a` key2 = `a` col = 3 )
( key1 = `a` key2 = `a` col = 4 )
( key1 = `a` key2 = `b` col = 5 )
( key1 = `b` key2 = `a` col = 6 )
( key1 = `b` key2 = `a` col = 7 ) ).
DATA itab2 LIKE itab[] WITH HEADER LINE.
"每次拆分条数
DATA count TYPE i VALUE 50000 .
DO 100010 TIMES.
ls_itab-key1 = 'Q'.
ls_itab-key2 = 'W'.
ls_itab-col = 10.
APPEND ls_itab TO itab.
ENDDO.
WHILE itab[] IS NOT INITIAL. "如果内表数据太大,则分批导入
CLEAR:l_handle,lt_tab[],l_length.
CLEAR itab2[].
APPEND LINES OF itab TO count TO itab2 . "把itab的前50000条数据给到表itab2
DELETE itab TO count. "删除itab的前50000条数据
l_pwdlength = strlen( l_pwd ).
*****************开始FTP传输数据**********
CALL FUNCTION 'HTTP_SCRAMBLE' "密码加密
EXPORTING
source = l_pwd
sourcelen = l_pwdlength
key = l_key
IMPORTING
destination = l_ftppwd.
"创建FTP连接
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
user = l_user
password = l_ftppwd
host = l_host
rfc_destination = l_dest
IMPORTING
handle = l_handle
EXCEPTIONS
not_connected = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE 'FTP 连接失败' TYPE 'E'.
ENDIF.
l_rc = COND #( WHEN l_path+(1) = '/' THEN ' ' ELSE ' /' ).
CONCATENATE 'cd' l_path INTO l_command SEPARATED BY l_rc. "拼接FTP命令,这里是打开文件夹地址
CALL FUNCTION 'FTP_COMMAND' "执行FTP命令
EXPORTING
handle = l_handle
command = l_command
TABLES
data = l_result
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
"关闭ftp 连接
PERFORM disconnect_ftp USING l_handle l_dest.
MESSAGE 'FTP 路径打开失败' TYPE 'E'.
ENDIF.
CONCATENATE 'polist_' sy-datum '_' sy-uzeit '.csv' INTO l_filename.
* 将内表数据转换成逗号分割符CSV文件
CALL FUNCTION 'SAP_CONVERT_TO_TEX_FORMAT'
EXPORTING
i_field_seperator = ',' " Comma seperator
TABLES
i_tab_sap_data = itab2
CHANGING
i_tab_converted_data = lt_text
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
"设置文件表头(以逗号分隔)
ls_tab-tline = 'key1,key2,col'.
APPEND ls_tab TO lt_tab.
CLEAR ls_tab.
LOOP AT lt_text ASSIGNING FIELD-SYMBOL(<text>).
"把数据存到一个单列的内表,等一下用作转换二进制用
APPEND VALUE #( tline = <text> ) TO lt_tab.
ENDLOOP.
CALL FUNCTION 'SCMS_TEXT_TO_BINARY' "转换成二进制文件
EXPORTING
encoding = l_encoding
IMPORTING
output_length = l_length
TABLES
text_tab = lt_tab
binary_tab = l_binary_tab
EXCEPTIONS
failed = 1
OTHERS = 2.
"刚刚已经用ftp命令打开的文件夹,现在可以直接把二进制文件传至服务器了。
CALL FUNCTION 'FTP_R3_TO_SERVER'
EXPORTING
handle = l_handle
fname = l_filename
blob_length = l_length
character_mode = ' '
TABLES
blob = l_binary_tab
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
CASE sy-subrc.
WHEN 0.
MESSAGE '文件上传FTP成功' TYPE 'S'.
WHEN 1.
MESSAGE '文件上传FTP失败 (Tcpip_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN 2.
MESSAGE '文件上传FTP失败 (Command_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN 3.
MESSAGE '文件上传FTP失败 (Data_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN OTHERS.
MESSAGE '文件上传FTP失败 (Other)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
ENDCASE.
"关闭ftp 连接
PERFORM disconnect_ftp USING l_handle l_dest.
WAIT UP TO 1 SECONDS.
ENDWHILE.
FORM disconnect_ftp USING p_handle p_dest.
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
handle = p_handle.
CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
destination = p_dest
EXCEPTIONS
destination_not_open = 1
OTHERS = 2.
ENDFORM.
16进制的程序如下
*&---------------------------------------------------------------------*
*& Report ZCYCLE048
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcycle048.
TYPES:
BEGIN OF struct,
key1 TYPE string,
key2 TYPE string,
col TYPE i,
END OF struct,
itab TYPE STANDARD TABLE OF struct WITH EMPTY KEY.
DATA ls_itab TYPE struct.
DATA: l_user(30) TYPE c VALUE 'username', "用户名
l_pwd(30) TYPE c VALUE 'password', "密码
l_host(64) TYPE c VALUE '192.168.1.1 6666', "FTP服务器地址(IP 空格 端口)
l_path(64) TYPE c VALUE 'pur/', "FTP路径
l_rc(1),
l_dest TYPE rfcdes-rfcdest . "前端:sapftp 后台运行:sapftpa.
DATA: l_handle TYPE i,
l_command(255) TYPE c,
l_result TYPE TABLE OF txmisporow,
l_filename(50) TYPE c,
l_pwdlength TYPE i,
l_length TYPE i,
l_ftppwd(255) TYPE c,
l_key TYPE i VALUE 26101957,
l_encoding TYPE abap_encoding VALUE '8400'.
DATA: lt_text TYPE truxs_t_text_data. "CSV内表
DATA: l_binary_tab LIKE TABLE OF solix. "二进制内表
DATA: BEGIN OF ls_tab,
tline(4096),
END OF ls_tab.
DATA: lt_tab LIKE TABLE OF ls_tab. "单列内表
DATA: lv_first TYPE c.
DATA :lv_xstring TYPE xstring, "二进制CSV数据
lv_string TYPE string. "原始CSV数据
PARAMETERS p_da TYPE sy-datum.
START-OF-SELECTION.
IF sy-batch = 'X'.
l_dest = 'SAPFTPA'.
ELSE.
l_dest = 'SAPFTP'.
ENDIF.
"填充内表
DATA(itab) = VALUE itab(
( key1 = `key1` key2 = `key2` col = 0 )
( key1 = `a` key2 = `a` col = 1 )
( key1 = `a` key2 = `b` col = 2 )
( key1 = `a` key2 = `a` col = 3 )
( key1 = `a` key2 = `a` col = 4 )
( key1 = `a` key2 = `b` col = 5 )
( key1 = `b` key2 = `a` col = 6 )
( key1 = `b` key2 = `a` col = 7 ) ).
DATA itab2 LIKE itab[] WITH HEADER LINE.
"每次拆分条数
DATA count TYPE i VALUE 50000 .
DO 10000 TIMES.
ls_itab-key1 = 'Q'.
ls_itab-key2 = 'W'.
ls_itab-col = 10.
APPEND ls_itab TO itab.
ENDDO.
l_pwdlength = strlen( l_pwd ).
*****************开始FTP传输数据**********
CALL FUNCTION 'HTTP_SCRAMBLE' "密码加密
EXPORTING
source = l_pwd
sourcelen = l_pwdlength
key = l_key
IMPORTING
destination = l_ftppwd.
"创建FTP连接
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
user = l_user
password = l_ftppwd
host = l_host
rfc_destination = l_dest
IMPORTING
handle = l_handle
EXCEPTIONS
not_connected = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE 'FTP 连接失败' TYPE 'E'.
ENDIF.
l_rc = COND #( WHEN l_path+(1) = '/' THEN ' ' ELSE ' /' ).
CONCATENATE 'cd' l_path INTO l_command SEPARATED BY l_rc. "拼接FTP命令,这里是打开文件夹地址
CALL FUNCTION 'FTP_COMMAND' "执行FTP命令
EXPORTING
handle = l_handle
command = l_command
TABLES
data = l_result
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
"关闭ftp 连接
PERFORM disconnect_ftp USING l_handle l_dest.
MESSAGE 'FTP 路径打开失败' TYPE 'E'.
ENDIF.
CONCATENATE 'polist_' sy-datum '_' sy-uzeit '.csv' INTO l_filename.
* 将内表数据转换成逗号分割符CSV文件
CALL FUNCTION 'SAP_CONVERT_TO_TEX_FORMAT'
EXPORTING
i_field_seperator = ',' " Comma seperator
TABLES
i_tab_sap_data = itab
CHANGING
i_tab_converted_data = lt_text
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
* "设置文件表头(以逗号分隔)
* ls_tab-tline = 'key1,key2,col'.
* APPEND ls_tab TO lt_tab.
* CLEAR ls_tab.
*
* LOOP AT lt_text ASSIGNING FIELD-SYMBOL(<text>).
* "把数据存到一个单列的内表,等一下用作转换二进制用
* APPEND VALUE #( tline = <text> ) TO lt_tab.
* ENDLOOP.
*
*
* CALL FUNCTION 'SCMS_TEXT_TO_BINARY' "转换成二进制文件
* EXPORTING
* encoding = l_encoding
* IMPORTING
* output_length = l_length
* TABLES
* text_tab = lt_tab
* binary_tab = l_binary_tab
* EXCEPTIONS
* failed = 1
* others = 2.
"RFC SCMS_TEXT_TO_BINARY 在转换的内表数据很大的时候,会直接DUMP,出来一个空表
"所以我先把表转成16进制,然后再把16进制的数据转化成2进制的表
"把CSV内表转换成十六进制数据(XSTRING)
LOOP AT lt_text ASSIGNING FIELD-SYMBOL(<fs_table>).
CLEAR:lv_first.
AT FIRST.
lv_first = 'X'.
lv_string = <fs_table>.
ENDAT.
IF lv_first <> 'X'.
CONCATENATE lv_string <fs_table> INTO lv_string SEPARATED BY cl_abap_char_utilities=>newline.
ENDIF.
ENDLOOP.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
* codepage_to = '8300'
mimetype = '"APPLICATION/MSEXCEL; charset=gb2312"'
"mimetype = '"application/json; charset=utf-8"'
text = lv_string
IMPORTING
buffer = lv_xstring
EXCEPTIONS
failed = 1
OTHERS = 2.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstring
* APPEND_TO_TABLE = ' '
IMPORTING
output_length = l_length
TABLES
binary_tab = l_binary_tab.
"刚刚已经用ftp命令打开的文件夹,现在可以直接把二进制文件传至服务器了。
CALL FUNCTION 'FTP_R3_TO_SERVER'
EXPORTING
handle = l_handle
fname = l_filename
blob_length = l_length
character_mode = ' '
TABLES
blob = l_binary_tab
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
CASE sy-subrc.
WHEN 0.
MESSAGE '文件上传FTP成功' TYPE 'S'.
WHEN 1.
MESSAGE '文件上传FTP失败 (Tcpip_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN 2.
MESSAGE '文件上传FTP失败 (Command_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN 3.
MESSAGE '文件上传FTP失败 (Data_error)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
WHEN OTHERS.
MESSAGE '文件上传FTP失败 (Other)' TYPE 'S' DISPLAY LIKE 'E'.EXIT.
ENDCASE.
"关闭ftp 连接
PERFORM disconnect_ftp USING l_handle l_dest.
FORM disconnect_ftp USING p_handle p_dest.
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
handle = p_handle.
CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
destination = p_dest
EXCEPTIONS
destination_not_open = 1
OTHERS = 2.
ENDFORM.
就是把内表转换成二进制,有以下方法可以使用:
SAP_CONVERT_TO_CSV_FORMAT
SAP_CONVERT_TO_TXT_FORMAT
SAP_CONVERT_TO_TEX_FORMAT
SAP_CONVERT_TO_XLS_FORMAT
SAP_CONVERT_TO_XML_FORMAT
SCMS_TEXT_TO_BINARY
SCMS_XSTRING_TO_BINARY
有兴趣的可以自己百度一下