Or you can trigger from OS level with the sapevt program.
Schedule job with event trigger
Now we will schedule the job in SM36 using a test program ZHELLOEVENT. In the job definition we will run the program ZHELLOEVENT. In the scheduling we will use the start condition After Event:
When you trigger the event now in SM36 you see the job will execute nicely. Go to transaction SM37 and key in the Or after event search option:
You will now find the jobs after the event triggering.
Jobs waiting for a trigger
To find batch jobs that are still waiting for a trigger, use SE11 to see the content of table BTCEVTJOB.
Reorganization of batch jobs events
Settings are done in SM64:
Run background program RSEVTHISTREORG for the clean up.
In quite some cases the basis team is asked: in which batch job variant is this company code XXXX used? Or we need to add another sales organization to all the batch jobs, can you provide us a list with jobs using sales organization YYYY?
* _____________________________________________________________________ *| T A B L E S | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ TABLES: trdir, tadir.
* _____________________________________________________________________ *| T Y P E S | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ TYPES: BEGIN OF ty_source, line(255) TYPE c, END OF ty_source.
TYPES: BEGIN OF ty_objname, obj_name TYPE sobj_name, END OF ty_objname.
TYPES: BEGIN OF ty_variant, variant TYPE variant, END OF ty_variant.
* _____________________________________________________________________ *| I T A B S & W O R K A R E A S | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ DATA: gt_selop TYPE STANDARD TABLE OF vanz, gt_params TYPE STANDARD TABLE OF vanz, gt_params_nonv TYPE STANDARD TABLE OF vanz, gt_selop_nonv TYPE STANDARD TABLE OF vanz, gs_vanz TYPE vanz, lv_text TYPE string, gv_report TYPE vari_reprt, mv_report TYPE vari_reprt, gt_variant TYPE STANDARD TABLE OF ty_variant, gs_variant TYPE ty_variant, gv_program TYPE syrepid, gv_subrc TYPE sysubrc, gt_reports TYPE STANDARD TABLE OF trdir, gs_reports TYPE trdir, gt_valuetab TYPE STANDARD TABLE OF rsparams, gt_objname TYPE STANDARD TABLE OF ty_objname.
FIELD-SYMBOLS: <fs_vanz> TYPE vanz. * _____________________________________________________________________ *| S E L E C T I O N - S C R E E N | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ SELECTION-SCREEN BEGIN OF BLOCK aa WITH FRAME. SELECTION-SCREEN BEGIN OF BLOCK bb WITH FRAME TITLE text-t01. PARAMETERS: ra_srch RADIOBUTTON GROUP a1 USER-COMMAND tab1 DEFAULT 'X', ra_srch2 RADIOBUTTON GROUP a1, ra_wday RADIOBUTTON GROUP a1, ra_synt RADIOBUTTON GROUP a1, ch_all AS CHECKBOX MODIF ID a2. SELECTION-SCREEN END OF BLOCK bb. SELECT-OPTIONS: so_prog FOR trdir-name. PARAMETERS: p_string TYPE s_text MODIF ID a1. SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF BLOCK cc WITH FRAME. PARAMETERS: pa_prog TYPE program, pa_local AS CHECKBOX. SELECTION-SCREEN END OF BLOCK cc. SELECTION-SCREEN END OF BLOCK aa.
* _____________________________________________________________________ *| A T S E L E C T I O N - S C R E E N O U T P U T | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN. CASE screen-group1. WHEN 'A1'.
IF ra_srch IS INITIAL AND ra_srch2 IS INITIAL. CLEAR p_string. screen-input = '0'. ELSE. screen-input = '1'. ENDIF. WHEN 'A2'. IF ra_synt = 'X'. screen-input = '1'.
* _____________________________________________________________________ *| S T A R T - O F - S E L E C T I O N | * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ START-OF-SELECTION. IF ( NOT ra_srch IS INITIAL OR NOT ra_srch2 IS INITIAL ) AND p_string IS INITIAL. MESSAGE e001(00) WITH 'No string entered'. ENDIF.
PERFORM select_programs. PERFORM select_variants.
END-OF-SELECTION.
*&---------------------------------------------------------------------* *& Form SELECT_PROGRAMS *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM select_programs.
DATA: lv_tabix TYPE sytabix, lv_lines TYPE i.
*-Only executable programs are taken into account IF ch_all IS INITIAL. SELECT * FROM trdir INTO TABLE gt_reports WHERE name IN so_prog AND subc = '1'.
*-For syntax checking you can also include other program types ELSE. SELECT * FROM trdir INTO TABLE gt_reports WHERE name IN so_prog. ENDIF.
SORT gt_reports BY name. DESCRIBE TABLE gt_reports LINES lv_lines.
*-check if the user wants to start from a certain program *-(so skip all preceding programs) IF NOT pa_prog IS INITIAL.
READ TABLE gt_reports WITH KEY name = pa_prog TRANSPORTING NO FIELDS. IF sy-subrc = 0. lv_tabix = sy-tabix + 1. IF lv_tabix < lv_lines. *- Delete all preceding reports including the start from report DELETE gt_reports FROM 1 TO lv_tabix. ENDIF. ENDIF.
ENDIF.
IF gt_reports[] IS INITIAL. MESSAGE s001(00) WITH 'No reports selected'. WRITE:/ 'No reports selected'. ENDIF.
ENDFORM. " SELECT_PROGRAMS *&---------------------------------------------------------------------* *& Form SELECT_VARIANTS *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM select_variants .
DATA: lt_results TYPE STANDARD TABLE OF rsvobs, lv_found TYPE flag.
REFRESH gt_objname.
CHECK NOT gt_reports[] IS INITIAL.
*-retrieve already all details for quicker reading IF pa_local = 'X'. "Exclude local programs SELECT obj_name INTO TABLE gt_objname FROM tadir FOR ALL ENTRIES IN gt_reports WHERE pgmid = 'R3TR' AND object = 'PROG' AND obj_name = gt_reports-name. ELSE. "Include local programs SELECT obj_name INTO TABLE gt_objname FROM tadir FOR ALL ENTRIES IN gt_reports WHERE pgmid = 'R3TR' AND object = 'PROG' AND obj_name = gt_reports-name AND devclass <> '$TMP'. ENDIF.
LOOP AT gt_reports INTO gs_reports.
READ TABLE gt_objname WITH KEY obj_name = gs_reports-name TRANSPORTING NO FIELDS. CHECK sy-subrc = 0.
gv_program = gv_report = gs_reports-name.
*=====================================================================* *- PERFORM A SYNTAX CHECK FOR PROGRAM *=====================================================================* *- Get the source code of the report for syntax checking PERFORM program_syntax_check USING gv_program CHANGING gv_subrc.
*- Skip programs with syntax errors for further variant checking IF gv_subrc <> 0. IF ra_synt = 'X'. MESSAGE s000(3w) WITH 'SYNTAX ERROR==>' gv_report. WRITE:/ gv_report, 50 'CONTAINS SYNTAX ERROR'. ELSE. CONTINUE. ENDIF. ENDIF.
*---------------------------------------------------------------------* *- Only process variants for select-options search and working days *---------------------------------------------------------------------* CHECK ra_srch = 'X' OR ra_srch2 = 'X' OR ra_wday = 'X'.
*- Select variants for a program *- (exclude the very old ones and also the standard SAP ones) SELECT variant INTO TABLE gt_variant FROM varid WHERE report = gv_report AND ( edat > 20100101 OR aedat > 20100101 ) AND ( ename <> 'SAP' AND aename <> 'SAP' ).
CHECK NOT gt_variant[] IS INITIAL. REFRESH lt_results.
*- Process all variants LOOP AT gt_variant INTO gs_variant. CLEAR lv_found.
*- Give a message to indicate which program/variant is being checked *- (comes in handy in case the program cancels during the check as *- you can then restart this program starting from the object that *- dumped) MESSAGE s000(3w) WITH 'Checking' gv_report '-' gs_variant-variant.
*=====================================================================* *- SEARCH VARIANTS FOR A CERTAIN FIELD VALUE IF ra_srch = 'X'. *=====================================================================* FIND FIRST OCCURRENCE OF p_string IN TABLE gt_valuetab IN CHARACTER MODE. IF sy-subrc = 0. CONCATENATE 'String' p_string 'found' INTO lv_text SEPARATED BY space. MESSAGE s000(3w) WITH 'FOUND:' gv_report gs_variant-variant lv_text.
*=====================================================================* *- SEARCH VARIANTS FOR A CERTAIN FIELD NAME OR FIELD DESCRIPTION ELSEIF ra_srch2 = 'X'. *=====================================================================* *- Check select-options field names and descriptions for a *- certain string LOOP AT gt_selop ASSIGNING <fs_vanz>. FIND FIRST OCCURRENCE OF p_string IN <fs_vanz>-name IN CHARACTER MODE. IF sy-subrc = 0. lv_found ='X'. EXIT. ENDIF. ENDLOOP.
IF lv_found IS INITIAL. LOOP AT gt_selop_nonv ASSIGNING <fs_vanz>. FIND FIRST OCCURRENCE OF p_string IN <fs_vanz>-name IN CHARACTER MODE. IF sy-subrc = 0. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF.
IF lv_found IS INITIAL. LOOP AT gt_params ASSIGNING <fs_vanz>. FIND FIRST OCCURRENCE OF p_string IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF.
IF lv_found IS INITIAL. LOOP AT gt_params_nonv ASSIGNING <fs_vanz>. FIND FIRST OCCURRENCE OF p_string IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF.
IF lv_found = 'X'. CONCATENATE 'String' p_string 'found' INTO lv_text SEPARATED BY space. MESSAGE s000(3w) WITH 'FOUND:' gv_report gs_variant-variant lv_text. WRITE:/ 'FOUND:', 7 gv_report, 50 gs_variant-variant, 80 lv_text. ENDIF.
*=====================================================================* *- SEARCH VARIANTS FOR VARIABLES THAT REQUIRE CALENDAR ENTRY ELSEIF ra_wday = 'X'. *=====================================================================* LOOP AT gt_selop INTO gs_vanz WHERE vname <> ''. IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'. lv_found ='X'. EXIT. ENDIF. ENDLOOP. IF lv_found IS INITIAL. LOOP AT gt_selop_nonv INTO gs_vanz WHERE vname <> ''. IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF. IF lv_found IS INITIAL. LOOP AT gt_params INTO gs_vanz WHERE vname <> ''. IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF. IF lv_found IS INITIAL. LOOP AT gt_params_nonv INTO gs_vanz WHERE vname <> ''. IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'. lv_found ='X'. EXIT. ENDIF. ENDLOOP. ENDIF.
ENDFORM. " SELECT_VARIANTS *&---------------------------------------------------------------------* *& Form PROGRAM_SYNTAX_CHECK *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * <--P_LV_SUBRC text *----------------------------------------------------------------------* FORM program_syntax_check USING p_program CHANGING p_subrc.
If a batch job step user is locked or deleted, that step will fail. To find batch jobs with deleted or locked step users, start program BTCAUX09:
This will give a full list of jobs that you might want to start analyzing for deletion:
Why clean up? You will most likely find a lot of jobs in Scheduled status that never ran and are planned very long time ago. All batch job related transactions will have to plough through this irrelevant data.
When a batch job finishes, there are use cases where you want to be informed on the results.
Questions that will be answered in this blog are:
How can I mail the spool result of a batch job?
How can I mail if the job went ok or not?
Mailing job status
As of version S4HANA 1709 (basis version 7.52), you can mail the batch job result for cancelled jobs, or in all cases when it finishes. In SM37 after job is planned goto change mode of the job and push the E-mail Notification button:
In SJOBREPO, more background information can be found by clicking the button Monitor help:
A very important remark is made here that it can take up to 1 hour before changes to SJOBREPO are visible in the monitoring overview. This is a very annoying feature.
This blog will explain how to debug a background batch program with real background mode (SY-BATCH is X).
Questions that will be answered are:
How to debug a running job?
How to debug a completed job?
Starting the debug mode for batch job
First we plan a single run of the batch job. In our example we run program RSWAITSEC which does nothing more than wait.
In SM37 show the job run:
Select the job and in the command line enter the background debug command JDBG:
Now the debugger starts first in the batch job part. Hit F7 a few time (F7 = jump back out of routine) until you reach the real program:
As you can see here the SY-BATCH variable is X, which means you are debugging with real background mode on.
SM50 background debugging
If you want to debug a running job, you have to goto SM50 and select the background process. Then choose the menu option Administration / Program / Debugging. Confirm the prompt:
Wait until the running SQL statement has completed and debug mode will start.
Please be very careful with this kind of debugging in a productive system. If you cancel the debug session there might be a rollback work statement triggered, which can cause database inconsistencies.
If you want to prevent same job from starting, while a previous instance is still running, you need to add program RSBTONEJOB or RSBTONEJOB2 as first step in the batch job. This step will detect if the previous instance is still running and abort to avoid the next steps from being executed. More background in OSS note 557610. The scope of both programs is in principle limited to be used for idocs and CUA. To extend the scope or in case of issues, read the instructions in note 3225033 – Behavior of program RSBTONEJOB, RSBTONEJOB2 not as expected.
Forcing a batch program to wait
If for some reason you need a batch program to wait between steps, you can use program RSWAITSEC as a step. This program will only do a wait for x amount of seconds.
Setting current date in the TVARVC table for the RV variables
The RV variables for current date, month and year are often used in month end closing batch jobs. Running program RVSETDAT will set the current dates for RV TVARC variables.
Checking basis background job system settings and working
If you want to validate if the background job system function itself is working properly, start transaction SM65 background processing analysis tool.
Result is shown correct working, number of batches and wait time:
Start transaction ST13 and start tool BACKGROUND_JOB_ANALYSIS. Or directly start program /SSA/BTC.
Pending on your selection you get a graphical overview or a full list for you to speed up your analysis.
Mass stop and start of batch jobs
Programs BTCTRNS1 and BTCTRNS2 can be used for mass forced stop and start of batch jobs. See this blog for more details.
Batch job interception
For more information on batch job interception, please read this blog.
Ignoring large spool output of a batch job
In some cases a batch job will generate a large amount of spool output which is clogging the spool system, but is never used. In this case you can set up the job to put the output to output device NULL. For setup read this blog.
Archiving spool as print list
If you want to store the spool as print list in the archive, please read this blog.
If you want to quickly check which user ID’s are use inside batch job steps, it is best to quickly go to table TBTCP. Here you can quickly see across many batch jobs which step users are used.
Check batch job headers
Sometimes you need to report and check data on batch job header level. This data is stored in table TBTCO. Example: if you have performance issues with jobs and you have multiple application servers, you can use table TBTCO to check on which application server the troublesome jobs are running.
Solving inconsistencies in batch job tables
In rare cases there might be inconsistencies in the batch job tables TBTCO and TBTCS. In this case you need to run program RSBTCCNS to check and delete the inconsistencies.
You can mail the spool result of a batch job to one or more mail addresses. Also with newer SAP netweaver versions you can mail if job was successful or not. Read this blog in detail.
Debugging batch jobs
For debugging batch jobs, please read this dedicated blog.
Batch jobs full
If there are no batch processes free any more, you might see this screen in SM37:
When you face this situation check in SM66 if there are BTC processes available.
Standard batch jobs in S4HANA are planned via transaction SJOBREPO. For more details read the dedicated blog.
Batch job server groups
If you have a large production system with many application servers you can setup batch job server groups to have batch jobs run on a set of dedicated application servers. To set up batch job server groups start transaction SM61 and click the button Job server groups:
In quite some cases the basis team is asked: in which batch job variant is this company code XXXX used? Or we need to add another sales organization to all the batch jobs, can you provide us a list with jobs using sales organization YYYY? How to get this data is answered in this dedicated blog.
How to check health of batch job scheduler
Start transaction SM61. Now select the Time-Driven scheduler. Select the server and choose the health check tab. Now press the check button:
Batch job event triggers
Batch jobs can also be triggered using events. Read more in this blog on batch job event triggers.
Mass job changes
Mass job changes can be done via program BTC_MASS_JOB_CHANGE. Changes with mass changes options variants, step and job user, execution target.
Batch job monitoring
Batch job monitoring can be done with SAP Focused Run. Read more in this blog.
Transaction codes
Transaction codes that can help:
SM37: generic batch job transaction
SM37DSIP: generic batch job transaction, display only
This blog will explain how to setup SAP batch job interception.
Questions that will be answered in this blog are:
How to activate SAP batch job interception?
How does an intercepted job look like?
Activating SAP batch job interception
Before you can begin the setup of the batch job interception you must run program INITXBP2 in SE38:
Next you have to start transaction CRIT and create the profiles.
First create the default SAP profile by clicking on the SAP logo. Activate it. Next step is to create the profile in which you want to do the interception. In the screen above click on the create profile button. Now enter a criteria. For simplicity we have called it interception. In our case we intercept all except a list of authorized users. In the user list we include the basis users and the background users (in this example WF-BATCH). Save the data.
Next step is to activate this profile:
Working of interception
When a batch job is planned the interception checks if the job should be intercepted or not. As a test logon as end user and launch a job. In our case the user ENDUSER tries to launch a job from SLG2 transaction to delete application logs. This jobs is intercepted and shows like this in SM37:
The job does not start immediately, but shows in intercepted state. If user with release rights now goes to SM37 for this job, he can release the intercepted job.
This blog explains how to mass stop and mass start batch jobs as admin. This especially useful putting the SAP system in maintenance mode. Maintenance mode can be needed for upgrade, support package patching or data conversion.
Questions that will be answered are:
How to mass stop batch jobs?
Can I plan new jobs I need during the suspend mode?