SAP Background Job History Report Generator: TBTCO and TBTCP in ABAP
This generator builds an ABAP report for SAP ECC 6.0 that lists background jobs from TBTCO (job header) joined to TBTCP (job steps), filtered by job name, program, status, step user and start date. It adds runtime in seconds and the last error message from the job log of cancelled jobs.
Fill in
A cancelled, F finished, R active, S released, * all
Report source (classic Open SQL, any ECC 6.0 release)
REPORT ZBC_JOB_HISTORY.
TYPES: BEGIN OF ty_result,
jobname TYPE tbtco-jobname,
jobcount TYPE tbtco-jobcount,
status TYPE tbtco-status,
strtdate TYPE tbtco-strtdate,
strttime TYPE tbtco-strttime,
enddate TYPE tbtco-enddate,
endtime TYPE tbtco-endtime,
sdluname TYPE tbtco-sdluname,
stepcount TYPE tbtcp-stepcount,
progname TYPE tbtcp-progname,
variant TYPE tbtcp-variant,
authcknam TYPE tbtcp-authcknam,
listident TYPE tbtcp-listident,
runtime_s TYPE i,
lastmsg TYPE tbtc5-text,
END OF ty_result.
DATA: lt_result TYPE STANDARD TABLE OF ty_result,
lt_log TYPE STANDARD TABLE OF tbtc5,
ls_log TYPE tbtc5,
lr_status TYPE RANGE OF tbtco-status,
ls_status LIKE LINE OF lr_status,
lr_user TYPE RANGE OF tbtcp-authcknam,
ls_user LIKE LINE OF lr_user,
lv_job TYPE tbtco-jobname,
lv_prog TYPE tbtcp-progname,
lv_text TYPE string,
lo_alv TYPE REF TO cl_salv_table,
lo_func TYPE REF TO cl_salv_functions_list,
lx_msg TYPE REF TO cx_salv_msg.
FIELD-SYMBOLS: <ls_res> TYPE ty_result.
PARAMETERS: p_job TYPE tbtco-jobname DEFAULT 'Z*',
p_prog TYPE tbtcp-progname DEFAULT '[Program name pattern (blank = all)]',
p_stat TYPE tbtco-status DEFAULT 'A',
p_from TYPE sy-datum DEFAULT '20261001',
p_to TYPE sy-datum DEFAULT '20261022',
p_user TYPE tbtcp-authcknam DEFAULT '[Step user (blank = all)]',
p_max TYPE i DEFAULT 500.
START-OF-SELECTION.
* Convert * wildcards to SQL LIKE wildcards
lv_job = p_job.
TRANSLATE lv_job USING '*%'.
IF lv_job IS INITIAL.
lv_job = '%'.
ENDIF.
lv_prog = p_prog.
TRANSLATE lv_prog USING '*%'.
IF lv_prog IS INITIAL.
lv_prog = '%'.
ENDIF.
* Empty range = no restriction
IF p_stat IS NOT INITIAL AND p_stat <> '*'.
ls_status-sign = 'I'.
ls_status-option = 'EQ'.
ls_status-low = p_stat.
APPEND ls_status TO lr_status.
ENDIF.
IF p_user IS NOT INITIAL.
ls_user-sign = 'I'.
ls_user-option = 'EQ'.
ls_user-low = p_user.
APPEND ls_user TO lr_user.
ENDIF.
SELECT a~jobname a~jobcount a~status a~strtdate a~strttime
a~enddate a~endtime a~sdluname
b~stepcount b~progname b~variant b~authcknam b~listident
INTO CORRESPONDING FIELDS OF TABLE lt_result
FROM tbtco AS a
INNER JOIN tbtcp AS b
ON b~jobname = a~jobname
AND b~jobcount = a~jobcount
UP TO p_max ROWS
WHERE a~jobname LIKE lv_job
AND a~status IN lr_status
AND a~strtdate BETWEEN p_from AND p_to
AND b~progname LIKE lv_prog
AND b~authcknam IN lr_user
ORDER BY a~strtdate DESCENDING a~strttime DESCENDING.
IF sy-subrc <> 0.
MESSAGE 'No jobs found for the selection' TYPE 'S'.
RETURN.
ENDIF.
LOOP AT lt_result ASSIGNING <ls_res>.
* Runtime: date difference in days plus time difference in seconds
IF <ls_res>-enddate IS NOT INITIAL.
<ls_res>-runtime_s = ( <ls_res>-enddate - <ls_res>-strtdate ) * 86400
+ ( <ls_res>-endtime - <ls_res>-strttime ).
ENDIF.
* Last error or abort message from the job log of cancelled jobs
IF <ls_res>-status = 'A'.
CLEAR lt_log.
CALL FUNCTION 'BP_JOBLOG_READ'
EXPORTING
client = sy-mandt
jobcount = <ls_res>-jobcount
jobname = <ls_res>-jobname
TABLES
joblogtbl = lt_log
EXCEPTIONS
OTHERS = 1.
IF sy-subrc = 0.
LOOP AT lt_log INTO ls_log WHERE msgtype = 'A' OR msgtype = 'E'.
<ls_res>-lastmsg = ls_log-text.
ENDLOOP.
ENDIF.
ENDIF.
ENDLOOP.
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_result ).
lo_func = lo_alv->get_functions( ).
lo_func->set_all( 'X' ).
lo_alv->display( ).
CATCH cx_salv_msg INTO lx_msg.
lv_text = lx_msg->get_text( ).
MESSAGE lv_text TYPE 'I'.
ENDTRY.Optional: strict Open SQL variant with INTO at the end (NW 7.40 SP08 and later)
* Replace the SELECT above with this form if your release supports it * SELECT a~jobname, a~jobcount, a~status, a~strtdate, a~strttime, * a~enddate, a~endtime, a~sdluname, * b~stepcount, b~progname, b~variant, b~authcknam, b~listident * FROM tbtco AS a * INNER JOIN tbtcp AS b * ON b~jobname = a~jobname * AND b~jobcount = a~jobcount * WHERE a~jobname LIKE @lv_job * AND a~status IN @lr_status * AND a~strtdate BETWEEN @p_from AND @p_to * AND b~progname LIKE @lv_prog * AND b~authcknam IN @lr_user * ORDER BY a~strtdate DESCENDING, a~strttime DESCENDING * INTO CORRESPONDING FIELDS OF TABLE @lt_result * UP TO @p_max ROWS.
Verify in SE11 that TBTCO and TBTCP carry the fields used here on your release and in SE37 that BP_JOBLOG_READ has the CLIENT, JOBCOUNT, JOBNAME and JOBLOGTBL parameters. Jobs that never started have an initial STRTDATE and are excluded by the date filter; select on SDLSTRTDT instead for scheduled jobs. Open SQL on TBTCO and TBTCP does not check batch authorizations, so the report shows every user's jobs: protect it with an authorization group or an AUTHORITY-CHECK on S_BTCH_JOB before you transport it.
Get a nightly failed-job digest
We can turn this query into a scheduled summary of failed jobs with likely causes, delivered to your support team.
Optional. The tool and every export work without this. No spam.
Where job data lives in ECC
TBTCO holds one row per job run, keyed by JOBNAME and JOBCOUNT, with the status, the user who scheduled it (SDLUNAME), planned start (SDLSTRTDT, SDLSTRTTM) and actual start and end (STRTDATE, STRTTIME, ENDDATE, ENDTIME). TBTCP holds one row per step, with PROGNAME, VARIANT, the step user AUTHCKNAM and the spool request number LISTIDENT. The job log is not a normal table: it is stored in the TemSe and read with BP_JOBLOG_READ, which returns lines of structure TBTC5. SM37 reads exactly these objects.
- Status values in TBTCO-STATUS: P scheduled, S released, Y ready, R active, F finished, A cancelled.
- To find which job runs a program, filter TBTCP-PROGNAME.
- LISTIDENT leads to the spool request in SP01.
How to use it
Enter the job and program patterns with * as wildcard, choose a status and a start date range, then copy the code into SE38. The selection screen defaults come from your inputs, so the same report can be reused with other values. The generated SELECT uses classic Open SQL without @ host variables so it compiles on every ECC 6.0 NetWeaver release; a strict-syntax version with the INTO clause at the end is included as a comment for 7.40 SP08 and later.
Worked example
To find every cancelled run of the stock extract this month, set job pattern Z*, program pattern ZMM_STOCK*, status A and dates 20261001 to 20261022. Each result row shows job name, job count, step program and variant, step user, start and end time and runtime_s. The lastmsg column holds the last E or A message from the job log, which is usually the real error, while the final log line is often only the generic job cancelled message.
Gotchas
A job with several steps returns one row per step, so counts of rows are not counts of jobs. Runtime across midnight works because the date difference is converted to seconds before the time difference is added. TBTCO grows fast on busy systems: keep the date range tight, and make sure the standard reorganisation job SAP_REORG_JOBS runs, otherwise both the report and SM37 slow down. Reading the job log for many cancelled jobs is the slowest part; lower max rows if needed.
Frequently Asked Questions
Which SAP table stores the background job with program name?
The program name is in TBTCP, field PROGNAME, one row per job step. Join it to TBTCO on JOBNAME and JOBCOUNT to get the job status, scheduler and start and end times. The generated report does this join and lets you filter by program pattern.
What is the batch job status table in SAP?
TBTCO holds the job status in field STATUS: P scheduled, S released, Y ready, R active, F finished and A cancelled. Each job run has its own JOBCOUNT, so a periodic job appears once per run. SM37 is the transaction view over the same data.
Where is the SAP batch job log stored?
The job log is stored in the TemSe, not as rows in a transparent table you can select directly. Use function module BP_JOBLOG_READ with job name and job count; it returns the log lines in table structure TBTC5 with date, time, message ID, number, type and text.
How do I find the batch job that runs a program?
Run the report with the program name in the program pattern and status * for all. Each row shows the job name and step. In SM37 you can also enter the program under the ABAP program name field of the extended selection, which reads TBTCP in the same way.
If you want Basis and support staff to ask which jobs failed overnight in plain English on your own servers, we can set that up over your ECC system.
Related Tools
SAP ECC Background Job Creation ABAP Generator (JOB_OPEN, SUBMIT, JOB_CLOSE)
Generate working ABAP that opens a job, submits a program with a variant and step user to a spool printer, and releases it immediately, at a date and time, or after an event.
SAPSAP Background Job Capacity Calculator
Estimate batch window utilisation, elapsed time and how many background work processes you need to finish nightly jobs.
SAPSAP Background Job Scheduling Template
A fill-in job request form that captures everything a Basis admin needs to schedule a background job in SM36 and monitor it in SM37.
Developer ToolsSAP ECC IDoc Segment Data Reader ABAP Generator (EDIDC, EDID4, EDIDS)
Choose a message type, basic type, segment and field, and get an ABAP report that lists IDocs, the value of that segment field and the last status message text.
More Developer Tools tools
See all- SAP ECC Enhancement Transactions and Exit Tables Reference (SMOD, CMOD, SE18, MODSAP, SXC_EXIT)
- SAP ECC Data Dictionary and Repository Tables Reference (DD02L, DD03L, T100, E070, TSTC)
- SAP ECC ABAP Runtime Errors (ST22 Dumps) and Error Log Transactions Reference
- SAP ECC Custom Inbound IDoc Function Module Skeleton Generator
- SAP ECC BAPI_SALESORDER_CHANGE ABAP Generator
- SAP ECC BAPI_PO_CHANGE ABAP Generator
- SAP ECC BAPI_MATERIAL_SAVEDATA Material Creation ABAP Generator
- SAP ECC BAPI_ACC_DOCUMENT_POST G/L and Vendor Posting ABAP Generator
- SAP ECC Condition Record Query ABAP Generator (Axxx Condition Tables + KONP)
Keep exploring
Free tools
- SAP ECC Background Job Tables Reference (TBTCO, TBTCP, Job Status Codes)Reference of the tables behind SM37 on SAP ECC 6.0: job header, steps, schedules, events, spool and variants, with joins, plus the TBTCO-STATUS values.
- SAP ECC Background Job Creation ABAP Generator (JOB_OPEN, SUBMIT, JOB_CLOSE)Generate working ABAP that opens a job, submits a program with a variant and step user to a spool printer, and releases it immediately, at a date and time, or after an event.
- SAP ECC Job Log, Spool and TBTCO Growth Housekeeping CalculatorEnter jobs per day, steps, spool share, average sizes and retention days to see how many job and spool rows you keep and how much TemSe storage they use in the database or file system.