Copyright 2024 - BV TallVision IT

Is sitting around until it's archived. Here's what you can do with it - allow the end user (several end users) to have a look at reporting output from a batch job, which itself is too slow to be executed directly by the end user (TIME_OUT)

Spool lists are a special topic in SAP. Batch jobs keep track of output in "spool files" for which quite special treatment is required. First of all, have a play around with transaction SM37 which is about batch job scheduling. Where reporting output is available, it can be listed. Note that during your program run, the number of the spool request is in ABAP memory in variabele SY-SPONO - Print list, spool number.

This number can be fed into function module RSPO_DISPLAY_SPOOLJOB - Display spool file contents, which would fetch the stored spool file from the batch job and dispay the output. I've copied this function module and used it after removing the authorization check - allowing the end user to view (only relevant) spool files for scheduled job runs. Effectively users that are not allowed to run a slow report in the background can still look at it's output via spool files. This can be a very effective way to save system resources...

The other function module to remember is another step back, the overview of available spool files for a given job, as displayed in transaction SM37 can be shown via function module RSPO_RID_SPOOLREQ_LIST- lists the available spool requests as shown in the job log.

This function module will fetch the spool output and display it to the end user. A copy of a standard SAP module was made to avoid an authorization check.. Original: RSPO_DISPLAY_SPOOLJOB.

FUNCTION Z_UX_DISPLAY_SPOOLJOB.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(RQIDENT) LIKE  TSP01-RQIDENT
*"     VALUE(FIRST_LINE) TYPE  I DEFAULT 1
*"     VALUE(LAST_LINE) TYPE  I OPTIONAL
*"     VALUE(SKIP_AUTHORIZATION_CHECK) LIKE  BAPIFLAG-BAPIFLAG OPTIONAL
*"  EXCEPTIONS
*"      NO_SUCH_JOB
*"      JOB_CONTAINS_NO_DATA
*"      SELECTION_EMPTY
*"      NO_PERMISSION
*"      CAN_NOT_ACCESS
*"      READ_ERROR
*"----------------------------------------------------------------------

*----------------------------------------------------------------------*
* Function mod. -  Z_UX_DISPLAY_SPOOLJOB                               *
* Description   -  Display spool contens for a given job               *
* Developer     -  Wim Maasdam                                         *
* Date          -  7th of March 2005                                   *
* SAP version   -  4.7 - 620                                           *
*----------------------------------------------------------------------*
* This function module is a copy of RSPO_DISPLAY_SPOOLJOB which allows *
* display of the spool of a background job. The only difference is the *
* processing of this functionality skipping an authorization check.    *
*                                                                      *
* For release changes: please consider a new copy of the above function*
* module before fixing any problems here.                              *
*----------------------------------------------------------------------*
* Amendment History                                                    *
* -----------------                                                    *
* Date     Developer   Ref      Description                            *
* ======== =========== ======== ====================================== *
* dd-mm-yy sap userid  DR num   desc                                   *
*                                                                      *
*----------------------------------------------------------------------*
  data: buffer like data_set_line occurs 1000.
  data: lcodepage like tst01-dcharcod.
  tables: tsp02l.

  select single * from tsp01 where rqident = rqident.
  if sy-subrc <> 0.
    message e126 with rqident raising no_such_job.
  endif.

  if SKIP_AUTHORIZATION_CHECK eq space.
    call function 'RSPO_CHECK_JOB_PERMISSION'
      EXPORTING
        access        = 'DISP'
        spoolreq      = tsp01
      EXCEPTIONS
        no_permission = 1
        others        = 2.
    if sy-subrc <> 0.
      route_exception no_permission.
    endif.
  endif.

  perform read_data tables buffer
                    using tsp01 first_line last_line
                    changing lcodepage.
  perform display_data tables buffer using tsp01-rqpaper tsp01-rqident
                                           lcodepage.
endfunction.

The following coding is to be set up in an include with the function module. Purpose: minimize changes in the copy of standard SAP (which should make an upgrade much easier). 

*----------------------------------------------------------------------*
* Include       -  LZUX_UTILITYF01                                     *
* Description   -  Form routines                                       *
*----------------------------------------------------------------------*
* Amendment History                                                    *
* -----------------                                                    *
* Date     Developer   Ref      Description                            *
* ======== =========== ======== ====================================== *
* dd-mm-yy sap userid  FD       Description                            *
*                                                                      *
*----------------------------------------------------------------------*

