* _ _ _ _ _ * /_\ | |__ __ _ _ __ ___ __ _ __| | __ _| |__ _ __ /_\ * //_\\| '_ \ / _` | '_ \ / __/ _` |/ _` |/ _` | '_ \| '__//_\\ * / _ \ |_) | (_| | |_) | (_| (_| | (_| | (_| | |_) | | / _ \ * \_/ \_/_.__/ \__,_| .__/ \___\__,_|\__,_|\__,_|_.__/|_| \_/ \_/ * |_| www.abapcadabra.com *---------------------------------------------------------------------------- * program : ZABAPCADABRA_BATCHJOB_REPORT * title : Batch job report - dayplanner * functional area : Cross modules * environment : 4.7 * program Function : This report visualizes the batch job activity for a day, where * a 24 hour/actvity matrix is displayed. It gives an insight on * which jobs were triggered, when they were triggered and how long * they ran. * Documentation : Search for "Batchjob report" on AbapcadabrA.com * Installation : Apply this source code and generate. * Previous version : This is the initial version * Developer name : Wim Maasdam * Development date : 14/11/2017 * Version : 0.1 *--------------------------------------------------------------------- * Change list: * Date Description * 14/11/2017 Initial release *--------------------------------------------------------------------- REPORT ZABAPCADABRA_BATCHJOB_REPORT. tables: sscrfields. "Selection screen purpose only TYPE-POOLS SABC. CLASS lcl_event_manager DEFINITION. PUBLIC SECTION. METHODS: constructor IMPORTING r_object TYPE REF TO cl_salv_table, * on_user_command FOR EVENT * added_function OF cl_salv_events * IMPORTING e_salv_function, 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. CLASS LCL_controller DEFINITION. PUBLIC SECTION. TYPES: ty_p type i, begin of ty_alv_report, JOBNAME type TBTCJOB-JOBNAME, STATUS type TBTCJOB-STATUS, STATUS_TXT type c length 15, JOBCOUNT type TBTCJOB-JOBCOUNT, SDLSTRTDT type TBTCJOB-SDLSTRTDT, SDLSTRTTM type TBTCJOB-SDLSTRTTM, ENDDATE type TBTCJOB-ENDDATE, ENDTIME type TBTCJOB-ENDTIME, RUNTIME type t, icon_separator type icon-id, * 24 hours (or alternate settings) p00 type ty_p, p01 type ty_p, p02 type ty_p, p03 type ty_p, p04 type ty_p, p05 type ty_p, p06 type ty_p, p07 type ty_p, p08 type ty_p, p09 type ty_p, p10 type ty_p, p11 type ty_p, p12 type ty_p, p13 type ty_p, p14 type ty_p, p15 type ty_p, p16 type ty_p, p17 type ty_p, p18 type ty_p, p19 type ty_p, p20 type ty_p, p21 type ty_p, p22 type ty_p, p23 type ty_p, icon_separator2 type icon-id, one type ty_p, SDLUNAME type TBTCJOB-SDLUNAME, JOBGROUP type TBTCJOB-JOBGROUP, PERIODIC type TBTCJOB-PERIODIC, JOBCLASS type TBTCJOB-JOBCLASS, BTCSYSTEM type TBTCJOB-BTCSYSTEM, * Color settings COLORS TYPE lvc_t_scol, end of ty_alv_report. CLASS-DATA: gt_alv_data type standard table of ty_alv_report, go_alv TYPE REF TO cl_salv_table, go_event_man TYPE REF TO lcl_event_manager. CLASS-METHODS: alv_report. ENDCLASS. *--------------------------------------------------------------------- * C L A S S D E F I N I T I O N S *--------------------------------------------------------------------- CLASS lcl_job_utility DEFINITION. PUBLIC SECTION. CLASS-DATA: gt_JOBLIST type standard table of TBTCJOB, gv_selection_date type d, gv_jobname_filter type TBTCJOB-JOBNAME, gv_jobdetails_selected type boolean. CLASS-METHODS: job_select importing jobname type TBTCJOB-JOBNAME default gv_jobname_filter FROM type d default gv_selection_date TILL type d default gv_selection_date PRELIM type boolean default abap_true SCHEDUL type boolean default abap_true READY type boolean default abap_true RUNNING type boolean default abap_true FINISHED type boolean default abap_true ABORTED type boolean default abap_true RETURNING VALUE(NR_OF_JOBS_FOUND) type i. ENDCLASS. CLASS lcl_job_utility IMPLEMENTATION. METHOD job_select. data: lw_JOBSEL_PARAM_IN type BTCSELECT. clear lw_JOBSEL_PARAM_IN. lw_JOBSEL_PARAM_IN-JOBNAME = jobname. lw_JOBSEL_PARAM_IN-USERNAME = '*'. lw_JOBSEL_PARAM_IN-FROM_DATE = from. lw_JOBSEL_PARAM_IN-FROM_TIME = '000000'. lw_JOBSEL_PARAM_IN-TO_DATE = till. lw_JOBSEL_PARAM_IN-TO_TIME = '235959'. lw_JOBSEL_PARAM_IN-PRELIM = prelim. lw_JOBSEL_PARAM_IN-SCHEDUL = schedul. lw_JOBSEL_PARAM_IN-READY = ready. lw_JOBSEL_PARAM_IN-RUNNING = running. lw_JOBSEL_PARAM_IN-FINISHED = finished. lw_JOBSEL_PARAM_IN-ABORTED = aborted. CALL FUNCTION 'BP_JOB_SELECT' EXPORTING JOBSELECT_DIALOG = 'N' JOBSEL_PARAM_IN = lw_JOBSEL_PARAM_IN IMPORTING NR_OF_JOBS_FOUND = NR_OF_JOBS_FOUND TABLES JOBSELECT_JOBLIST = gt_JOBLIST EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0. clear NR_OF_JOBS_FOUND. ENDIF. sort gt_JOBLIST by jobname SDLSTRTTM. gv_jobdetails_selected = abap_true. ENDMETHOD. 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_user_command FOR lo_events. SET HANDLER on_link_click FOR lo_events. ENDMETHOD. "constructor * METHOD on_user_command. * * CASE sy-ucomm. * WHEN 'COPY'. * ENDCASE. * * ENDMETHOD. "on_user_command METHOD on_link_click. DATA: lt_bdcdata TYPE STANDARD TABLE OF bdcdata, lw_bdcdata TYPE bdcdata, lw_ALV_data type lcl_controller=>ty_ALV_report, begin of lw_bdcinfo, startdate type c length 10, enddate type c length 10, starttime type c length 8, endtime type c length 8, end of lw_bdcinfo. * bdc_add 'X' 'PROGRAM_NAME' 'SCREEN NUMBER'. * bdc_add ' ' 'FIELDNAME' 'FIELDVALUE'. DEFINE bdc_add. clear lw_bdcdata. lw_bdcdata-dynbegin = &1. if &1 eq 'X'. lw_bdcdata-program = &2. lw_bdcdata-dynpro = &3. else. lw_bdcdata-fnam = &2. lw_bdcdata-fval = &3. endif. append lw_bdcdata to lt_bdcdata. END-OF-DEFINITION. * lt_rows TYPE salv_t_row, * lv_row TYPE int4. * lt_rows = lcl_inventory=>rf_selections->get_selected_rows( ). * DESCRIBE TABLE lt_rows LINES lv_row. * IF lv_row = 1. READ TABLE lcl_controller=>gt_ALV_data INTO lw_ALV_data INDEX row. IF sy-subrc = 0. CASE column. WHEN 'JOBNAME'. clear: lt_bdcdata[]. write lw_ALV_data-SDLSTRTDT to lw_bdcinfo-startdate DD/MM/YYYY. write lw_ALV_data-SDLSTRTTM to lw_bdcinfo-starttime USING EDIT MASK '__:__:__'. if not lw_ALV_data-ENDDATE = space. write lw_ALV_data-ENDDATE to lw_bdcinfo-enddate DD/MM/YYYY. write lw_ALV_data-ENDTIME to lw_bdcinfo-endtime USING EDIT MASK '__:__:__'. else. lw_bdcinfo-enddate = lw_bdcinfo-startdate. lw_bdcinfo-endtime = lw_bdcinfo-starttime. endif. bdc_add: 'X' 'SAPLBTCH' '2170', ' ' 'BTCH2170-JOBNAME' lw_ALV_data-JOBNAME, ' ' 'BTCH2170-USERNAME' lw_ALV_data-SDLUNAME, ' ' 'BTCH2170-PRELIM' 'X', ' ' 'BTCH2170-SCHEDUL' 'X', ' ' 'BTCH2170-READY' 'X', ' ' 'BTCH2170-RUNNING' 'X', ' ' 'BTCH2170-FINISHED' 'X', ' ' 'BTCH2170-ABORTED' 'X', ' ' 'BTCH2170-FROM_DATE' lw_bdcinfo-startdate, ' ' 'BTCH2170-TO_DATE' lw_bdcinfo-enddate, ' ' 'BTCH2170-FROM_TIME' lw_bdcinfo-starttime, ' ' 'BTCH2170-TO_TIME' lw_bdcinfo-endtime, ' ' 'BDC_OKCODE' '=DOIT', 'X' 'SAPMSSY0' '0120'. call transaction 'SM37' using lt_bdcdata mode 'E'. ENDCASE. ENDIF. go_salv->refresh( ). ENDMETHOD. ENDCLASS. CLASS lcl_controller IMPLEMENTATION. method alv_report. DATA: lv_text TYPE scrtext_s, lv_text_m TYPE scrtext_m, lv_text_l TYPE scrtext_l, rf_functions_list TYPE REF TO cl_salv_functions_list, rf_columns_table TYPE REF TO cl_salv_columns_table, rf_column_table TYPE REF TO cl_salv_column_table, rf_column TYPE REF TO cl_salv_column, lw_alv_data type ty_alv_report, lw_TBTCJOB type TBTCJOB, * Aggregation settings: lo_aggregations TYPE REF TO cl_salv_aggregations, * The header/footer box rf_alv_header TYPE REF TO cl_salv_form_layout_grid, rf_alv_footer TYPE REF TO cl_salv_form_layout_grid, rf_sorts TYPE REF TO cl_salv_sorts, rf_display_settings TYPE REF TO CL_SALV_DISPLAY_SETTINGS, lw_colored_field TYPE lvc_s_scol, lw_colored_status TYPE lvc_s_scol, lt_COLORS TYPE lvc_t_scol, lv_fieldname TYPE string, lv_duration type t, begin of lw_timecaster, h type n length 2, m type n length 2, s type n length 2, end of lw_timecaster, begin of lw_totals, h type n length 6, m type n length 6, s type n length 6, jobs type n length 5, unique_jobs type n length 5, end of lw_totals, lv_calculate type n length 6, lv_minutes_total type n length 3, lv_minutes_in_hour type n length 2, lv_jobname type TBTCJOB-JOBNAME. FIELD-SYMBOLS type any. DEFINE set_text_field. * rf_column ?= rf_columns_table->get_column( &1 ). move rf_columns_table->get_column( &1 ) to rf_column. lv_text = &2. lv_text_m = &2. lv_text_l = &2. rf_column->set_short_text( lv_text ). rf_column->set_medium_text( lv_text_m ). rf_column->set_long_text( lv_text_l ). rf_column->set_zero( abap_false ). END-OF-DEFINITION. DEFINE set_hidden_field. set_text_field &1 &2. rf_column->set_visible( abap_false ). END-OF-DEFINITION. clear: gt_alv_data[]. lw_colored_field-color-col = 7. lw_colored_field-color-int = 0. lw_colored_field-color-inv = 0. clear: lw_totals, lv_jobname. loop at lcl_JOB_utility=>gt_JOBLIST into lw_TBTCJOB. clear lw_alv_data. add 1 to lw_totals-jobs. if lv_jobname <> lw_TBTCJOB-jobname. add 1 to lw_totals-unique_jobs. lv_jobname = lw_TBTCJOB-jobname. endif. lw_alv_data-one = 1. move-corresponding lw_TBTCJOB to lw_alv_data. * Set the status field - as text: lw_colored_status-color-int = 0. lw_colored_status-color-inv = 0. lw_colored_status-fname = 'STATUS_TXT'. case lw_alv_data-status. when 'P'. lw_alv_data-status_txt = 'Planned'. lw_colored_status-color-col = 1. when 'S'. lw_alv_data-status_txt = 'Released'. lw_colored_status-color-col = 1. * ? = Ready when 'R'. lw_alv_data-status_txt = 'Running / Active'. lw_colored_status-color-col = 0. when 'A'. lw_alv_data-status_txt = 'Cancelled'. lw_colored_status-color-col = 6. when 'F'. lw_alv_data-status_txt = 'Finished'. lw_colored_status-color-col = 5. endcase. append lw_colored_status to lw_alv_data-colors. * Set the color of the Class field: lw_colored_status-color-int = 0. lw_colored_status-color-inv = 0. lw_colored_status-fname = 'JOBCLASS'. case lw_alv_data-jobclass. when 'A'. lw_colored_status-color-col = 6. append lw_colored_status to lw_alv_data-colors. when 'B'. when 'C'. * No action, normal class. endcase. * Set the separator Icons" lw_alv_data-icon_separator = ICON_ODS_INA. lw_alv_data-icon_separator2 = ICON_ODS_INA. if lw_alv_data-status <> 'F' and lw_alv_data-status <> 'A'. append lw_alv_data to gt_alv_data. continue. endif. * Fill in the hour blocks - 24 hours: concatenate 'P' lw_alv_data-SDLSTRTTM(2) into lw_colored_field-fname. APPEND lw_colored_field TO lw_alv_data-colors. concatenate 'LW_ALV_DATA' lw_colored_field-fname into lv_fieldname separated by '-'. assign (lv_fieldname) to . if sy-subrc = 0. * Calculate the number of minutes in the hour the job started on. First calculate the * total job-duration: if lw_alv_data-ENDDATE = lw_alv_data-SDLSTRTDT. lv_duration = lw_alv_data-ENDTIME - lw_alv_data-SDLSTRTTM. else. move '235959' to lv_duration. lv_duration = lv_duration - lw_alv_data-SDLSTRTTM. endif. lw_alv_data-runtime = lv_duration. move lv_duration to lw_timecaster. lv_minutes_total = lw_timecaster-h * 60 + lw_timecaster-m. ADD lw_timecaster-h to lw_totals-h. ADD lw_timecaster-m to lw_totals-m. ADD lw_timecaster-s to lw_totals-s. * The minutes in the first hour: move lw_alv_data-SDLSTRTTM to lw_timecaster. lv_minutes_in_hour = 60 - lw_timecaster-m. if lv_minutes_in_hour < lv_minutes_total. = lv_minutes_in_hour. * NOW also process the other minutes... subtract lv_minutes_in_hour from lv_minutes_total. do. if lv_minutes_total > 60. lv_minutes_in_hour = 60. else. lv_minutes_in_hour = lv_minutes_total. endif. add 1 to lw_timecaster-h. move lw_timecaster to lv_duration. concatenate 'P' lv_duration(2) into lw_colored_field-fname. APPEND lw_colored_field TO lw_alv_data-colors. concatenate 'LW_ALV_DATA' lw_colored_field-fname into lv_fieldname separated by '-'. assign (lv_fieldname) to . if sy-subrc = 0. = lv_minutes_in_hour. endif. subtract lv_minutes_in_hour from lv_minutes_total. if lv_minutes_total <= 0. exit. endif. enddo. else. = lv_minutes_total. endif. endif. append lw_alv_data to gt_alv_data. endloop. * The total times - as hours, minutes and seconds: first add the seconds to the minutes: lv_calculate = lw_totals-s div 60. add lv_calculate to lw_totals-m. lw_totals-s = lw_totals-s mod 60. lv_calculate = lw_totals-m div 60. add lv_calculate to lw_totals-h. lw_totals-m = lw_totals-m mod 60. try. cl_salv_table=>factory( importing r_salv_table = go_alv changing t_table = gt_alv_data ). rf_functions_list = go_alv->get_functions( ). rf_functions_list->set_all( ). rf_columns_table = go_alv->get_columns( ). rf_columns_table->set_color_column( value = 'COLORS' ). rf_columns_table->set_optimize( abap_true ). "Always a good idea set_hidden_field: 'STATUS' 'Status', 'SDLSTRTDT' 'Start', 'JOBCOUNT' 'Job number', 'ENDDATE' 'Finish', 'ENDTIME' 'at', 'BTCSYSTEM' 'System', 'JOBGROUP' 'Jobgroup'. set_text_field: 'SDLSTRTTM' 'Start', 'STATUS_TXT' 'Status', 'RUNTIME' 'Duration', 'ONE' 'One', 'JOBCLASS' 'Class', 'PERIODIC' 'Periodic', 'ICON_SEPARATOR' '--', 'ICON_SEPARATOR2' '--'. * Hotspot field rf_column_table ?= rf_columns_table->get_column( 'JOBNAME' ). rf_column_table->set_cell_type( if_salv_c_cell_type=>hotspot ). * Checkbox field rf_column_table ?= rf_columns_table->get_column( 'PERIODIC' ). rf_column_table->set_cell_type( if_salv_c_cell_type=>checkbox ). set_text_field: 'P00' '00h', 'P01' '01h', 'P02' '02h', 'P03' '03h', 'P04' '04h', 'P05' '05h', 'P06' '06h', 'P07' '07h', 'P08' '08h', 'P09' '09h', 'P10' '10h', 'P11' '11h', 'P12' '12h', 'P13' '13h', 'P14' '14h', 'P15' '15h', 'P16' '16h', 'P17' '17h', 'P18' '18h', 'P19' '19h', 'P20' '20h', 'P21' '21h', 'P22' '22h', 'P23' '23h'. lo_aggregations = go_alv->get_aggregations( ). lo_aggregations->add_aggregation( columnname = 'ONE' ). lo_aggregations->add_aggregation( columnname = 'P00' ). lo_aggregations->add_aggregation( columnname = 'P01' ). lo_aggregations->add_aggregation( columnname = 'P02' ). lo_aggregations->add_aggregation( columnname = 'P03' ). lo_aggregations->add_aggregation( columnname = 'P04' ). lo_aggregations->add_aggregation( columnname = 'P05' ). lo_aggregations->add_aggregation( columnname = 'P06' ). lo_aggregations->add_aggregation( columnname = 'P07' ). lo_aggregations->add_aggregation( columnname = 'P08' ). lo_aggregations->add_aggregation( columnname = 'P09' ). lo_aggregations->add_aggregation( columnname = 'P10' ). lo_aggregations->add_aggregation( columnname = 'P11' ). lo_aggregations->add_aggregation( columnname = 'P12' ). lo_aggregations->add_aggregation( columnname = 'P13' ). lo_aggregations->add_aggregation( columnname = 'P14' ). lo_aggregations->add_aggregation( columnname = 'P15' ). lo_aggregations->add_aggregation( columnname = 'P16' ). lo_aggregations->add_aggregation( columnname = 'P17' ). lo_aggregations->add_aggregation( columnname = 'P18' ). lo_aggregations->add_aggregation( columnname = 'P19' ). lo_aggregations->add_aggregation( columnname = 'P20' ). lo_aggregations->add_aggregation( columnname = 'P21' ). lo_aggregations->add_aggregation( columnname = 'P22' ). lo_aggregations->add_aggregation( columnname = 'P23' ). rf_sorts = go_alv->get_sorts( ). rf_sorts->add_sort( columnname = 'JOBNAME' subtotal = abap_true sequence = IF_SALV_C_SORT=>SORT_UP ). CREATE OBJECT rf_alv_header. rf_alv_header->create_text( text = '________________' row = 1 column = 1 ). rf_alv_header->create_text( text = '____________' row = 1 column = 2 ). rf_alv_header->create_text( text = '________________' row = 1 column = 3 ). rf_alv_header->create_text( text = '____________' row = 1 column = 4 ). rf_alv_header->create_text( text = '________________' row = 1 column = 5 ). rf_alv_header->create_text( text = '____________' row = 1 column = 6 ). rf_alv_header->create_text( text = 'Batchjobs for:' row = 2 column = 1 ). rf_alv_header->create_text( text = lcl_job_utility=>gv_selection_date row = 2 column = 2 ). rf_alv_header->create_text( text = 'Total jobs:' row = 2 column = 3 ). rf_alv_header->create_text( text = lw_totals-jobs row = 2 column = 4 ). rf_alv_header->create_text( text = 'Batchjob names:' row = 3 column = 1 ). rf_alv_header->create_text( text = lcl_job_utility=>gv_jobname_filter row = 3 column = 2 ). rf_alv_header->create_text( text = 'Unique jobs:' row = 3 column = 3 ). rf_alv_header->create_text( text = lw_totals-unique_jobs row = 3 column = 4 ). rf_alv_header->create_text( text = 'Total runtime:' row = 2 column = 5 ). if lw_totals-h < 99. MOVE-CORRESPONDING lw_totals to lw_timecaster. move lw_timecaster to lv_duration. rf_alv_header->create_text( text = lv_duration row = 2 column = 6 ). else. rf_alv_header->create_text( text = lw_totals-h && ' hours' row = 2 column = 6 ). endif. rf_display_settings = go_alv->get_display_settings( ). rf_display_settings->set_striped_pattern( abap_true ). go_alv->set_top_of_list( rf_alv_header ). go_alv->set_top_of_list_print( rf_alv_header ). ** ** CREATE OBJECT rf_alv_footer. ** rf_alv_footer->create_text( text = 'Number of jobs: ' row = 1 column = 1 ). ** lv_string = lines( gt_calendar ). ** rf_alv_footer->create_text( text = lv_string row = 1 column = 2 ). ** ** go_alv->set_end_of_list( rf_alv_footer ). ** go_alv->set_end_of_list_print( rf_alv_footer ). CREATE OBJECT go_event_man EXPORTING r_object = go_alv. go_alv->display( ). catch CX_SALV_MSG CX_SALV_DATA_ERROR CX_SALV_NOT_FOUND CX_SALV_EXISTING. message 'ALV error' type 'S'. endtry. endmethod. ENDCLASS. *--------------------------------------------------------------------- * S E L E C T I O N - S C R E E N *--------------------------------------------------------------------- selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_01 FOR FIELD pa_date. parameter: pa_date TYPE d default sy-datum. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_02 FOR FIELD pa_jobna. parameter: pa_jobna type TBTCJOB-JOBNAME DEFAULT '*'. selection-SCREEN END OF LINE. *--------------------------------------------------------------------- * I N I T I A L I Z A T I O N *--------------------------------------------------------------------- INITIALIZATION. * All texts for this report have been set up as hard-coded texts lbl_01 = 'Date'. lbl_02 = 'Job name'. *--------------------------------------------------------------------- * S T A R T - O F - S E L E C T I O N *--------------------------------------------------------------------- START-OF-SELECTION. lcl_job_utility=>gv_selection_date = pa_date. lcl_job_utility=>gv_jobname_filter = pa_jobna. lcl_job_utility=>job_select( ). lcl_controller=>alv_report( ).