Beruflich Dokumente
Kultur Dokumente
Applies to:
SAP BI 7.0/BW 3.x. For more information, visit the Business Intelligence homepage.
Summary
In any IT infrastructure of a Company it is very common to have many servers supporting various applications. Therefore SAP BI being a consumer of data may have to maintain interface with many systems. In such cases sending or receiving files via FTP is a very common task. In this article an ABAP based solution is presented to achieve this in hassle free manner. Author: Hemant Kumar Vyas
Author Bio
Hemant Kumar Vyas has been working for Infosys technologies limited for past 2.5 years and has experience in SAP BI 7.0 implementations.
Table of Contents
Salient Features .................................................................................................................................................. 3 Steps to Create ............................................................................................................................................... 3 Create Structure ZZFILI .................................................................................................................................. 4 Creating Table Type Z_ZZFILI ........................................................................................................................ 7 Creating Function Module Z_GET_DIR_LIST ................................................................................................ 9
Source Code Function Module................................................................................................................................... 13 Creating Program Z0I005........................................................................................................................................... 16 Creating Include Z0I005_TOP ................................................................................................................................... 17 Creating Include Z0I005_SELECTION ...................................................................................................................... 18 Creating Include Z0I005_FORMS .............................................................................................................................. 18 Some Points Regarding Codes .................................................................................................................................. 26 Creating Text Element and Selection Text Elements ................................................................................................. 28
Salient Features
Following are some salient points regarding Program will be reusable (i.e. independent of projects/generic). Program will accept local path, Remote path, User Id, password etc. Program will also have an option for file stem field which will let the user choose which files to send/receive I.e. ASD* will pick files starting with ASD only. Can be integrated in process chains using a variant. Variant need not be changed when transport happens as Program takes care of the path on whatever system it is. Following screenshot shows various parameters.
Steps to Create The Program works on the principle that once we open a FTP connection using standard SAP provided Function Modules we can create the sequence of commands to execute to our effect. Following are the steps to create the solution: 1. Create structure ZZFILI (is used for providing a structure to organize file data). 2. Create table type Z_ZZFILI. 3. Create Function Module Z_GET_DIR_LIST (is used to read the files available in the directory) 4. Create ABAP Program Z0I005. 5. Create Includes Z0I005_TOP, Z0I005_FORMS, Z0I005_SELECTION. 6. Create Text elements and selection text elements. 7. Create Messages.
Create Structure ZZFILI 1. Create data element ZNAME (Char 1024) description: File Name Go to transaction code SE11 and choose data type type the name ZNAME and press create. When asked for type choose data element
Save and Activate. Similarly create ZSIZE (INT4) Description Size screenshots below. and ZMASK (Char 40) Description: File Mask. See
After creating data elements Structure ZZFILI (List of Files) needs to be created. Go to Transaction code SE11 choose data type and type ZZFILI and press create, when asked for type choose structure. Make following entries.
Choose the enhancement category from (ExtrasEnhancement category) Can not be enhanced. Save and activate.
Creating Table Type Z_ZZFILI For ECC6.0 and above it is not possible to give TABLES parameters so the solution requires a table type in the function module Z_GET_DIR_LIST and Z_MOVE_FILES. Steps to create table type Z_ZZFILI. 1. Go to Transaction code SE11. 2. Select data type and type Z_ZZFILI. 3. Press create. 4. Select type as table type. 5. Give description and line type as ZZFILI. 6. Follow the screen shots.
Creating Function Module Z_GET_DIR_LIST For creating function module we will need a function group (can be created new or can be existing, but it is better to create separate function groups for function module whose functionalities are different.) 1. We will create a function group ZSCG. 2. Go to transaction code SE80. 3. Choose Function group from drop down box. 4. Type the name ZSCG and press enter. Follow the screenshots.
2. Import parameters.
3. Export parameters.
4. Changing parameters
5. Exceptions
6.
Source Code Function Module FUNCTION Z_GET_DIR_LIST. *"---------------------------------------------------------------------*"*"Local Interface: *" IMPORTING *" REFERENCE(FILE_NAME) TYPE ZZFILI-ZNAME *" REFERENCE(FILE_MASK) TYPE ZZFILI-ZMASK *" EXPORTING *" REFERENCE(RETURN_CODE) TYPE SY-SUBRC *" CHANGING *" REFERENCE(LIST) TYPE Z_ZZFILI *" EXCEPTIONS *" LIST_ERROR *" FILE_NAME_TOO_LONG *"----------------------------------------------------------------------
" name of directory. (possibly " truncated.) type name_of_file, " name of entry. (possibly " truncated.) type c, " type of entry. type p, " length in bytes. type c, " owner of the entry. type p, " last modification date, seconds since 1970 type c, " like "rwx-r-x--x": protection mode.
useable(1) subrc(4) errno(3) errmsg(40) mod_date mod_time(8) seen(1) changed(1) end of file.
c, c, c, c,
d, c, c, c,
" hh:mm:ss
data: begin of file_list occurs 100, dirname type name_of_dir, " name of directory. (possibly " truncated.) name type name_of_file, " name of entry. (possibly " truncated.) type(10) type c, " type of entry. len(8) type p, " length in bytes. owner(8) type c, " owner of the entry. mtime(6) type p, " last modification date, seconds since 1970 mode(9) type c, " like "rwx-r-x--x": protection mode. useable(1) type c, subrc(4) type c, errno(3) type c, errmsg(40) type c, mod_date type d, mod_time(8) type c, " hh:mm:ss seen(1) type c, changed(1) type c, end of file_list. data: errcnt(2) type p value 0. data: a_dir_name type name_of_dir, " name of directory. a_generic_name type name_of_file." name of entry. (may end with *) data wa_list like line of list. parameters: p_dir type name_of_dir lower case.
a_dir_name = file_name. a_generic_name = file_mask.
* * *
IF a_dir_name IS INITIAL. MESSAGE e220. " 'Place cursor on valid line !'. ENDIF.
call 'C_DIR_READ_FINISH' " just to be sure id 'ERRNO' field file_list-errno id 'ERRMSG' field file_list-errmsg. call 'C_DIR_READ_START' id 'DIR' field a_dir_name id 'FILE' field a_generic_name id 'ERRNO' field file-errno id 'ERRMSG' field file-errmsg.
if sy-subrc <> 0. sy-subrc = 4. raise list_error. endif. do. clear file. call 'C_DIR_READ_NEXT' id 'TYPE' field file-type id 'NAME' field file-name id 'LEN' field file-len id 'OWNER' field file-owner id 'MTIME' field file-mtime id 'MODE' field file-mode id 'ERRNO' field file-errno id 'ERRMSG' field file-errmsg.
file-dirname = a_dir_name. move sy-subrc to file-subrc. case sy-subrc. when 0. when 1. " end of directory exit. when 4. " filename too long raise list_error. when others. raise file_name_too_long. endcase. if file-type = text-001. move-corresponding file to file_list. append file_list. endif. enddo.
call 'C_DIR_READ_FINISH' id 'ERRNO' field file_list-errno id 'ERRMSG' field file_list-errmsg. if sy-subrc <> 0. write: / 'C_DIR_READ_FINISH', 'SUBRC', sy-subrc. endif. sy-subrc = 0. sort file_list by name. loop at file_list. move file_list-name to wa_list-zname. append wa_list to list. * WRITE : / FILE_LIST-NAME. endloop.
ENDFUNCTION.
Creating Program Z0I005 To create program follow the steps. 1. Go to transaction Code SE80. 2. Select Program from drop down box. 3. Type the name as Z0I005. 4. Hit Enter. Give following properties. These can be specific to the project.
if psend eq 'X'.
if v_no_files_found ne c_x. perform send_files. if v_subrc eq 0. message i018. endif. endif. else. "Use Program to receive files PERFORM check_local_path. PERFORM retrieve_files. endif. b) Now Do Right ClickCreateInclude g) Give the name of include as Z0I005_top. Similarly create 2 more includes as Z0I005_selection, Z0I005_forms. Creating Include Z0I005_TOP Add following code *&---------------------------------------------------------------------* *& Include Z0I005_TOP *&---------------------------------------------------------------------* types: begin of ty_text, line(255) type c, end of ty_text. types: types:
ty_move_results type btcxpm.
constants: c_navgl(6) type c value 'ABC*', c_asterisk(1) type c value '*', c_x(1) type c value 'X'. data: it_result type table of ty_text, "FTP results table it_commands type table of ty_text, "FTP commands it_list type table of zzfili, "list of files in a directory it_move_results type table of ty_move_results. "results of moving file like line of it_result, wa_command like line of it_commands, wa_list like line of it_list, wa_move_results like line of it_move_results. type type type type type i, i, i value 26101957, "Encryption key c, i,
data: wa_result
data: v_handle
v_command_index v_key v_encrypted_pwd(80) v_slen
v_filename v_source_dir v_dest_dir v_subrc v_no_files_found v_files_found v_file v_lines v_stem v_loop
type type type like type type type type type type
constants:
c_rfc_destination type rfcdes-rfcdest value 'SAPFTPA'.
parameter: pstem
type zzfili-zmask lower case obligatory default c_navgl, plpath type zzfili-zname lower case obligatory, puser(40) type c lower case obligatory, ppwd(40) type c lower case obligatory, phost(70) type c lower case obligatory, prpath(70) type c lower case obligatory, pasc radiobutton group r1 default 'X', pbin radiobutton group r1.
*----------------------------------------------------------------------at selection-screen output. *----------------------------------------------------------------------* Scramble Password field on screen loop at screen. if screen-name = 'PPWD'. screen-invisible = '1'. modify screen. endif. endloop.
*&---------------------------------------------------------------------* *& Include Z0I005_FORMS *&---------------------------------------------------------------------* form check_local_path . * check whether local directory to send data from exists * and raise an error if it does not or if it is not accessible * due to permissions.
v_filename = pstem. condense v_filename no-gaps. v_source_dir = plpath. condense v_source_dir no-gaps. v_dest_dir = prpath. condense v_dest_dir no-gaps. perform check_directory using v_source_dir.
endform. " CHECK_LOCAL_PATH *&---------------------------------------------------------------------* *& Form CHECK_DIRECTORY *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->P_V_SOURCE_DIR text *----------------------------------------------------------------------* form check_directory using p_v_source_dir. * check whether a directory exists and error if it does not or is not * accessible data: l_source_dir type btch0000-text80.
l_source_dir = p_v_source_dir.
FILNAME exceptions
pfl_dir_not_exist pfl_permission_denied pfl_cant_build_dataset_name pfl_file_not_exist
= ' '
= 1 = 2 = 3 = 4 = 5.
message e014. else. write: / 'Unspecified error checking local directory on SAP Server:'(016), / l_source_dir. message e015. endif. endif. endform. " CHECK_DIRECTORY *&---------------------------------------------------------------------* *& Form CHECK_FOR_FILES *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* form check_for_files . * check if files exist * read files in directory refresh it_list. call function 'Z_GET_DIR_LIST' exporting
file_name file_mask = plpath = pstem = it_list
changing
list
exceptions
list_error = 1 file_name_too_long = 2. v_subrc = sy-subrc.
if pstem(1) eq c_asterisk and pstem(2) is not initial. move pstem to v_stem. replace all occurrences of c_asterisk in v_stem with space. condense v_stem no-gaps. loop at it_list into wa_list where zname ns v_stem. delete it_list. endloop. endif.
write: /'No files have been found in SAP server directory:'(005), /'File stem:'(006), pstem, /'SAP Server file path:'(007), plpath. message i005. else. write: /'Error reading SAP server local directory:'(031), /'SAP Server file path:'(007), plpath. message e019 with v_subrc. endif. else. loop at it_list into wa_list. write: /10 wa_list-zname. endloop. endif. skip 2. endform. form send_files . * connect to the FTP server and send the files. * Calculate password length v_slen = strlen( ppwd ). * Encrypt password call function 'HTTP_SCRAMBLE' exporting
source sourcelen = ppwd = v_slen = v_key
" CHECK_FOR_FILES
key
importing
destination = v_encrypted_pwd.
importing
handle = v_handle
exceptions
not_connected.
if sy-subrc <> 0. message e002 with phost sy-subrc. endif. refresh it_result. refresh it_commands. * change the directory on the destination machine concatenate 'cd' prpath into wa_command-line separated by space. append wa_command to it_commands. * Change the local directory on the sap server concatenate 'lcd' plpath into wa_command-line separated by space. append wa_command to it_commands. * Set Ascii mode clear wa_command-line. if pbin eq 'X'. move 'bin' to wa_command-line. else. move 'asc' to wa_command-line. endif. append wa_command to it_commands. * files to be transferred loop at it_list into wa_list. * Put the file from the sap server to the destination machine concatenate 'put' wa_list-zname wa_list-zname into wa_command-line separated by space. append wa_command to it_commands. endloop. * Send FTP commands to server call function 'FTP_COMMAND_LIST' exporting
handle = v_handle
importing
command_index = v_command_index
tables data
= it_result
commands
= it_commands
exceptions
command_error = 1 tcpip_error = 2. v_subrc = sy-subrc.
* write results of FTP and error if an error occurred. write: /'Messages generated by FTP Send to remote server:'(009),
phost, /'Directory:'(011), prpath.
skip 1. ** For each FTP command result line loop at it_result into wa_result. write: /10 wa_result. endloop. skip 2. if v_subrc ne 0. * if there is an error disconnect from the server * and display an appropriate message perform ftp_disconnect using v_handle c_rfc_destination. message e004. endif. endform. " SEND_FILES
*&--------------------------------------------------------------------* *& Form ftp_disconnect *&--------------------------------------------------------------------* * text *---------------------------------------------------------------------* form ftp_disconnect using
in_handle in_rfc_destination.
= 1.
"ftp_disconnect
FORM RETRIEVE_FILES . * connect to the FTP server and retrieve the files. * Calculate password length V_SLEN = STRLEN( PPWD ). * Encrypt password CALL FUNCTION 'HTTP_SCRAMBLE' EXPORTING
SOURCE SOURCELEN = PPWD = V_SLEN = V_KEY
KEY IMPORTING
DESTINATION = V_ENCRYPTED_PWD.
IMPORTING
HANDLE = V_HANDLE
EXCEPTIONS
NOT_CONNECTED.
IF SY-SUBRC <> 0. MESSAGE E002 WITH PHOST SY-SUBRC. ENDIF. REFRESH IT_RESULT. REFRESH IT_COMMANDS. * Change the directory on the destination machine CONCATENATE 'cd' PRPATH INTO WA_COMMAND-LINE SEPARATED BY SPACE. APPEND WA_COMMAND TO IT_COMMANDS. * Change the local directory on the sap server CONCATENATE 'lcd' PLPATH INTO WA_COMMAND-LINE SEPARATED BY SPACE. APPEND WA_COMMAND TO IT_COMMANDS.
* get files from remote server CONCATENATE 'mget' PSTEM INTO WA_COMMAND-LINE SEPARATED BY SPACE. APPEND WA_COMMAND TO IT_COMMANDS. * Send FTP commands to server CALL FUNCTION 'FTP_COMMAND_LIST' EXPORTING
HANDLE = V_HANDLE
IMPORTING
COMMAND_INDEX = V_COMMAND_INDEX
TABLES DATA
COMMANDS
= IT_RESULT = IT_COMMANDS
EXCEPTIONS
COMMAND_ERROR = 1 TCPIP_ERROR = 2. V_SUBRC = SY-SUBRC.
CLEAR V_NO_FILES_FOUND. CLEAR V_FILES_FOUND. * write results of FTP and error if an error occurred. * not finding files to retrieve is not an error, but will be reported. WRITE: /'Messages generated by FTP Retrieval from remote server:'(009),
PHOST, /'Directory:'(011), PRPATH.
SKIP 1. ** For each FTP command result line LOOP AT IT_RESULT INTO WA_RESULT. WRITE: /10 WA_RESULT. * * * check for no files returned from AIX server return code is 1, so look for error message to distinguish from genuine error IF WA_RESULT-LINE EQ TEXT-003.
V_NO_FILES_FOUND = C_X. V_LOOP = 'Y'.
ENDIF. * * check for files returned from NT server return code is 0, so check for existence of
ENDIF.
SKIP 2. IF V_SUBRC NE 0 OR ( V_SUBRC EQ 0 AND V_FILES_FOUND IS INITIAL ). * if there is an error or there are no files disconnect from the server * and display an appropriate message PERFORM FTP_DISCONNECT USING V_HANDLE C_RFC_DESTINATION. IF V_NO_FILES_FOUND EQ C_X OR ( V_SUBRC EQ 0 AND V_FILES_FOUND IS INITIAL ). WRITE: /'No files have been found on remote server. File Stem:'(004),
PSTEM.
"D01K910515
Some Points Regarding Codes 1) The sequence of commands used for sending files is following a) CD <Remote path> (changes directory on server to desired one.) b) LCD <Local Path> (changes local directory) c) ASC or BIN (To set the transfer mode) d) PUT <FILE NAME1> (sends file from local machine to remote machine) e) PUT <FILE NAME2> f)
2) The sequence of commands used for sending files is following a) CD <Remote path> (changes directory on server to desired one.) b) LCD <Local Path> (changes local directory) c) MGET <FILENAME>* (gets all the files specified by wild card e.g. ABC*) Based on the operating systems in concern both at local and remote server these commands need to be tweaked (In given coding UNIX commands are used as most of the times servers are run on UNIX. Though same FTP commands are used in NT servers as well but need to be sure). If commands need to be modified these are the places to do it.
concatenate 'cd' prpath into wa_commandline separated by space. append wa_command to it_commands.
* files to be transferred
clear wa_command-line. if pbin eq 'X'. move 'bin' to wa_command-line. else. move 'asc' to wa_command-line. endif. append wa_command to it_commands. loop at it_list into wa_list.
* Put the file from the sap server to the destination machine
concatenate 'put' wa_list-zname wa_list-zname into wa_commandline separated by space. append wa_command to it_commands. endloop.
CONCATENATE 'mget' PSTEM INTO WA_COMMANDLINE SEPARATED BY SPACE. APPEND WA_COMMAND TO IT_COMMANDS.
Creating Text Element and Selection Text Elements To Create Text Elements for the program do GoToText ElementsText Symbols Create following text symbols.
Create messages. For creating messages do Go ToMessages. Give attributes and messages as shown.
Related Content
http://wiki.sdn.sap.com/wiki/display/Snippets/ABAP+solution+to+implement+FTP+transactions
http://www.columbia.edu/acis/eds/data_tools/ftp-man/ftp_com.html