*---------------------------------------------------------------------
*  Form  GET_SPOOL_LINE (copied from std SAP)                                               
*--------------------------------------------------------------------- 
FORM GET_SPOOL_LINE.
  data: length type i.
  DO.
    IF TEMSE_RECTYP+1(1) = 'Y'.
      CALL 'C_RSTS_READ'
         ID 'HANDLE'  FIELD TEMSE_HANDLE
         ID 'BUFF'    FIELD DATA_SET_LINE
         ID 'BUFFLG'  FIELD 1006
         ID 'ALLINE'  FIELD 'X'
         ID 'BINARY'  FIELD ' '
         ID 'SHOWLG'  FIELD 'X'
         ID 'LENGTH'  FIELD length
         ID 'RC'      FIELD RC
         ID 'ERRMSG'  FIELD ERRMSG.
      STATUS = SY-SUBRC.
    ELSE.
      CALL 'C_RSTS_READ'
         ID 'HANDLE'  FIELD TEMSE_HANDLE
         ID 'BUFF'    FIELD DATA_SET_LINE+1
         ID 'BUFFLG'  FIELD 1005
         ID 'ALLINE'  FIELD 'X'
         ID 'BINARY'  FIELD ' '
         ID 'SHOWLG'  FIELD 'X'
         ID 'LENGTH'  FIELD length
         ID 'RC'      FIELD RC
         ID 'ERRMSG'  FIELD ERRMSG.
      STATUS = SY-SUBRC.
      DATA_SET_LINE(5) = DATA_SET_LINE+1(5).
      DATA_SET_LINE-PRECOL = ' '.
      ADD 1 TO DATA_SET_LINE-DATA_LENGTH.
    ENDIF.
    STATUS = SY-SUBRC.
    IF STATUS <> 6.               " EOF, error condition, or got data
      EXIT.
    ENDIF.
* end of this part, try to open next part
    ADD 1 TO TEMSE_PART.
    CALL 'C_RSTS_CLOSE'
          ID 'HANDLE'  FIELD TEMSE_HANDLE
          ID 'RC'      FIELD RC
          ID 'ERRMSG'  FIELD ERRMSG.
    STATUS = SY-SUBRC.
    IF STATUS = 0.
      CALL FUNCTION 'RSTS_GET_ATTRIBUTES'
        EXPORTING
          AUTHORITY     = 'SP01'
          CLIENT        = TEMSE_CLIENT                          
          NAME          = TEMSE_NAME
          PART          = TEMSE_PART
        IMPORTING
          CHARCO        = TEMSE_CHARCO
          RECTYP        = TEMSE_RECTYP
          OBJTYPE       = TEMSE_OBJTYP
       EXCEPTIONS
          FB_ERROR      = 1
          FB_RSTS_OTHER = 2
          NO_OBJECT     = 3
          NO_PERMISSION = 4
          OTHERS        = 5.
      STATUS = SY-SUBRC.
    ENDIF.
    IF STATUS = 0.
      CALL 'C_RSTS_OPEN_READ'
        ID 'HANDLE'   FIELD TEMSE_HANDLE
        ID 'CLIENT'   FIELD TEMSE_CLIENT                     
        ID 'NAME'     FIELD TEMSE_NAME
        ID 'PART'     FIELD TEMSE_PART
        ID 'TYPE'     FIELD TEMSE_OBJTYP
        ID 'CONV'     FIELD ' '
        ID 'ALLINE'   FIELD 'X'
        ID 'BINARY'   FIELD ' '
        ID 'RECTYP'   FIELD TEMSE_RECTYP
        ID 'CHARCO'   FIELD TEMSE_CHARCO
        ID 'PROM'     FIELD 'I'
        ID 'RC'       FIELD RC
        ID 'ERRMSG'   FIELD ERRMSG.
      STATUS = SY-SUBRC.
    ENDIF.
  ENDDO.
  IF STATUS = 4.
    STATUS = 12.    "EOF
  ENDIF.
  IF STATUS = 8.
    STATUS = 40.    "Line too long
  ENDIF.
  DATA_SET_LENGTH = DATA_SET_LINE-DATA_LENGTH.
