* _ _ _ _ _ * /_\ | |__ __ _ _ __ ___ __ _ __| | __ _| |__ _ __ /_\ * //_\\| '_ \ / _` | '_ \ / __/ _` |/ _` |/ _` | '_ \| '__//_\\ * / _ \ |_) | (_| | |_) | (_| (_| | (_| | (_| | |_) | | / _ \ * \_/ \_/_.__/ \__,_| .__/ \___\__,_|\__,_|\__,_|_.__/|_| \_/ \_/ * |_| www.abapcadabra.com *---------------------------------------------------------------------------- * ____ _ _ _ _ _ * | __ ) _ _| |_| |_ ___ _ __ | (_)_ __ | | _____ Assistance programs * | _ \| | | | __| __/ _ \| '_ \ | | | '_ \| |/ / __| to be called from * | |_) | |_| | |_| || (_) | | | | | | | | | | <\__ \ your report selection * |____/ \__,_|\__|\__\___/|_| |_| |_|_|_| |_|_|\_\___/ screen: BLINKS ! * * AbapcadabrA Button Links: an AbapcadabrA trade mark product - FREE DOWNLOAD * Turn-key and ready to use functionality that can be made available * from a button on the selection screen of your report. There are a variety * of Button-link reports and this is one of them. * Find out MORE on AbapcadabrA.com - Search for "Button links" * * program : ZABAPCADABRA_BLINK_SERVERFILES * title : Files on server * Listing of the files on a server location * functional area : Cross modules * environment : 4.7 * program Function : This ALV report lists all files (and optionally directories) * on a given server location. * It can be used as "additional information" from the selection * screen of inbound or outbound interface reports, to allow a * quick peek of files that have been produced or files that should * be ready to be processed. * Documentation : Search for "list serverfiles" on AbapcadabrA.com * Previous version : This is the initial version * Developer name : Wim Maasdam * Development date : 27/09/2017 * Version : 0.1 *--------------------------------------------------------------------- * Change list: * Date Description * 27/09/2017 Initial release * 01/03/2018 Directories should have no length/size * 22/03/2018 Large files - calculate size in alternate way *--------------------------------------------------------------------- REPORT zabapcadabra_blink_serverfiles. CLASS lcl_event_manager DEFINITION FINAL. PUBLIC SECTION. METHODS: constructor IMPORTING r_object TYPE REF TO cl_salv_table, on_link_click FOR EVENT link_click OF cl_salv_events_table IMPORTING row column. PRIVATE SECTION. DATA: go_salv TYPE REF TO cl_salv_table. ENDCLASS. "lcl_event_manager DEFINITION class lcl_controller DEFINITION FINAL. PUBLIC SECTION. CONSTANTS: co_all(1) TYPE c VALUE 'A', co_directories_only(1) TYPE c VALUE 'D', co_files_only(1) TYPE c VALUE 'F'. TYPES: begin of ty_ooi, "Object Of Interest, a file or directory name type c length 75, directory type boolean, length type p length 4 decimals 0, owner type c length 20, change_date type d, change_time type t, rights type c length 12, end of ty_ooi, BEGIN OF ty_dir_entry, name(75), " name of entry type(15), " type of entry len(4) TYPE p DECIMALS 0, " length in bytes owner(8), " owner of the entry mtime(6) TYPE p DECIMALS 0, " last mod. date, seconds since 1970 mode(9), " like "rwx-r-x--x": protection mode. subrc(4), errno(3), errmsg(40), len8(8) type p decimals 0, END OF ty_dir_entry, ty_dir_entry_tt TYPE STANDARD TABLE OF ty_dir_entry. CLASS-DATA: gt_UNIX_listing type ty_dir_entry_tt, gt_listing type standard table of ty_ooi, go_salv TYPE REF TO CL_SALV_TABLE, go_event_man TYPE REF TO lcl_event_manager, gv_serverpath type c length 200, gv_filemask type c length 60. CLASS-METHODS: get_directory_listing IMPORTING directory TYPE any file TYPE any filter TYPE c DEFAULT 'A' "A=All, D=Directory only, F=File only EXPORTING listing TYPE ty_dir_entry_tt returncode TYPE sy-subrc, unix_rights_to_str importing mode type any returning value(rights) type char20, prepare_listing importing include_directories type boolean, prepare_ALV importing include_directories type boolean. endclass. CLASS lcl_event_manager IMPLEMENTATION. METHOD constructor. DATA: lo_events TYPE REF TO cl_salv_events_table. go_salv = r_object. lo_events = go_salv->get_event( ). SET HANDLER on_link_click FOR lo_events. ENDMETHOD. "constructor METHOD on_link_click. data: lw_listing type lcl_controller=>ty_ooi, lv_newpath type string, lv_fullname type dirname_al11, lv_dirname type dirname_al11, lv_filename type filename_al11. case column. when 'NAME'. read table lcl_controller=>gt_listing into lw_listing index row. if sy-subrc = 0. * A directory ? Spawn off a new session: if lw_listing-directory = abap_true. concatenate lcl_controller=>gv_serverpath lw_listing-name into lv_newpath. submit ZABAPCADABRA_BLINK_SERVERFILES with pa_fpath = lv_newpath with pa_fmask = lcl_controller=>gv_filemask with pa_BLINK = abap_true and return. else. * A file ? Preview it, the way AL11 does this lv_dirname = lcl_controller=>gv_serverpath. lv_filename = lw_listing-name. concatenate lcl_controller=>gv_serverpath lw_listing-name into lv_fullname. *-------------------------------------------------------------------- export p1 = lv_fullname p2 = lv_dirname p3 = lv_filename to memory id 'RSWATCH0'. submit RSWATCH0 and return. *-------------------------------------------------------------------- endif. endif. endcase. ENDMETHOD. "on_link_click ENDCLASS. "lcl_event_manager IMPLEMENTATION class lcl_controller IMPLEMENTATION. * || _ _ _ * Class : LCL_CONTROLLER || _ __ ___ ___| |_| |__ ___ __| | * Method: GET_DIRECTORY_LISTING || | '_ ` _ \ / _ | __| '_ \ / _ \ / _` | * || | | | | | | __| |_| | | | (_) | (_| | * || |_| |_| |_|\___|\__|_| |_|\___/ \__,_| METHOD get_directory_listing. *---------------------------------------------------------------------- DATA: lw_dir_entry TYPE ty_dir_entry, lv_directory TYPE c length 200, lv_file TYPE c length 200, lv_long_file_name type EPS2FILNAM, lv_long_dir_path type EPS2PATH. CLEAR: listing[]. returncode = 4. "Default assumption: if we don't make it to the end - it's an error CALL 'C_DIR_READ_FINISH' ID 'ERRNO' FIELD lw_dir_entry-errno ID 'ERRMSG' FIELD lw_dir_entry-errmsg. lv_directory = directory. lv_file = file. * Position the read in the directory we want CALL 'C_DIR_READ_START' ID 'DIR' FIELD lv_directory ID 'FILE' FIELD lv_file ID 'ERRNO' FIELD lw_dir_entry-errno ID 'ERRMSG' FIELD lw_dir_entry-errmsg. CHECK lw_dir_entry-errno IS INITIAL. * Find the files DO. CLEAR lw_dir_entry. CALL 'C_DIR_READ_NEXT' ID 'TYPE' FIELD lw_dir_entry-type ID 'NAME' FIELD lw_dir_entry-name ID 'LEN' FIELD lw_dir_entry-len ID 'OWNER' FIELD lw_dir_entry-owner ID 'MTIME' FIELD lw_dir_entry-mtime ID 'MODE' FIELD lw_dir_entry-mode ID 'ERRNO' FIELD lw_dir_entry-errno ID 'ERRMSG' FIELD lw_dir_entry-errmsg. IF sy-subrc = 1. EXIT. "End of the listing has been reached ELSEIF sy-subrc = 3. "RC=3 File too big to fit in v_file-len CONTINUE. ELSEIF lw_dir_entry-name IS INITIAL. CONTINUE. ENDIF. * The file size: captured in P(4) if possible, otherwise there is a second attempt to * determine the filesize: if lw_dir_entry-len = 1. lv_long_file_name = lw_dir_entry-name. lv_long_dir_path = lv_directory. CALL FUNCTION 'EPS_GET_FILE_ATTRIBUTES' EXPORTING IV_LONG_FILE_NAME = lv_long_file_name IV_LONG_DIR_NAME = lv_long_dir_path IMPORTING FILE_SIZE_LONG = lw_dir_entry-len8 EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0. lw_dir_entry-len8 = lw_dir_entry-len. lw_dir_entry-errmsg = 'Size undetermined (!)'. ENDIF. else. lw_dir_entry-len8 = lw_dir_entry-len. endif. * Check the type against the filter settings: IF ( filter = co_directories_only AND lw_dir_entry-type(3) = 'dir' AND lw_dir_entry-name <> '.' AND lw_dir_entry-name <> '..' ) OR ( filter = co_files_only AND lw_dir_entry-type(4) = 'file' ) OR ( filter = co_all ). APPEND lw_dir_entry TO listing. ENDIF. ENDDO. CALL 'C_DIR_READ_FINISH' ID 'ERRNO' FIELD lw_dir_entry-errno ID 'ERRMSG' FIELD lw_dir_entry-errmsg. CHECK lw_dir_entry-errno IS INITIAL. returncode = 0. ENDMETHOD. "get_directory_UNIX_listing METHOD unix_rights_to_str. data: lv_group_rights type c length 3. define convert_mode. case &1. when '0'. lv_group_rights = '---'. when '1'. lv_group_rights = '--x'. when '2'. lv_group_rights = '-w-'. when '3'. lv_group_rights = '-wx'. when '4'. lv_group_rights = 'r--'. when '5'. lv_group_rights = 'r-x'. when '6'. lv_group_rights = 'rw-'. when '7'. lv_group_rights = 'rwx'. endcase. end-of-definition. check strlen( mode ) = 3. convert_mode mode(1). rights = lv_group_rights. convert_mode mode+1(1). concatenate rights lv_group_rights into rights SEPARATED BY space. convert_mode mode+2(1). concatenate rights lv_group_rights into rights SEPARATED BY space. ENDMETHOD. METHOD prepare_listing. data: lw_UNIX_listing type ty_dir_entry, lw_listing type ty_ooi, lv_time type c length 8. clear gt_LISTING[]. loop at gt_UNIX_listing into lw_UNIX_listing. clear: lw_listing. lw_listing-name = lw_UNIX_listing-name. if lw_UNIX_listing-type = 'directory file'. lw_listing-directory = abap_true. if include_directories = abap_false. continue. endif. else. lw_listing-length = lw_UNIX_listing-len. endif. lw_listing-owner = lw_UNIX_listing-owner. * Get an AL11 routine (form pool) to convert seconds since 1970 into a date and time: perform p6_to_date_time_tz in program rstr0400 using lw_UNIX_listing-mtime lv_time lw_listing-change_date. replace ALL OCCURRENCES OF ':' IN lv_time WITH ''. move lv_time to lw_listing-change_time. lw_listing-rights = unix_rights_to_str( lw_UNIX_listing-mode ). append lw_listing to gt_listing. endloop. sort gt_listing by name. ENDMETHOD. METHOD prepare_ALV. DATA: lo_rf_display_settings TYPE REF TO cl_salv_display_settings, lo_rf_columns_table TYPE REF TO cl_salv_columns_table, lo_rf_functions_list TYPE REF TO cl_salv_functions_list, lo_rf_layout TYPE REF TO cl_salv_layout, lw_layout_key TYPE salv_s_layout_key, lo_rf_column_table TYPE REF TO cl_salv_column_table, lv_scrtext_s TYPE scrtext_s, lv_scrtext_m TYPE scrtext_m, lv_scrtext_l TYPE scrtext_l, lv_columnname TYPE LVC_FNAME, * The header box lo_rf_alv_header TYPE REF TO cl_salv_form_layout_grid. DEFINE alv_field. try. lv_columnname = &1. lo_rf_column_table ?= lo_rf_columns_table->get_column( lv_columnname ). case &2. when 'HIDE'. lo_rf_column_table->set_visible( abap_false ). when 'HOT'. lo_rf_column_table->set_cell_type( if_salv_c_cell_type=>hotspot ). when 'CHECKBOX'. lo_rf_column_table->set_cell_type( if_salv_c_cell_type=>checkbox ). when 'UNAVAILABLE'. lo_rf_column_table->set_technical( abap_true ). when others. lv_scrtext_s = lv_scrtext_m = lv_scrtext_l = &2. lo_rf_column_table->set_short_text( lv_scrtext_s ). lo_rf_column_table->set_medium_text( lv_scrtext_m ). lo_rf_column_table->set_long_text( lv_scrtext_l ). endcase. catch cx_salv_not_found cx_salv_data_error ##NO_HANDLER. endtry. END-OF-DEFINITION. TRY. cl_salv_table=>factory( IMPORTING r_salv_table = go_salv CHANGING t_table = gt_listing ). CATCH cx_salv_msg ##NO_HANDLER. * No action here. ENDTRY. lo_rf_display_settings = go_salv->get_display_settings( ). lo_rf_display_settings->set_striped_pattern( abap_true ). lo_rf_columns_table = go_salv->get_columns( ). lo_rf_columns_table->set_optimize( abap_true ). lo_rf_functions_list = go_salv->get_functions( ). lo_rf_functions_list->set_all( ). * Layout's are available for the end user to control lo_rf_layout = go_salv->get_layout( ). lw_layout_key-report = sy-cprog. lw_layout_key-logical_group = 'ABRA'. * The key for layouts needs to be set to enable it's functionality. lo_rf_layout->set_key( lw_layout_key ). lo_rf_layout->set_default( abap_true ). lo_rf_layout->set_save_restriction( if_salv_c_layout=>restrict_none ). * Header box: CREATE OBJECT lo_rf_alv_header. lo_rf_alv_header->create_text( text = '[LOCATION]' row = 1 column = 1 ). lo_rf_alv_header->create_text( text = '' row = 1 column = 2 ). lo_rf_alv_header->create_text( text = gv_serverpath row = 1 column = 3 ). lo_rf_alv_header->create_text( text = '' row = 1 column = 4 ). lo_rf_alv_header->create_text( text = '[MASK]' row = 1 column = 5 ). lo_rf_alv_header->create_text( text = '' row = 1 column = 6 ). lo_rf_alv_header->create_text( text = gv_filemask row = 1 column = 7 ). go_salv->set_top_of_list( lo_rf_alv_header ). go_salv->set_top_of_list_print( lo_rf_alv_header ). * Field specifics: alv_field: 'NAME' 'Name', 'NAME' 'HOT', 'DIRECTORY' 'Directory', 'DIRECTORY' 'CHECKBOX', 'LENGTH' 'Size', 'OWNER' 'Owner', 'CHANGE_DATE' 'Changed on', 'CHANGE_TIME' 'At', 'RIGHTS' 'Rights'. if include_directories = abap_false. alv_field: 'DIRECTORY' 'HIDE'. endif. ENDMETHOD. ENDCLASS. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT (20) lbl_01 FOR FIELD pa_fpath. PARAMETERS pa_fpath TYPE STRING lower case. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 22(10) lbl_02. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT (20) lbl_03 FOR FIELD pa_lfile. PARAMETERS pa_lfile TYPE FILENAME-FILEINTERN. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT (20) lbl_04 FOR FIELD pa_para1. PARAMETERS pa_para1 TYPE c length 30 VISIBLE LENGTH 14. PARAMETERS pa_para2 TYPE c length 30 VISIBLE LENGTH 14. PARAMETERS pa_para3 TYPE c length 30 VISIBLE LENGTH 14. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN skip. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT (20) lbl_05 FOR FIELD pa_fmask. PARAMETERS pa_fmask TYPE c length 20 lower case DEFAULT '*'. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN: BEGIN OF LINE, position 22. PARAMETERS pa_direc as checkbox default abap_true. SELECTION-SCREEN COMMENT 26(20) lbl_06 FOR FIELD pa_direc. SELECTION-SCREEN END OF LINE. * When you call this report with a Submit - make sure you fill in pa_BLINK with 'X'. PARAMETERS pa_BLINK type c length 1 default space NO-DISPLAY. INITIALIZATION. lbl_01 = 'Server path'. lbl_02 = 'or'. lbl_03 = 'Logical filename'. lbl_04 = '... , 2>,3>'. lbl_05 = 'File mask'. lbl_06 = 'Include directories'. START-OF-SELECTION. if not pa_fpath is initial. "Server path filled ? data: lv_lastpos type sy-fdpos, lv_lastchar type c length 1. lcl_controller=>gv_serverpath = pa_fpath. lcl_controller=>gv_filemask = pa_fmask. * The server path should end with a / (Unix) if sy-opsys = 'AIX' or sy-opsys = 'Linux'. lv_lastpos = strlen( lcl_controller=>gv_serverpath ) - 1. lv_lastchar = lcl_controller=>gv_serverpath+lv_lastpos(1). if lv_lastchar <> '/'. concatenate lcl_controller=>gv_serverpath '/' into lcl_controller=>gv_serverpath. endif. endif. lcl_controller=>get_directory_listing( exporting directory = lcl_controller=>gv_serverpath file = lcl_controller=>gv_filemask importing listing = lcl_controller=>gt_UNIX_listing ). elseif not pa_lfile is initial. data: lv_filename type string, lv_offsetter type sy-fdpos. CALL FUNCTION 'FILE_GET_NAME' EXPORTING LOGICAL_FILENAME = pa_lfile PARAMETER_1 = pa_para1 PARAMETER_2 = pa_para2 PARAMETER_3 = pa_para3 IMPORTING FILE_NAME = lcl_controller=>gv_serverpath EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0. Message 'Invalid logical path' type 'S'. leave program. ELSE. * We have not just the path, but the filename as well. Remove filename to get the path: CALL FUNCTION 'FILE_GET_NAME_AND_LOGICAL_PATH' EXPORTING LOGICAL_FILENAME = pa_lfile IMPORTING FILE_NAME = lv_filename EXCEPTIONS OTHERS = 0. * Cut the length of lv_filename off from the end of lcl_controller=>gv_serverpath lv_offsetter = strlen( lcl_controller=>gv_serverpath ) - strlen( lv_filename ). if lv_offsetter > 0. lcl_controller=>gv_serverpath = lcl_controller=>gv_serverpath(lv_offsetter). else. clear lcl_controller=>gv_serverpath. endif. lcl_controller=>gv_filemask = pa_fmask. lcl_controller=>get_directory_listing( exporting directory = lcl_controller=>gv_serverpath file = lcl_controller=>gv_filemask importing listing = lcl_controller=>gt_UNIX_listing ). ENDIF. endif. lcl_controller=>prepare_listing( pa_direc ). lcl_controller=>prepare_ALV( pa_direc ). if lcl_controller=>gt_listing[] is initial. message 'No files found on the server location' type 'S'. else. * Involve the events manager CREATE OBJECT lcl_controller=>go_event_man EXPORTING r_object = lcl_controller=>go_salv. * Output the report as ALV lcl_controller=>go_salv->display( ). endif. if pa_BLINK = abap_true. * Leave the program - we explicitly don't want to go back to the selection * screen as this report is to be called from the selection screen of other * reports. leave program. endif.