REPORT z_find_where_rfc_is_called. CLASS lcl_salv_event_handler DEFINITION DEFERRED. TYPES BEGIN OF gts_rfc. TYPES name TYPE rs38l_fnam. TYPES vaild TYPE boolean. TYPES END OF gts_rfc. TYPES BEGIN OF gts_display. TYPES rfc_fm TYPE cross-name. TYPES include TYPE cross-include. TYPES line_num TYPE i. TYPES END OF gts_display. TYPES gtt_display TYPE STANDARD TABLE OF gts_display. CONSTANTS gc_not_found TYPE string VALUE 'Not Found'. CONSTANTS gc_rfc_error TYPE string VALUE 'RFC Error'. DATA gv_fm_name TYPE rs38l-name. DATA gt_fm_range LIKE RANGE OF gv_fm_name. * DATA gt_cross TYPE TABLE OF cross. DATA gs_cross TYPE cross * DATA gt_rfc TYPE TABLE OF gts_rfc. DATA gs_rfc TYPE gts_rfc. DATA gt_rfc_temp TYPE TABLE OF gts_rfc. * DATA gt_tfdir TYPE TABLE OF tfdir. DATA gt_tfdir_temp TYPE TABLE OF tfdir. * DATA gt_display TYPE gtt_display. DATA gs_display TYPE gts_display. * DATA go_salv_table TYPE REF TO cl_salv_table. DATA go_salv_events_table TYPE REF TO cl_salv_events_table. DATA go_salv_functions_list TYPE REF TO cl_salv_functions_list. DATA go_salv_display_settings TYPE REF TO cl_salv_display_settings. DATA go_salv_columns_table TYPE REF TO cl_salv_columns_table. DATA go_salv_column TYPE REF TO cl_salv_column. * DATA go_salv_event_handler TYPE REF TO lcl_salv_event_handler. * DATA gv_remote_call TYPE rs38l-remote. DATA gv_total_records TYPE i. DATA gv_alv_title TYPE lvc_title. FIELD-SYMBOLS TYPE gts_rfc.   CLASS lcl_salv_event_handler DEFINITION. PUBLIC SECTION. METHODS on_double_click FOR EVENT double_click OF cl_salv_events_table IMPORTING row. ENDCLASS. "lcl_salv_event_handler DEFINITION * CLASS lcl_salv_event_handler IMPLEMENTATION. METHOD on_double_click. FIELD-SYMBOLS TYPE gts_display. * Read the row READ TABLE gt_display ASSIGNING INDEX row. IF sy-subrc EQ 0. IF -include EQ gc_not_found OR -include EQ gc_rfc_error OR -include IS INITIAL. MESSAGE i001(00) WITH 'Error finding location'. ELSE. CALL FUNCTION 'RS_TOOL_ACCESS' EXPORTING operation = 'SHOW' object_name = -include object_type = 'PROG' position = -line_num EXCEPTIONS not_executed = 1 invalid_object_type = 2 OTHERS = 3. IF sy-subrc NE 0. MESSAGE i001(00) WITH 'Error navigating to code'. ENDIF. ENDIF. ENDIF. ENDMETHOD. "on_double_click ENDCLASS. "lcl_salv_event_handler IMPLEMENTATION  SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(20) tx_1. PARAMETERS p_rfc TYPE rfcdest DEFAULT 'ECC_DEV01100'. "Replace with 'Real' System SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT (17) tx_2. SELECT-OPTIONS s_fm FOR gv_fm_name NO INTERVALS DEFAULT 'BAPI_PO_GETDETAIL'. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. PARAMETERS cb_1 AS CHECKBOX. SELECTION-SCREEN COMMENT 5(60) tx_3. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. PARAMETERS cb_2 AS CHECKBOX DEFAULT 'X'. SELECTION-SCREEN COMMENT 5(60) tx_4. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN SKIP. SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(60) tx_5. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(60) tx_6. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(60) tx_7. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(60) tx_8. SELECTION-SCREEN END OF LINE. INITIALIZATION. tx_1 = 'System of RFC'. tx_2 = 'RFC Function Name'. tx_3 = 'Exclude Function with same name'. tx_4 = 'Display only found RFC'. tx_5 = 'Insure Navigation index is up to date with Programs'. tx_6 = ' SAPRSEUB - Generate Where-Used List (All Programs)'. tx_7 = ' SAPRSEUT - Update Object List after Transport'. tx_8 = ' SAPRSLOG - Refreash Navigation indexes and Object List'.   START-OF-SELECTION. CLEAR gt_tfdir. CLEAR gt_cross. CLEAR gt_display. CLEAR gt_rfc. APPEND s_fm TO s_fm[]. SORT s_fm[]. DELETE ADJACENT DUPLICATES FROM s_fm[] COMPARING low. WHILE s_fm[] IS NOT INITIAL. PERFORM build_ranges. IF gt_fm_range IS NOT INITIAL. CLEAR gs_rfc-name. SELECT * FROM cross INTO gs_cross WHERE type = 'F' AND name IN gt_fm_range. APPEND gs_cross TO gt_cross. IF gs_rfc-name NE gs_cross-name. gs_rfc-name = gs_cross-name. APPEND gs_rfc TO gt_rfc_temp. ENDIF. ENDSELECT. IF gt_rfc_temp IS NOT INITIAL AND cb_1 IS NOT INITIAL. CLEAR gt_tfdir_temp. SELECT * FROM tfdir INTO TABLE gt_tfdir_temp FOR ALL ENTRIES IN gt_rfc_temp WHERE funcname = gt_rfc_temp-name AND fmode = 'R'. IF sy-subrc EQ 0. APPEND LINES OF gt_tfdir_temp TO gt_tfdir. ENDIF. ENDIF. APPEND LINES OF gt_rfc_temp TO gt_rfc. ENDIF. ENDWHILE. SORT gt_rfc BY name. DELETE ADJACENT DUPLICATES FROM gt_rfc COMPARING name. SORT gt_tfdir BY funcname. DELETE ADJACENT DUPLICATES FROM gt_tfdir COMPARING funcname.   LOOP AT gt_rfc ASSIGNING . gv_fm_name = -name. READ TABLE gt_tfdir TRANSPORTING NO FIELDS BINARY SEARCH WITH KEY funcname = gv_fm_name. IF sy-subrc EQ 0. -vaild = ''. CONTINUE. ENDIF. CLEAR gv_remote_call. CALL FUNCTION 'FUNCTION_IMPORT_INTERFACE' "could use FM 'RFC_FUNCTION_SEARCH' DESTINATION p_rfc EXPORTING funcname = gv_fm_name IMPORTING remote_call = gv_remote_call EXCEPTIONS error_message = 1 function_not_found = 2 invalid_name = 3 system_failure = 5 communication_failure = 6 OTHERS = 4. CASE sy-subrc. WHEN 0. IF gv_remote_call EQ 'R'. -vaild = 'X'. ELSE. -vaild = ''. IF cb_2 IS INITIAL. CLEAR gs_display. gs_display-rfc_fm = gv_fm_name. gs_display-include = gc_not_found. APPEND gs_display TO gt_display. ENDIF. ENDIF. WHEN 2. -vaild = ''. IF cb_2 IS INITIAL. CLEAR gs_display. gs_display-rfc_fm = gv_fm_name. gs_display-include = gc_not_found. APPEND gs_display TO gt_display. ENDIF. WHEN OTHERS. -vaild = ''. IF cb_2 IS INITIAL. CLEAR gs_display. gs_display-rfc_fm = gv_fm_name. gs_display-include = gc_rfc_error. APPEND gs_display TO gt_display. ENDIF. ENDCASE. ENDLOOP. SORT gt_rfc BY name. SORT gt_cross BY name. LOOP AT gt_cross INTO gs_cross. IF IS NOT ASSIGNED OR gs_cross-name NE -name. UNASSIGN . READ TABLE gt_rfc ASSIGNING BINARY SEARCH WITH KEY name = gs_cross-name. ENDIF. IF IS ASSIGNED AND -vaild EQ 'X'. PERFORM find_where_in_source USING gs_cross CHANGING gt_display. ENDIF. ENDLOOP. * Find FMs that where not found in the External system SORT gt_rfc BY name. LOOP AT s_fm. READ TABLE gt_rfc TRANSPORTING NO FIELDS WITH KEY name = s_fm-low. IF sy-subrc NE 0. CLEAR gs_display. gs_display-rfc_fm = gv_fm_name. gs_display-include = gc_not_found. APPEND gs_display TO gt_display. ENDIF. ENDLOOP. cl_salv_table=>factory( EXPORTING list_display = abap_false IMPORTING r_salv_table = go_salv_table CHANGING t_table = gt_display ). gv_total_records = LINES( gt_display ). gv_alv_title = gv_total_records. CONDENSE gv_alv_title NO-GAPS. CONCATENATE 'Total Found RFC Calls' gv_alv_title INTO gv_alv_title SEPARATED BY space. *------------------------------------------------------------------------------- * Handle ALV Grid events. CREATE OBJECT go_salv_event_handler. go_salv_events_table = go_salv_table->get_event( ). SET HANDLER go_salv_event_handler->on_double_click FOR go_salv_events_table. * Instantiate a CL_SALV_FUNCTIONS subclass. Set all functions on. go_salv_functions_list = go_salv_table->get_functions( ). go_salv_functions_list->set_all( abap_true ). * Instantiate a CL_SALV_DISPLAY_SETTINGS subclass. Set the list header title. go_salv_display_settings = go_salv_table->get_display_settings( ). go_salv_display_settings->set_list_header( gv_alv_title ). go_salv_display_settings->set_striped_pattern( cl_salv_display_settings=>true ). * Set Column names go_salv_columns_table = go_salv_table->get_columns( ). * Get the columns in the ALV. Change the columns headers names from the default values TRY. go_salv_column = go_salv_columns_table->get_column( 'RFC_FM' ). go_salv_column->set_long_text( 'External FM' ). " 40 Char go_salv_column->set_medium_text( 'External FM' ). " 20 Char go_salv_column->set_short_text( 'Ext FM' ). " 10 Char CATCH cx_salv_not_found. WRITE: / 'RFC_FM not found it ALV table'. ENDTRY. TRY. go_salv_column = go_salv_columns_table->get_column( 'INCLUDE' ). go_salv_column->set_long_text( 'Include Calling RFC' ). " 40 Char go_salv_column->set_medium_text( 'Include Calling RFC' ). " 20 Char go_salv_column->set_short_text( 'Include FM' ). " 10 Char CATCH cx_salv_not_found. WRITE: / 'INCLUDE not found it ALV table'. ENDTRY. TRY. go_salv_column = go_salv_columns_table->get_column( 'LINE_NUM' ). go_salv_column->set_long_text( ' Line Number in Include' ). " 40 Char go_salv_column->set_medium_text( 'Line Number' ). " 20 Char go_salv_column->set_short_text( 'Line' ). " 10 Char CATCH cx_salv_not_found. WRITE: / 'LINE_NUM not found it ALV table'. ENDTRY. * Display the ALV Grid. go_salv_table->display( ). FORM build_ranges. CONSTANTS lc_max_size TYPE i VALUE 1000. DATA lv_size TYPE i. CLEAR gt_fm_range. lv_size = LINES( s_fm[] ). IF lv_size GT lc_max_size. lv_size = lc_max_size. ENDIF. APPEND LINES OF s_fm[] FROM 1 TO lv_size TO gt_fm_range. DELETE s_fm[] FROM 1 TO lv_size. ENDFORM. "build_ranges * FORM find_where_in_source USING is_cross TYPE cross CHANGING ct_display TYPE gtt_display. TYPES BEGIN OF lts_found_fm. TYPES order_num TYPE i. TYPES statement TYPE string. TYPES is_rfc_call TYPE boolean. TYPES END OF lts_found_fm. DATA lt_token TYPE STANDARD TABLE OF stokesx. DATA lt_statement TYPE STANDARD TABLE OF sstmnt. DATA lt_found_fm TYPE TABLE OF lts_found_fm. DATA ls_found_fm TYPE lts_found_fm. DATA lt_source_temp TYPE rswsourcet. DATA lt_source TYPE rswsourcet. DATA ls_statement TYPE sstmnt. DATA ls_token TYPE stokesx. DATA ls_display TYPE gts_display. DATA lv_source_code_line TYPE string. DATA lv_pattern_rfc TYPE string. DATA lv_pattern_fm TYPE string. DATA lv_order_num TYPE i. CONCATENATE '*' is_cross-name '*DESTINATION*' INTO lv_pattern_rfc. CONDENSE lv_pattern_rfc NO-GAPS. CONCATENATE '*' is_cross-name '*' INTO lv_pattern_fm. CONDENSE lv_pattern_fm NO-GAPS. CLEAR lt_source. READ REPORT is_cross-include INTO lt_source. CHECK lt_source IS NOT INITIAL. lt_source_temp = lt_source. SCAN ABAP-SOURCE lt_source_temp TOKENS INTO lt_token STATEMENTS INTO lt_statement WITH ANALYSIS.   "Look at each ABAP statment LOOP AT lt_statement INTO ls_statement. CLEAR lv_source_code_line. LOOP AT lt_token INTO ls_token FROM ls_statement-from TO ls_statement-to. CONCATENATE lv_source_code_line ls_token-str INTO lv_source_code_line SEPARATED BY space. ENDLOOP. IF lv_source_code_line CP lv_pattern_fm. lv_order_num = lv_order_num + 1. CLEAR ls_found_fm. ls_found_fm-order_num = lv_order_num. ls_found_fm-statement = lv_source_code_line. IF lv_source_code_line CP lv_pattern_rfc. ls_found_fm-is_rfc_call = 'X'. ENDIF. APPEND ls_found_fm TO lt_found_fm. ENDIF. ENDLOOP. READ TABLE lt_found_fm TRANSPORTING NO FIELDS WITH KEY is_rfc_call = 'X'. IF sy-subrc NE 0. EXIT. ENDIF. CLEAR lv_order_num. LOOP AT lt_source TRANSPORTING NO FIELDS WHERE table_line CP lv_pattern_fm. ls_display-line_num = sy-tabix. ls_display-rfc_fm = is_cross-name. ls_display-include = is_cross-include. lv_order_num = lv_order_num + 1. READ TABLE lt_found_fm TRANSPORTING NO FIELDS WITH KEY order_num = lv_order_num is_rfc_call = 'X'. IF sy-subrc EQ 0. APPEND ls_display TO ct_display. ENDIF. ENDLOOP. ENDFORM. "find_where_in_source