ENDFORM.                    "GET_SPOOL_LINE
*---------------------------------------------------------------------
*  Form  read_data (copied from std SAP)                                               
*--------------------------------------------------------------------- 
FORM READ_DATA TABLES BUFFER
               USING TSP01 LIKE TSP01 VALUE(FIRST) TYPE I
                                      VALUE(LAST) TYPE I
               changing codepage like tst01-dcharcod.
  DATA: LINES TYPE I.

  REFRESH BUFFER.
  CLEAR IS_OTF.

  TEMSE_CLIENT = TSP01-RQCLIENT.
  TEMSE_NAME = TSP01-RQO1NAME.
  TEMSE_PART = 1.

  CALL FUNCTION 'RSTS_GET_ATTRIBUTES'
      EXPORTING
          AUTHORITY     = 'SP01'
          CLIENT        = TEMSE_CLIENT
          NAME          = TEMSE_NAME
          PART          = TEMSE_PART
      IMPORTING
          CHARCO        = codepage
          RECTYP        = TEMSE_RECTYP
          OBJTYPE       = TEMSE_OBJTYP
     EXCEPTIONS
          FB_ERROR      = 1
          FB_RSTS_OTHER = 2
          NO_OBJECT     = 3
          NO_PERMISSION = 4
          OTHERS        = 5.

  IF SY-SUBRC = 0.
    IF TEMSE_OBJTYP(3) = 'OTF'.
      IS_OTF = 'X'.
    ENDIF.
  ELSE.
    message e466 with tsp01-rqident raising READ_ERROR.
  ENDIF.

  CLEAR TEMSE_HANDLE.
  CALL 'C_RSTS_OPEN_READ'
      ID 'HANDLE'   FIELD TEMSE_HANDLE
      ID 'CLIENT'   FIELD TEMSE_CLIENT                       "hjl
      ID 'NAME'     FIELD TEMSE_NAME
      ID 'PART'     FIELD TEMSE_PART
      ID 'TYPE'     FIELD TEMSE_OBJTYP
      ID 'CONV'     FIELD ' '
      ID 'ALLINE'   FIELD 'X'
      ID 'BINARY'   FIELD ' '
      ID 'RECTYP'   FIELD TEMSE_RECTYP
      ID 'CHARCO'   FIELD codepage
      ID 'PROM'     FIELD 'I'
      ID 'RC'       FIELD RC
      ID 'ERRMSG'   FIELD ERRMSG.
  STATUS = SY-SUBRC.

  IF STATUS = 0.

    DO.
      PERFORM GET_SPOOL_LINE.
      IF STATUS <> 0 AND STATUS <> 40 AND STATUS <> 12.
        PERFORM CLOSE_JOB.
        message e466 with tsp01-rqident raising READ_ERROR.
      ENDIF.
      IF STATUS <> 12.                                      " 12 = End
        IF NOT ( DATA_SET_LENGTH IS INITIAL ).
          DATA_SET_LINE-DATA_LENGTH = DATA_SET_LENGTH - 1.
        ENDIF.
        ADD 1 TO LINES.
        IF LINES >= FIRST.
          APPEND DATA_SET_LINE TO BUFFER.
        ENDIF.
        IF ( NOT LAST IS INITIAL ) AND ( LINES >= LAST ).
          EXIT.
        ENDIF.
      ELSE.
        IF LINES = 0.
          PERFORM CLOSE_JOB.
          message e467 with tsp01-rqident RAISing JOB_CONTAINS_NO_DATA.
        ENDIF.
        IF LINES < FIRST .
          PERFORM CLOSE_JOB.
          message e420 RAISing SELECTION_EMPTY.
        ENDIF.
        EXIT.
      ENDIF.
    ENDDO.
    PERFORM CLOSE_JOB.
  ENDIF.
