* _ _ _ _ _ * /_\ | |__ __ _ _ __ ___ __ _ __| | __ _| |__ _ __ /_\ * //_\\| '_ \ / _` | '_ \ / __/ _` |/ _` |/ _` | '_ \| '__//_\\ * / _ \ |_) | (_| | |_) | (_| (_| | (_| | (_| | |_) | | / _ \ * \_/ \_/_.__/ \__,_| .__/ \___\__,_|\__,_|\__,_|_.__/|_| \_/ \_/ * |_| www.abapcadabra.com *---------------------------------------------------------------------------- * program : ZABAPCADABRA_BATCH_SCHEDULER * title : Batch job scheduling * functional area : Cross modules * environment : 4.7 * program Function : This report allows scheduling other reports in an alternate time * range, every 10 minutes until noon, then every 20 minutes till * diner time. With a date-range a calendar can be applied (e.g. * don't run at Christmas). * Documentation : Search for "Batch scheduler" on AbapcadabrA.com * Installation : Apply this source code and generate. The setup will store * settings in TVARVC, for which the parameters will be created * automatically (name: ZABAPCADABRA_SCHEDULER*). * Previous version : This is the initial version * Developer name : Wim Maasdam * Development date : 18/10/2017 * Version : 0.1 *--------------------------------------------------------------------- * Change list: * Date Description * 18/10/2017 Initial release *--------------------------------------------------------------------- REPORT ZABAPCADABRA_BATCH_SCHEDULER. tables: sscrfields. "Selection screen purpose only TYPE-POOLS SABC. CLASS LCL_controller DEFINITION. PUBLIC SECTION. CONSTANTS: gc_tvarv_jobname type tvarv-name value 'ZABAPCADABRA_SCHEDULER_JOBNAME', gc_tvarv_savelog type tvarv-name value 'ZABAPCADABRA_SCHEDULER_SAVELOG', gc_tvarv_authusr type tvarv-name value 'ZABAPCADABRA_SCHEDULER_AUTHUSR'. CLASS-DATA: begin of gw_scheduler_controls, settings_ok type boolean, scheduler_on_air type boolean, variant_active type boolean, end of gw_scheduler_controls, gw_scheduler_TVARVC type TVARVC, gv_scheduler_jobname type tbtcp-JOBNAME, gv_scheduler_jobname_mask type tbtcp-JOBNAME, gv_scheduler_savelogs type boolean, gt_varid type STANDARD TABLE OF varid. CLASS-METHODS: set_listbox_jobcl, get_active_variants. ENDCLASS. constants: co_slg0_object TYPE balobj_d VALUE 'ALERT', co_slg0_subobject TYPE balsubobj VALUE 'PROCESSING'. *--------------------------------------------------------------------- * 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: gv_jobname type TBTCJOB-JOBNAME, gv_jobcount type TBTCJOB-JOBCOUNT, gt_JOBLIST type standard table of TBTCJOB, gv_jobdetails_selected type boolean. CLASS-METHODS: job_open importing jobname type TBTCJOB-JOBNAME returning value(success) type boolean, job_submit importing report type RSVAR-REPORT variant type RSVAR-VARIANT returning value(success) type boolean, job_close importing immediate type boolean default abap_false start_date type sy-datum start_time type sy-uzeit targetserver type BTCTGTSRVR-SRVNAME DEFAULT space returning value(success) type boolean, job_select importing jobname type TBTCJOB-JOBNAME from type d default sy-datum till type d default sy-datum 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_false ABORTED type boolean default abap_false RETURNING VALUE(NR_OF_JOBS_FOUND) type i, job_delete importing jobname type TBTCJOB-JOBNAME jobcount type TBTCJOB-jobcount returning value(success) type boolean. ENDCLASS. *---------------------------------------------------------------------- * CLASS lcl_logging - the message logging and error logging for this * interface is done in the Business Application Log (trx. SLG0, SLG1). * The log is displayed at the end of the report run. Logs can also * be saved (options on the selection screen are available). *---------------------------------------------------------------------- CLASS lcl_logging DEFINITION. PUBLIC SECTION. CLASS-DATA: go_log TYPE REF TO cl_ishmed_bal, gv_errors_were_logged TYPE boolean VALUE space. CLASS-METHODS: initialize IMPORTING object TYPE balobj_d DEFAULT co_slg0_object subobject TYPE balsubobj DEFAULT co_slg0_subobject extid type any default space, set_message IMPORTING message TYPE any OPTIONAL par1 TYPE any DEFAULT space par2 TYPE any DEFAULT space par3 TYPE any DEFAULT space msgty TYPE symsgty DEFAULT 'I' pass_to_joblog type boolean DEFAULT space PREFERRED PARAMETER message, set_subject IMPORTING subject TYPE any, set_error IMPORTING message TYPE any OPTIONAL par1 TYPE any DEFAULT space par2 TYPE any DEFAULT space PREFERRED PARAMETER message, formatter IMPORTING input type any format type any default 'DATE' returning value(result) type char80. ENDCLASS. "lcl_logging DEFINITION CLASS lcl_job_utility IMPLEMENTATION. METHOD job_open. gv_jobname = jobname. CALL FUNCTION 'JOB_OPEN_ADK' EXPORTING JOBNAME = gv_jobname IMPORTING JOBCOUNT = gv_jobcount EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0. clear success. ELSE. success = abap_true. ENDIF. ENDMETHOD. METHOD job_submit. data: lw_TVARVC type TVARVC, lv_AUTHCKNAM type TBTCJOB-AUTHCKNAM. select single * from TVARVC into lw_TVARVC where name = lcl_controller=>gc_tvarv_authusr and type = 'P' and numb = 0000. if sy-subrc = 0 and not lw_TVARVC-low is initial. lv_AUTHCKNAM = lw_TVARVC-low. else. lv_AUTHCKNAM = sy-uname. endif. clear success. CALL FUNCTION 'JOB_SUBMIT_ADK' EXPORTING AUTHCKNAM = lv_AUTHCKNAM JOBCOUNT = gv_jobcount JOBNAME = gv_jobname REPORT = report VARIANT = variant EXCEPTIONS OTHERS = 4. IF SY-SUBRC = 0. success = abap_true. ENDIF. ENDMETHOD. METHOD job_close. clear success. if immediate = abap_true. CALL FUNCTION 'JOB_CLOSE_ADK' EXPORTING JOBCOUNT = gv_jobcount JOBNAME = gv_jobname STRTIMMED = 'X' EXCEPTIONS OTHERS = 4. IF SY-SUBRC = 0. success = abap_true. ENDIF. else. CALL FUNCTION 'JOB_CLOSE_ADK' EXPORTING JOBCOUNT = gv_jobcount JOBNAME = gv_jobname SDLSTRTDT = start_date SDLSTRTTM = start_time TARGETSERVER = targetserver EXCEPTIONS OTHERS = 4. IF SY-SUBRC = 0. success = abap_true. ENDIF. endif. ENDMETHOD. 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. gv_jobdetails_selected = abap_true. ENDMETHOD. METHOD job_delete. CALL FUNCTION 'BP_JOB_DELETE' EXPORTING JOBCOUNT = jobcount JOBNAME = jobname * FORCEDMODE = ' ' * COMMITMODE = 'X' EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0. success = abap_false. ELSE. success = abap_true. ENDIF. ENDMETHOD. ENDCLASS. *---------------------------------------------------------------------- * CLASS lcl_logging IMPLEMENTATION *---------------------------------------------------------------------- CLASS lcl_logging IMPLEMENTATION. METHOD initialize. data: lv_extid type BALNREXT. lv_extid = extid. TRY. CREATE OBJECT go_log EXPORTING i_object = object i_subobject = subobject i_extid = lv_extid i_repid = sy-repid. CATCH cx_ishmed_log. "#EC NO_HANDLER * No actual processing here ENDTRY. ENDMETHOD. "initialize METHOD set_message. " importing message type any, par1, par2 DATA: lv_message TYPE c LENGTH 200, lv_par1 type c length 80, lv_par2 type c length 80, lv_par3 type c length 80. lv_message = message. move par1 to lv_par1. shift lv_par1 LEFT DELETING LEADING space. move par2 to lv_par2. shift lv_par2 LEFT DELETING LEADING space. move par3 to lv_par3. shift lv_par3 LEFT DELETING LEADING space. REPLACE '&' WITH lv_par1 INTO lv_message. CONDENSE lv_message. REPLACE '&' WITH lv_par2 INTO lv_message. CONDENSE lv_message. REPLACE '&' WITH lv_par3 INTO lv_message. CONDENSE lv_message. TRY. go_log->add_free_text( EXPORTING i_msg_type = msgty i_text = lv_message ). CATCH cx_ishmed_log. "#EC NO_HANDLER * No actual logic on catch ENDTRY. if pass_to_joblog = abap_true and sy-batch = abap_true. message id 'V1' type 'I' number 899 with lv_message(50) lv_message+50(50). endif. ENDMETHOD. "set_message METHOD set_subject. DATA: lv_subject TYPE c LENGTH 100. lv_subject = subject. * concatenate '==>' lv_subject into lv_subject SEPARATED BY space. TRANSLATE lv_subject TO UPPER CASE. set_message( message = lv_subject msgty = 'W' ). ENDMETHOD. "set_subject METHOD set_error. set_message( message = message par1 = par1 par2 = par2 msgty = 'E' ). lcl_logging=>gv_errors_were_logged = abap_true. ENDMETHOD. "set_error METHOD formatter. case format. when 'DATE'. write input to result DD/MM/YYYY. when 'TIME'. write input to result using EDIT MASK '__:__'. endcase. ENDMETHOD. ENDCLASS. "lcl_logging IMPLEMENTATION CLASS lcl_controller IMPLEMENTATION. method set_listbox_jobcl. DATA: lt_list TYPE vrm_values, lw_list LIKE LINE OF lt_list. lw_list-key = 'A'. lw_list-text = 'High priority'. APPEND lw_list TO lt_list. lw_list-key = 'B'. lw_list-text = 'Medium priority'. APPEND lw_list TO lt_list. lw_list-key = 'C'. lw_list-text = 'Low priority'. APPEND lw_list TO lt_list. CALL FUNCTION 'VRM_SET_VALUES' EXPORTING id = 'PA_JOBCL' values = lt_list. endmethod. method get_active_variants. data: lw_varid type varid, lt_VALUTAB type standard table of RSPARAMS, lw_valutab type RSPARAMS, lv_active_variant type boolean. select * from varid into table gt_varid where report = sy-repid and variant <> 'MASTER'. loop at gt_varid into lw_varid. lv_active_variant = abap_false. CALL FUNCTION 'RS_VARIANT_CONTENTS' EXPORTING REPORT = lw_varid-report VARIANT = lw_varid-variant TABLES VALUTAB = lt_VALUTAB EXCEPTIONS OTHERS = 4. IF SY-SUBRC = 0. read table lt_VALUTAB into lw_valutab with key SELNAME = 'PA_ACTIV'. if sy-subrc = 0 and lw_valutab-low = abap_true. lv_active_variant = abap_true. endif. ENDIF. if lv_active_variant = abap_false. delete gt_varid. endif. endloop. endmethod. ENDCLASS. *--------------------------------------------------------------------- * S E L E C T I O N - S C R E E N *--------------------------------------------------------------------- selection-SCREEN BEGIN OF LINE. parameter: pa_live TYPE c length 39 lower case modif id REO. parameter: pa_live2 TYPE c length 38 lower case modif id REO. SELECTION-SCREEN PUSHBUTTON 80(20) live_btn USER-COMMAND controls MODIF ID XXX VISIBLE LENGTH 4. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. parameter: pa_live3 TYPE c length 39 lower case modif id REO. parameter: pa_live4 TYPE c length 38 lower case modif id REO. SELECTION-SCREEN PUSHBUTTON 80(20) stat_btn USER-COMMAND ACTIVATOR MODIF ID XXX VISIBLE LENGTH 4. selection-SCREEN END OF LINE. selection-SCREEN ULINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_01 FOR FIELD pa_jobna. parameter: pa_jobna type TBTCO-JOBNAME visible length 18 MODIF ID ro. "Instead of 32, variant name excluded parameter: pa_jobva TYPE RSVAR-VARIANT MODIF ID ro. parameter: pa_jobvt TYPE c LENGTH 35 LOWER CASE MODIF ID reo. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_01b FOR FIELD pa_jobcl. parameter: pa_jobcl type TBTCO-JOBCLASS AS LISTBOX VISIBLE LENGTH 14 DEFAULT 'C' MODIF ID RO. selection-SCREEN COMMENT 33(6) lbl_01c FOR FIELD pa_serve. parameter: pa_serve type TBTCO-EXECSERVER. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_02 FOR FIELD pa_step1. PARAMETER: pa_step1 TYPE sy-repid, pa_sttx1 TYPE trdirt-text lower case visible length 35. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_02b FOR FIELD pa_vari1. parameter: pa_vari1 type RSVAR-VARIANT, pa_vatx1 type varit-vtext lower case. SELECTION-SCREEN PUSHBUTTON 80(20) stp2_btn USER-COMMAND set_step2 MODIF ID ST1 VISIBLE LENGTH 4. parameter: pa_st1 type c length 1 NO-DISPLAY. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_03 FOR FIELD pa_step2 modif id ST2. PARAMETER: pa_step2 TYPE sy-repid modif id ST2, pa_sttx2 TYPE trdirt-text lower case visible length 35 modif id ST2. selection-SCREEN END OF LINE. selection-SCREEN BEGIN OF LINE. selection-SCREEN COMMENT 1(13) lbl_03b FOR FIELD pa_vari2 modif id ST2. parameter: pa_vari2 type RSVAR-VARIANT modif id ST2, pa_vatx2 type varit-vtext lower case modif id ST2. selection-SCREEN END OF LINE. SELECTION-SCREEN: SKIP. selection-screen BEGIN OF LINE. selection-SCREEN COMMENT 1(10) lbl_04 FOR FIELD so_onair. select-options so_onair for sy-datum. selection-SCREEN END OF LINE. SELECTION-SCREEN: ULINE, BEGIN OF LINE, COMMENT 1(6) lbl_k1 MODIF ID lk1, COMMENT 9(5) lbl_d1, COMMENT 14(5) lbl_d2, COMMENT 19(5) lbl_d3, COMMENT 24(5) lbl_d4, COMMENT 29(5) lbl_d5, COMMENT 34(5) lbl_d6, COMMENT 39(5) lbl_d7, COMMENT 47(8) lbl_k2, COMMENT 56(5) lbl_k3, COMMENT 65(5) lbl_k4, END OF LINE. define time_line. SELECTION-SCREEN: BEGIN OF LINE, POSITION 3. PARAMETERS: pa_act&1 as CHECKBOX default abap_false USER-COMMAND act&1 MODIF ID t&1. SELECTION-SCREEN POSITION 10. PARAMETERS: pa_mon&1 as CHECKBOX default abap_true MODIF ID t&1. SELECTION-SCREEN POSITION 15. PARAMETERS: pa_tue&1 as CHECKBOX default abap_true MODIF ID t&1. SELECTION-SCREEN POSITION 20. PARAMETERS: pa_wed&1 as CHECKBOX default abap_true MODIF ID t&1. SELECTION-SCREEN POSITION 25. PARAMETERS: pa_thu&1 as CHECKBOX default abap_true MODIF ID t&1. SELECTION-SCREEN POSITION 30. PARAMETERS: pa_fri&1 as CHECKBOX default abap_true MODIF ID t&1. SELECTION-SCREEN POSITION 35. PARAMETERS: pa_sat&1 as CHECKBOX default abap_false MODIF ID t&1. SELECTION-SCREEN POSITION 40. PARAMETERS: pa_sun&1 as CHECKBOX default abap_false MODIF ID t&1. SELECTION-SCREEN POSITION 47. PARAMETERS: pa_frm&1 type c length 5 default '00:00' MODIF ID t&1. PARAMETERS: pa_ico&1 type c length 10 VISIBLE LENGTH 2 DEFAULT '@1F@' MODIF ID reo. PARAMETERS: pa_til&1 type c length 5 default '23:59' MODIF ID t&1. SELECTION-SCREEN POSITION 65. PARAMETERS: pa_per&1 type c length 5 default '00:00' MODIF ID t&1. SELECTION-SCREEN END OF LINE. end-of-definition. time_line: 01, 02, 03, 04, 05, 06, 07, 08. SELECTION-SCREEN ULINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN PUSHBUTTON (70) lbl_abca USER-COMMAND ABAPCADABRA MODIF ID XXX VISIBLE LENGTH 5. SELECTION-SCREEN PUSHBUTTON (16) pushbut1 USER-COMMAND preview MODIF ID XXX. SELECTION-SCREEN PUSHBUTTON (16) pushbut2 USER-COMMAND schedule_now MODIF ID XXX. SELECTION-SCREEN PUSHBUTTON (16) pushbut3 USER-COMMAND retract_now MODIF ID XXX. SELECTION-SCREEN PUSHBUTTON (16) pushbut4 USER-COMMAND slg1 MODIF ID XXX. parameter: pa_ACTIV type boolean NO-DISPLAY. selection-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 5(70) lbl_10 MODIF ID MST. SELECTION-SCREEN END OF LINE. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 5(14) lbl_11 FOR FIELD pa_bjnam MODIF ID MST. PARAMETERS: pa_bjnam type TBTCO-JOBNAME MODIF ID MST. SELECTION-SCREEN END OF LINE. PARAMETERS: EXECUTE type c length 10 MODIF ID XXX NO-DISPLAY. PARAMETERS: SHOWLOG type boolean default abap_true NO-DISPLAY. AT SELECTION-SCREEN OUTPUT. define time_line_screen. if pa_act&1 = abap_false. IF SCREEN-GROUP1 = 'T&1' AND SCREEN-NAME <> 'PA_ACT&1'. SCREEN-INPUT = '0'. MODIFY SCREEN. ENDIF. else. * Start and finish times - align if not pa_frm&1 is initial. if pa_til&1 < pa_frm&1. pa_til&1 = pa_frm&1. endif. endif. endif. end-of-definition. define hide_timeline. * All lines are ACTIVE, hide Active column IF SCREEN-NAME = 'PA_ACT&1'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. if pa_act&1 = abap_false. IF SCREEN-GROUP1 = 'T&1' OR SCREEN-NAME = 'PA_ICO&1'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. elseif pa_per&1 = '00:00'. IF SCREEN-NAME = 'PA_TIL&1' or SCREEN-NAME = 'PA_PER&1' or SCREEN-NAME = 'PA_ICO&1'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. endif. end-of-definition. * Determine whether the scheduler is ON-AIR, set status messages PA_live, PA_live2 to 4 clear LCL_controller=>gw_scheduler_controls. select single * from TVARVC into lcl_controller=>gw_scheduler_TVARVC where NAME = lcl_controller=>gc_tvarv_jobname and TYPE = 'P' and NUMB = 0000. if sy-subrc = 0 and not lcl_controller=>gw_scheduler_TVARVC-low is initial. LCL_controller=>gw_scheduler_controls-settings_ok = abap_true. lcl_controller=>gv_scheduler_jobname = lcl_controller=>gw_scheduler_TVARVC-low. pa_jobna = lcl_controller=>gw_scheduler_TVARVC-low. replace '' in pa_jobna with space. pa_bjnam = lcl_controller=>gw_scheduler_TVARVC-low. replace '' in pa_bjnam with 'MASTER'. * Test whether the scheduler is UP: if lcl_job_utility=>job_select( jobname = pa_bjnam ) > 0. LCL_controller=>gw_scheduler_controls-scheduler_on_air = abap_true. endif. else. clear: pa_jobna, pa_bjnam. endif. LCL_controller=>gw_scheduler_controls-variant_active = pa_ACTIV. if LCL_controller=>gw_scheduler_controls-settings_ok = abap_false. pa_live = '@0A@ Control settings missing'. pa_live2 = '@AI@ Define settings (batch job name) ==>'. elseif LCL_controller=>gw_scheduler_controls-scheduler_on_air = abap_true. pa_live = '@08@ Live !'. pa_live2 = ''. else. pa_live = '@09@ Ready to go (not live)'. pa_live2 = '@AI@ Schedule job with variant MASTER'. endif. if LCL_controller=>gw_scheduler_controls-variant_active = abap_true. pa_live3 = '@08@ Calendar settings active'. pa_live4 = ''. else. pa_live3 = '@EB@ Calendar settings not active'. pa_live4 = '@AI@ Activate settings, save variant'. endif. select single * from TVARVC into lcl_controller=>gw_scheduler_TVARVC where NAME = lcl_controller=>gc_tvarv_savelog and TYPE = 'P' and NUMB = 0000. if sy-subrc = 0. lcl_controller=>gv_scheduler_savelogs = lcl_controller=>gw_scheduler_TVARVC-low. else. clear lcl_controller=>gv_scheduler_savelogs. endif. LOOP AT SCREEN. * The text fields IF SCREEN-GROUP1 = 'REO' or SCREEN-NAME(7) = 'PA_STTX' or SCREEN-NAME(7) = 'PA_VATX'. SCREEN-INPUT = '0'. SCREEN-DISPLAY_3D = '0'. SCREEN-INTENSIFIED = '1'. MODIFY SCREEN. ENDIF. IF SCREEN-GROUP1 = 'RO'. SCREEN-INPUT = '0'. MODIFY SCREEN. ENDIF. * Step 2 available switch if pa_st1 = abap_false. IF SCREEN-GROUP1 = 'ST2'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. else. IF SCREEN-GROUP1 = 'ST1'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. endif. * Active / inactive switch (right bottom button) if pa_ACTIV = abap_true. IF SCREEN-GROUP1 <> 'XXX'. SCREEN-INPUT = '0'. MODIFY SCREEN. ENDIF. * Hide the column title "Active" IF SCREEN-GROUP1 = 'LK1'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. * If the settings are active, - inactive lines are hidden hide_timeline: 01, 02, 03, 04, 05, 06, 07, 08. else. time_line_screen: 01, 02, 03, 04, 05, 06, 07, 08. IF SCREEN-NAME = 'PUSHBUT1' OR SCREEN-NAME = 'PUSHBUT2' OR SCREEN-NAME = 'PUSHBUT3'. SCREEN-INPUT = '0'. MODIFY SCREEN. ENDIF. endif. * If the variant is set to MASTER, all fields shouls be dimmed completely: if sy-slset = 'MASTER'. IF SCREEN-GROUP1 <> 'MST'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. else. IF SCREEN-GROUP1 = 'MST'. SCREEN-INPUT = '0'. SCREEN-ACTIVE = '0'. MODIFY SCREEN. ENDIF. endif. IF screen-name = 'PA_BJNAM'. SCREEN-INPUT = '0'. MODIFY SCREEN. ENDIF. ENDLOOP. if not pa_step1 is initial. select single text from trdirt into pa_sttx1 where name = pa_step1 and sprsl = sy-langu. endif. if not pa_vari1 is initial. select single vtext from varit into pa_vatx1 where langu = sy-langu and report = pa_step1 and variant = pa_vari1. endif. if pa_ACTIV = abap_true. stat_btn = '@BG\QChange@'. else. stat_btn = '@BF\QActivate@'. endif. data: lw_varit type varit. select * from varit into lw_varit up to 1 rows where report = sy-repid and variant = sy-slset. endselect. if sy-subrc = 0. pa_jobva = sy-slset. pa_jobvt = lw_varit-vtext. endif. lcl_controller=>set_listbox_jobcl( ). *--------------------------------------------------------------------- AT SELECTION-SCREEN. CASE sscrfields-ucomm. WHEN 'ACTIVATOR'. if pa_ACTIV = abap_false. * Perform a series of checks: if pa_jobna is initial. message 'Please supply jobname' type 'S'. elseif pa_step1 is initial or pa_vari1 is initial. message 'Please supply step and variant' type 'S'. elseif not pa_step2 is initial and pa_vari2 is initial. message 'Please supply step and variant - step 2' type 'S'. else. pa_ACTIV = abap_true. if pa_step2 is initial. clear: pa_st1, pa_vari2. endif. message 'Do not forget to SAVE THE VARIANT' type 'S'. endif. else. pa_ACTIV = abap_false. endif. WHEN 'ABAPCADABRA'. CALL FUNCTION 'CALL_BROWSER' EXPORTING URL = 'http://abapcadabra.com/index.php/reporting/background-jobs/640-batchjob-scheduler' EXCEPTIONS OTHERS = 0. WHEN 'SLG1'. SET PARAMETER ID 'BALOBJ' FIELD co_slg0_object. SET PARAMETER ID 'BALSUBOBJ' FIELD co_slg0_subobject. concatenate pa_jobna '*' into lcl_controller=>gv_scheduler_jobname_mask. SET PARAMETER ID 'BALEXT' FIELD lcl_controller=>gv_scheduler_jobname_mask. CALL TRANSACTION 'SLG1'. WHEN 'SET_STEP2'. pa_st1 = abap_true. WHEN 'PREVIEW'. submit ZABAPCADABRA_BATCH_SCHEDULER USING SELECTION-SET sy-slset with execute = '' AND RETURN. WHEN 'SCHEDULE_NOW'. submit ZABAPCADABRA_BATCH_SCHEDULER USING SELECTION-SET sy-slset with execute = 'SCHEDULE' with showlog = abap_true AND RETURN. WHEN 'RETRACT_NOW'. submit ZABAPCADABRA_BATCH_SCHEDULER USING SELECTION-SET sy-slset with execute = 'RETRACT' with showlog = abap_true AND RETURN. WHEN 'CONTROLS'. data: lt_SVAL type STANDARD TABLE OF SVAL, lw_SVAL type SVAL, lw_TVARVC_1 type TVARVC, lw_TVARVC_2 type TVARVC, lw_TVARVC_3 type TVARVC, lv_returncode type c. * Fetch values: from TVARV select single * from TVARVC into lw_TVARVC_1 where name = lcl_controller=>gc_tvarv_jobname and type = 'P' and numb = 0000. if sy-subrc <> 0. clear lw_TVARVC_1. lw_TVARVC_1-name = lcl_controller=>gc_tvarv_jobname. lw_TVARVC_1-type = 'P'. lw_TVARVC_1-numb = 0000. endif. clear: lt_SVAL[], lw_SVAL. lw_SVAL-TABNAME = 'TBTCO'. lw_SVAL-FIELDNAME = 'JOBNAME'. lw_SVAL-VALUE = lw_TVARVC_1-low. append lw_SVAL to lt_SVAL. select single * from TVARVC into lw_TVARVC_2 where name = lcl_controller=>gc_tvarv_authusr and type = 'P' and numb = 0000. if sy-subrc <> 0. clear lw_TVARVC_2. lw_TVARVC_2-name = lcl_controller=>gc_tvarv_authusr. lw_TVARVC_2-type = 'P'. lw_TVARVC_2-numb = 0000. endif. clear: lw_SVAL. lw_SVAL-TABNAME = 'TBTCJOB'. lw_SVAL-FIELDNAME = 'AUTHCKNAM'. lw_SVAL-VALUE = lw_TVARVC_2-low. append lw_SVAL to lt_SVAL. select single * from TVARVC into lw_TVARVC_3 where name = lcl_controller=>gc_tvarv_savelog and type = 'P' and numb = 0000. if sy-subrc <> 0. clear lw_TVARVC_3. lw_TVARVC_3-name = lcl_controller=>gc_tvarv_savelog. lw_TVARVC_3-type = 'P'. lw_TVARVC_3-numb = 0000. endif. clear: lw_SVAL. lw_SVAL-TABNAME = '/ISDFPS/CFDPSA06'. lw_SVAL-FIELDNAME = 'AC_MSG_SAVE'. lw_SVAL-VALUE = lw_TVARVC_3-low. append lw_SVAL to lt_SVAL. * Show controls popup CALL FUNCTION 'POPUP_GET_VALUES' EXPORTING POPUP_TITLE = 'Batch job scheduler - controls' IMPORTING RETURNCODE = lv_returncode TABLES FIELDS = lt_SVAL EXCEPTIONS OTHERS = 4. IF SY-SUBRC <> 0 or LV_RETURNCODE = 'A'. message 'Action cancelled' type 'S'. ELSE. read table lt_SVAL index 1 into lw_SVAL. lw_TVARVC_1-low = lw_SVAL-VALUE. *---------------------------------------------------- * Update the TVARV variabele modify TVARVC from lw_TVARVC_1. *---------------------------------------------------- if sy-subrc <> 0. message 'Control settings - UPDATE ERROR' type 'W'. else. read table lt_SVAL index 2 into lw_SVAL. lw_TVARVC_2-low = lw_SVAL-VALUE. *---------------------------------------------------- * Update the TVARV variabele modify TVARVC from lw_TVARVC_2. *---------------------------------------------------- if sy-subrc <> 0. message 'Control settings - UPDATE ERROR' type 'W'. else. read table lt_SVAL index 3 into lw_SVAL. lw_TVARVC_3-low = lw_SVAL-VALUE. *---------------------------------------------------- * Update the TVARV variabele modify TVARVC from lw_TVARVC_3. *---------------------------------------------------- if sy-subrc <> 0. message 'Control settings - UPDATE ERROR' type 'W'. else. message 'Control settings changed' type 'S'. endif. endif. endif. ENDIF. ENDCASE. CLASS lcl_calendar DEFINITION. PUBLIC SECTION. TYPES: BEGIN OF ty_calendar, date TYPE sy-datum, dow type n LENGTH 1, "1 = Monday ! job_icon type icon-id, starttime type t, jobname type tbtcp-JOBNAME, status type c length 30, jobcount type TBTCJOB-jobcount, actioncode type c length 3, colors TYPE lvc_t_scol, END OF ty_calendar. CLASS-DATA: gt_calendar TYPE STANDARD TABLE OF ty_calendar, * Variables for ALV display support go_alv TYPE REF TO cl_salv_table. CLASS-METHODS: compose_runbook importing workdate type d default sy-datum, jobstatus, alv_report, schedule, retract. ENDCLASS. CLASS lcl_calendar IMPLEMENTATION. method compose_runbook. types: begin of ty_weekday, dow type n LENGTH 1, "1 = Monday ! start type t, finish type t, period type t, end of ty_weekday, begin of ty_runbook_entry, dow type n LENGTH 1, "1 = Monday ! start type t, end of ty_runbook_entry. data: lt_weekdays type standard table of ty_weekday, lw_weekday type ty_weekday, lt_runbook_entries type standard table of ty_runbook_entry, lw_runbook_entry type ty_runbook_entry, lv_time_prepper type c length 6, lv_lines type sy-tabix, lv_start_time type t, lw_calendar type ty_calendar, lv_daynr type HRVSCHED-DAYNR. define set_weekday. lw_weekday-dow = &1. concatenate &2(2) &2+3(2) '00' into lv_time_prepper. lw_weekday-start = lv_time_prepper. concatenate &3(2) &3+3(2) '00' into lv_time_prepper. lw_weekday-finish = lv_time_prepper. concatenate &4(2) &4+3(2) '00' into lv_time_prepper. lw_weekday-period = lv_time_prepper. append lw_weekday to lt_weekdays. end-of-definition. define set_week. if PA_ACT&1 = abap_true and pa_frm&1 < pa_til&1. if PA_MON&1 = abap_true. set_weekday 1 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_TUE&1 = abap_true. set_weekday 2 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_WED&1 = abap_true. set_weekday 3 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_THU&1 = abap_true. set_weekday 4 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_FRI&1 = abap_true. set_weekday 5 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_SAT&1 = abap_true. set_weekday 6 pa_frm&1 pa_til&1 pa_per&1. endif. if PA_SUN&1 = abap_true. set_weekday 7 pa_frm&1 pa_til&1 pa_per&1. endif. endif. end-of-definition. clear: lt_weekdays[]. * The information that is currenly on the selection screen is used to compose a * "runbook" - which is effectively a list of runtimes in the fore-seeable future. set_week: 01, 02, 03, 04, 05, 06, 07, 08. sort lt_weekdays. DELETE ADJACENT DUPLICATES FROM lt_weekdays. * Step 2: transform periods into an actual hitlist: clear: lt_runbook_entries[]. loop at lt_weekdays into lw_weekday. lw_runbook_entry-dow = lw_weekday-dow. * Then run through the periods, until the end-time is reached: while lw_weekday-start <= lw_weekday-finish. lw_runbook_entry-start = lw_weekday-start. append lw_runbook_entry to lt_runbook_entries. lv_start_time = lw_weekday-start. * No period = no repetition. if lw_weekday-period is initial. exit. else. add lw_weekday-period to lw_weekday-start. if lv_start_time > lw_weekday-start. * Midnight has passed.. exit. endif. endif. endwhile. endloop. * Health check: remove double entries and throw message when doubles are removed: lv_lines = lines( lt_runbook_entries ). sort lt_runbook_entries. delete ADJACENT DUPLICATES FROM lt_runbook_entries. if lv_lines < lines( lt_runbook_entries ). message 'Overlapping entries removed from week calendar' type 'S'. endif. * Step 3: transform the findings into a calendar, for the workdate CALL FUNCTION 'RH_GET_DATE_DAYNAME' EXPORTING LANGU = sy-langu DATE = workdate IMPORTING DAYNR = lv_daynr EXCEPTIONS OTHERS = 4. IF SY-SUBRC = 0. loop at lt_runbook_entries into lw_runbook_entry where dow = lv_daynr. lw_calendar-date = workdate. lw_calendar-dow = lv_daynr. lw_calendar-job_icon = ICON_BACKGROUND_JOB. lw_calendar-starttime = lw_runbook_entry-start. append lw_calendar to gt_calendar. endloop. ENDIF. endmethod. method jobstatus. data: lv_jobname type TBTCO-JOBNAME, lw_calendar type ty_calendar, lw_TBTCJOB type TBTCJOB, lw_color_field type lvc_s_scol. define dimm_field_colors. lw_color_field-color-col = 3. lw_color_field-color-int = 0. lw_color_field-color-inv = 1. lw_color_field-fname = 'JOB_ICON'. append lw_color_field to lw_calendar-colors. lw_color_field-fname = 'STARTTIME'. append lw_color_field to lw_calendar-colors. lw_color_field-fname = 'JOBNAME'. append lw_color_field to lw_calendar-colors. lw_color_field-fname = 'STATUS'. append lw_color_field to lw_calendar-colors. lw_color_field-fname = 'JOBCOUNT'. append lw_color_field to lw_calendar-colors. end-of-definition. * This method determines which of the jobs on the schedule are already sheduled, by * checking the status of scheduled jobs concatenate pa_jobna pa_jobva into lv_jobname. lcl_job_utility=>job_select( jobname = lv_jobname ). * Status of the jobs loop at gt_calendar into lw_calendar. lw_calendar-jobname = lv_jobname. * Check whether the job is available read table LCL_JOB_UTILITY=>GT_JOBLIST into lw_TBTCJOB with key SDLSTRTDT = lw_calendar-date SDLSTRTTM = lw_calendar-starttime. if sy-subrc = 0. if lw_calendar-starttime <= sy-uzeit. dimm_field_colors. endif. lw_calendar-status = 'Scheduled'. lw_calendar-jobcount = lw_TBTCJOB-jobcount. else. if lw_calendar-starttime <= sy-uzeit. dimm_field_colors. else. lw_calendar-actioncode = 'CRE'. endif. lw_calendar-status = 'NOT Scheduled'. endif. modify gt_calendar from lw_calendar. endloop. endmethod. 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 TYPE REF TO cl_salv_column, * The footer box rf_alv_header TYPE REF TO cl_salv_form_layout_grid, rf_alv_footer TYPE REF TO cl_salv_form_layout_grid, lv_string type string. 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 ). END-OF-DEFINITION. DEFINE set_hidden_field. set_text_field &1 &2. rf_column->set_visible( abap_false ). END-OF-DEFINITION. try. cl_salv_table=>factory( importing r_salv_table = go_alv changing t_table = gt_calendar ). 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: 'DATE' 'Datum', 'JOBNAME' 'Job name', 'DOW' 'DOW', 'ACTIONCODE' 'Action code'. set_text_field: 'JOB_ICON' '___', 'STARTTIME' 'Start time', 'STATUS' 'Status', 'JOBCOUNT' 'Jobnumber'. CREATE OBJECT rf_alv_header. rf_alv_header->create_text( text = 'Batchjob name: ' row = 1 column = 1 ). * rf_layout_data ?= rf_text->get_layout_data( ). * rf_layout_data->set_h_align( if_salv_form_c_h_align=>right ). rf_alv_header->create_text( text = pa_jobna && pa_jobva row = 1 column = 2 ). rf_alv_header->create_text( text = 'Variant on scheduler: ' row = 2 column = 1 ). concatenate pa_jobva pa_jobvt into lv_string SEPARATED BY space. rf_alv_header->create_text( text = lv_string row = 2 column = 2 ). rf_alv_header->create_text( text = 'Schedule for: ' row = 3 column = 1 ). rf_alv_header->create_text( text = sy-datum row = 3 column = 2 ). 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 ). go_alv->display( ). catch CX_SALV_MSG CX_SALV_DATA_ERROR CX_SALV_NOT_FOUND. message 'ALV error' type 'S'. endtry. endmethod. method schedule. data: lw_calendar type ty_calendar. * Schedule the jobs that need to be scheduled, based on the information in gt_calendar loop at gt_calendar into lw_calendar where starttime > sy-uzeit and jobcount = space. lcl_logging=>set_message( message = 'Batch job & start time &' par1 = lw_calendar-jobname par2 = lcl_logging=>formatter( input = lw_calendar-starttime format = 'TIME' ) ). * Open the job *------------------------------------------------------------------------------ if lcl_job_utility=>job_open( lw_calendar-jobname ) = abap_false. *------------------------------------------------------------------------------ lcl_logging=>set_error( 'Could not open job' ). else. * Set step details *------------------------------------------------------------------------------ if lcl_job_utility=>job_submit( report = pa_step1 variant = pa_vari1 ) = abap_false. *------------------------------------------------------------------------------ lcl_logging=>set_error( message = 'Could not add step & variant &' par1 = pa_step1 par2 = pa_vari1 ). else. if not pa_step2 is initial. *------------------------------------------------------------------------------ if lcl_job_utility=>job_submit( report = pa_step2 variant = pa_vari2 ) = abap_false. *------------------------------------------------------------------------------ lcl_logging=>set_error( message = 'Could not add step & variant &' par1 = pa_step2 par2 = pa_vari2 ). continue. "Process the next gt_calendar entry endif. endif. * Close the job *------------------------------------------------------------------------------ if lcl_job_utility=>job_close( start_date = sy-datum start_time = lw_calendar-starttime targetserver = pa_serve ) = abap_false. *------------------------------------------------------------------------------ lcl_logging=>set_error( 'Could not complete the job' ). else. lcl_logging=>set_message( 'Batch job scheduled' ). endif. endif. endif. endloop. if sy-subrc <> 0. lcl_logging=>set_message( 'Nothing to do' ). endif. endmethod. method retract. * Remove the jobs that are not started yet data: lw_calendar type ty_calendar. * Schedule the jobs that need to be scheduled, based on the information in gt_calendar loop at gt_calendar into lw_calendar where starttime > sy-uzeit and jobcount <> space. lcl_logging=>set_message( message = 'Batch job & start time &' par1 = lw_calendar-jobname par2 = lcl_logging=>formatter( input = lw_calendar-starttime format = 'TIME' ) ). * Open the job *------------------------------------------------------------------------------ if lcl_job_utility=>job_delete( jobname = lw_calendar-jobname jobcount = lw_calendar-jobcount ) = abap_false. *------------------------------------------------------------------------------ lcl_logging=>set_error( message = 'Could not delete batch job &' par1 = lw_calendar-jobcount ). else. lcl_logging=>set_message( message = 'Batch job & retracted (deleted)' par1 = lw_calendar-jobcount ). endif. endloop. if sy-subrc <> 0. lcl_logging=>set_message( 'Nothing to do' ). endif. endmethod. ENDCLASS. *--------------------------------------------------------------------- * 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 (no use * of the report text-pool). Reason: easy copying of report source code. lbl_abca = '@N5\QMore on AbapcadabrA.com@'. live_btn = '@AJ\QControls@'. lbl_01 = 'Jobname'. lbl_01b = 'Jobclass'. lbl_01c = 'Server'. lbl_02 = 'Step'. lbl_02b = 'Variant'. stp2_btn = '@B8\QAdd step@'. lbl_03 = 'Step 2'. lbl_03b = 'Variant'. lbl_04 = 'Run on'. lbl_k1 = 'Active'. lbl_k2 = 'At/From'. lbl_k3 = 'To'. lbl_k4 = 'Every'. lbl_d1 = 'Mon'. lbl_d2 = 'Tue'. lbl_d3 = 'Wed'. lbl_d4 = 'Thu'. lbl_d5 = 'Fri'. lbl_d6 = 'Sat'. lbl_d7 = 'Sun'. * When the MASTER variant is used the selection screen transforms: lbl_10 = '@0S@ Schedule this report in the background to activate the scheduler'. lbl_11 = 'Batchjob name'. pushbut1 = 'Preview'. pushbut2 = 'Schedule now'. pushbut3 = 'Retract now'. pushbut4 = 'Application log'. *--------------------------------------------------------------------- * S T A R T - O F - S E L E C T I O N *--------------------------------------------------------------------- START-OF-SELECTION. * The MASTER runs should be scheduled with variant "Master". if sy-slset = 'MASTER'. lcl_logging=>initialize( ). lcl_logging=>set_subject( 'Batch scheduler' ). * Select all the active variants: lcl_controller=>get_active_variants( ). * HAZARD - the active variants are KNOWN, now process them... data: lw_varid type varid. loop at lcl_controller=>gt_varid into lw_varid. lcl_logging=>set_message( message = 'Report & with variant &' par1 = lw_varid-report par2 = lw_varid-variant ). submit ZABAPCADABRA_BATCH_SCHEDULER USING SELECTION-SET lw_varid-variant with execute = 'SCHEDULE' with showlog = abap_false AND RETURN. endloop. lcl_logging=>go_log->display( ). else. if sy-datum in so_onair. lcl_calendar=>compose_runbook( ). lcl_calendar=>jobstatus( ). endif. case EXECUTE. when space. if not lcl_calendar=>gt_calendar[] is initial. lcl_calendar=>alv_report( ). else. message 'Schedule preview: no information to report' type 'S'. endif. when 'SCHEDULE'. if pa_activ = abap_true. lcl_logging=>initialize( extid = pa_jobna && pa_jobva ). lcl_logging=>set_subject( 'Batch scheduler - execute = SCHEDULE' ). lcl_logging=>set_message( message = 'Batch scheduler - for variant &' par1 = sy-slset ). lcl_calendar=>schedule( ). if SHOWLOG = abap_true. lcl_logging=>go_log->display( ). endif. if LCL_CONTROLLER=>GV_SCHEDULER_SAVELOGS = abap_true. lcl_logging=>go_log->save( ). endif. else. message 'No scheduling: calendar is not active' type 'S'. endif. when 'RETRACT'. lcl_logging=>initialize( extid = pa_jobna && pa_jobva ). lcl_logging=>set_subject( 'Batch scheduler - execute = RETRACT' ). lcl_logging=>set_message( message = 'Batch scheduler - for variant &' par1 = sy-slset ). lcl_calendar=>retract( ). if SHOWLOG = abap_true. lcl_logging=>go_log->display( ). endif. if LCL_CONTROLLER=>GV_SCHEDULER_SAVELOGS = abap_true. lcl_logging=>go_log->save( ). endif. endcase. endif.