ENDFORM.                    "READ_DATA
*---------------------------------------------------------------------
*  FORM CLOSE_JOB (copied from std SAP)                                               
*--------------------------------------------------------------------- 
FORM CLOSE_JOB.
  IF STATUS <> 0 AND STATUS <> 12.
    CALL 'C_RSTS_CLOSE'
          ID 'HANDLE'  FIELD TEMSE_HANDLE
          ID 'RC'      FIELD RC
          ID 'ERRMSG'  FIELD ERRMSG.
    MESSAGE E112(PO) WITH STATUS RC ERRMSG RAISING READ_ERROR.
  ENDIF.
  CALL 'C_RSTS_CLOSE'
     ID 'HANDLE'  FIELD TEMSE_HANDLE
     ID 'RC'      FIELD RC
     ID 'ERRMSG'  FIELD ERRMSG.
  STATUS = SY-SUBRC.
  IF STATUS <> 0.
    MESSAGE E112(PO) WITH STATUS RC ERRMSG RAISING READ_ERROR.
  ENDIF.
ENDFORM.                    "CLOSE_JOB
*---------------------------------------------------------------------
*  Form  DISPLAY_DATA (copied from std SAP)
*--------------------------------------------------------------------- 
FORM DISPLAY_DATA TABLES BUFFER using rqpaper like tsp01-rqpaper
                                      rqid like tsp01-rqident
                                      lcodepage.
  DATA: LINE_LENGTH TYPE I, gcol type i, glines type i,
        LINE_LENGTH2 LIKE RSTSTYPE-LINELENGTH,
        v, v2.

  CLASS CL_ABAP_CHAR_UTILITIES DEFINITION LOAD.

  CALL FUNCTION 'RSPO_SPOOLDATA_WRITE_INIT'
    EXPORTING
      codepage = lcodepage.
  call function 'RSPO_OPTION_GET'
    EXPORTING
      name  = spopt_realwidth
    IMPORTING
      VALUE = v.
  call function 'RSPO_OPTION_GET'
    EXPORTING
      name  = spopt_realheight
    IMPORTING
      VALUE = v2.
  if not v is initial or not v2 is initial.
    gcol = 0.
    glines = 0.
    select single * from tsp02l where pjident = rqid
                                and pjnummer = 0.
    if sy-subrc = 0.
      gcol = tsp02l-columns.
      glines = tsp02l-lines.
    else.
      CALL FUNCTION 'RSPO_GET_SIZE_OF_LAYOUT'
         EXPORTING
              layout  = rqpaper
         IMPORTING
              COLUMNS = gcol
              LINES   = glines.
    endif.
  endif.

  if gcol < 80 or v is initial.
    gcol = 255.
  endif.

  if glines < 5 or v2 is initial.
    glines = 0.
  endif.

* Buffer only 1000
  if gcol >= 1000.
    gcol = 999.
  endif.

  NEW-PAGE NO-HEADING NO-TITLE LINE-SIZE gcol
                                 line-count glines.  " make a wide list
  SET BLANK LINES ON.

  LOOP AT BUFFER.
    DATA_SET_LINE = BUFFER.
    IF DATA_SET_LINE-PRECOL = 'P'.
      IF DATA_SET_LINE(1) = ' '.    " Echter Vorschub ?"
        NEW-PAGE.
      ENDIF.
      CONTINUE.
    ENDIF.
*   Zeilenlänge berechnen, falls unbekannt.
    IF DATA_SET_LINE-DATA_LENGTH IS INITIAL.
      LINE_LENGTH = STRLEN( DATA_SET_LINE-DATA_LINE ).
    ELSE.
      LINE_LENGTH = DATA_SET_LINE-DATA_LENGTH.
    ENDIF.

    IF LINE_LENGTH > 0.
      LINE_LENGTH2 = LINE_LENGTH.
      IF cl_abap_char_utilities=>charsize > 1.
        CALL FUNCTION 'RSPO_SPOOLDATA_WRITE'
          EXPORTING
            SPOOL_DATA  = DATA_SET_LINE-DATA_LINE
            DATA_LENGTH = LINE_LENGTH2.
      ELSE.
        CALL FUNCTION 'RSPO_SPOOLDATA_WRITE_OLD'
          EXPORTING
            SPOOL_DATA  = DATA_SET_LINE-DATA_LINE
            DATA_LENGTH = LINE_LENGTH2.
      ENDIF.
    ELSE.
      " Leerzeile
      SKIP.
    ENDIF.
  ENDLOOP.
ENDFORM.                    "DISPLAY_DATA