Have you ever seen an ABAP dump in ST22 and wished you could save it as a PDF, so you (or another developer) could analyse it in colors instead of an ugly plain text file?
Or maybe you wished you could send any other transactions’ list output to someone in a pretty format that wasn’t a fat cumbersome HTML file?
Well, wouldn’t this be nice then?
The full dump exported as PDF has only 44 KB!
Here’s how I did it:
1 – Create a new function group based on the standard function group SYSF.
Don’t forget to copy all the text symbols for the languages you use.
Here’s the TOP include (most of it came from the SYSF top include):
FUNCTION-POOL ZNINJA_LISTS MESSAGE-ID 02.
************************************************************************
* Tables *
************************************************************************
TABLES RSYSF.
************************************************************************
* Constants *
************************************************************************
INCLUDE <LIST>.
************************************************************************
* Types *
************************************************************************
TYPE-POOLS: SLIST, abap.
TYPES: BEGIN OF SEARCH_RESULT,
OFFSET TYPE I,
LENGTH TYPE I,
END OF SEARCH_RESULT.
TYPES: SEARCH_RESULT_TAB TYPE SEARCH_RESULT OCCURS 0.
***********************************************************************
* LIST-Tables
***********************************************************************
INCLUDE <%_LIST>.
DATA: PAGES TYPE SLIST_PAGEDESCR_TAB.
DATA: LIST TYPE SLIST_LIST_TAB WITH HEADER LINE.
DATA: FMBS TYPE SLIST_FMBS_TAB WITH HEADER LINE.
DATA: FMBX TYPE SLIST_FMBS_TAB WITH HEADER LINE.
DATA: FSEL TYPE SLIST_FSEL_TAB WITH HEADER LINE.
DATA: FPOS TYPE SLIST_FPOS_TAB WITH HEADER LINE.
DATA LIST_DESCRIPTION LIKE LISTDS OCCURS 10 WITH HEADER LINE.
DATA PAGE_DESCRIPTION LIKE PAGEDS OCCURS 10 WITH HEADER LINE.
TYPES: BEGIN OF listtable_stack_line,
list TYPE SLIST_LIST_TAB,
fmbx TYPE SLIST_FMBS_TAB,
fsel type slist_fsel_tab,
fpos type slist_fpos_tab,
END OF listtable_stack_line.
DATA listtable_stack TYPE TABLE OF listtable_stack_line.
DATA listtable_stack_counter TYPE I VALUE 0.
***********************************************************************
* LIST-Description
***********************************************************************
DATA: LISTINDEX LIKE SY-LSIND,
START_ROW LIKE SY-STARO,
LINESIZE LIKE SY-LINSZ,
CURRENT_FIRSTLINE LIKE SY-LILLI,
CURRENT_LASTLINE LIKE SY-LILLI,
CURRENT_LINE LIKE SY-LILLI,
CURRENT_LINES LIKE SY-LILLI,
CURRENT_TOP LIKE SY-LILLI,
CURRENT_HEAD LIKE SY-LILLI,
CURRENT_TITLE LIKE SY-LILLI,
NEW_CURRENT_LINE LIKE SY-LILLI.
***********************************************************************
* Daten fuer Funktion: Pflegen Ueberschriften in Listen
***********************************************************************
DATA: TITELZEILE(72),
HEADER1ZEILE TYPE SLIST_MAX_LISTLINE,
HEADER2ZEILE TYPE SLIST_MAX_LISTLINE,
HEADER3ZEILE TYPE SLIST_MAX_LISTLINE,
HEADER4ZEILE TYPE SLIST_MAX_LISTLINE,
CORRF LIKE SY-SUBRC.
data: filename type string, "#EC NEEDED
filefilter type string,
path type string, "#EC NEEDED
fullpath type string.
DATA: BEGIN OF TPOOL OCCURS 5. "Einlese-Tab - READ TEXTPOOL BINK036480
INCLUDE STRUCTURE TEXTPOOL. "BINK036418
* ID(1), "BINK036418
* NO(8), "BINK036418
* LINE(255), "BINK036418
DATA: END OF TPOOL. "BINK036418
DATA: BEGIN OF TPOOLS OCCURS 5. "Save Tpool BINK036480
INCLUDE STRUCTURE TEXTPOOL. "BINK036418
DATA: END OF TPOOLS. "BINK036418
DATA: ENQ(8), "Enqueue auf Programmname
UFLAG, "Update-Flag
UFLAGT, "Titelidentische Überschrift löschen ?
SYFCODE LIKE SY-UCOMM,
SFCODE(4), "Save F-Code
POPUPANSWER. "BINK036418
***********************************************************************
* Daten fuer Funktion: Suchen String in Listen
***********************************************************************
DATA: BEGIN OF SCAN_STRING,
SCREEN LIKE SY-DYNNR VALUE 800,
COL LIKE SY-CUCOL VALUE 10,
ROW LIKE SY-CUROW VALUE 05,
START(1) VALUE 'X', "X = nur ab aktueller Zeile
RANGE(1) VALUE ' ', "X = nur in der aktuellen Seite
FUZZY(1) VALUE ' ', "X = auch aehnliche Worte suchen
LIMIT TYPE I VALUE 100,
MATCHES TYPE I VALUE 0,
END OF SCAN_STRING.
DATA: BEGIN OF SCAN_LIST,
SCREEN LIKE SY-DYNNR VALUE 810,
COL1 LIKE SY-CUCOL,
ROW1 LIKE SY-CUROW,
COL2 LIKE SY-CUCOL,
ROW2 LIKE SY-CUROW,
RC LIKE SY-SUBRC,
END OF SCAN_LIST.
DATA: SCAN_MATCHING_LILLI LIKE SY-TABIX,
SCAN_CURSOR_OFFSET LIKE SY-CUCOL,
SCAN_SCOLS LIKE SY-SCOLS.
DATA: OK_CODE LIKE SY-UCOMM.
DATA: tmp_listline LIKE %_list_wa.
***********************************************************************
* Daten fuer Funktion: Download Liste
***********************************************************************
2 – Create a report that will write a list exported to memory.
This report is very simple, and it will be used to output the list contents to a spool job, so we can convert it to PDF.
*&---------------------------------------------------------------------*
*& Report ZDISPLAY_LIST
*& Displays an ABAP list (for output to a spool)
*&---------------------------------------------------------------------*
report zdisplay_list no standard page heading.
data: t_list type table of abaplist.
"// Get the list contents from memory
"// (list contents were exporte by the caller)
call function 'LIST_FROM_MEMORY'
tables
listobject = t_list
exceptions
not_found = 1
others = 2.
if sy-subrc <> 0.
message id sy-msgid type 'E' number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
"// Write the read list to the current list
"// (this is what will be output to the spool)
call function 'WRITE_LIST'
exporting
write_only = 'X'
tables
listobject = t_list
exceptions
empty_list = 1
others = 2.
if sy-subrc <> 0.
message id sy-msgid type 'E' number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
3 – Create a new function module to export the current list as a PDF file.
Use the same signature as the DOWNLOAD_LIST
function module, excluding the COPY_TO_CLIPBOARD
parameter.
This function will do a few things:
- Ask for the file path to be saved
- Submit our new report to a spool job
- Convert the generated spool job to a PDF file
- Finally, download the PDF file to the client
So here’s the code:
function zdownload_list_pdf.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(LIST_INDEX) LIKE SY-LSIND DEFAULT SLIST_INDEX_DEFAULT
*" REFERENCE(COPY_TO_CLIPBOARD) TYPE CHAR1 DEFAULT SPACE
*" EXCEPTIONS
*" LIST_INDEX_INVALID
*" LIST_DOWNLOAD_ERROR
*"----------------------------------------------------------------------
data: lv_user_action type i,
lv_filename type string,
lv_path type string,
lv_fullpath type string,
lv_file_encoding type abap_encoding,
ls_print_parameters type pri_params,
lv_spool_nr type rspoid,
lt_pdf type table of tline,
lv_listname type syplist value 'LIST EXPORT'.
if list_index = slist_index_default.
list_index = sy-lsind.
endif.
"//
"// (1) Ask for the file path
"//
call function 'GUI_FILE_SAVE_DIALOG'
exporting
file_filter = 'PDF|*.pdf'
default_extension = 'pdf'
default_file_name = '.pdf'
importing
filename = lv_filename
path = lv_path
fullpath = lv_fullpath
user_action = lv_user_action.
check lv_user_action = 1 or lv_user_action = 0.
"//
"// (2) Submit the report to output the list to the spool
"//
call function 'GET_PRINT_PARAMETERS'
exporting
abap_list = 'X'
list_name = lv_listname
list_text = 'Exported ABAP list'
mode = 'OKPRI1'
importing
out_parameters = ls_print_parameters
exceptions
archive_info_not_found = 1
invalid_print_params = 2
invalid_archive_params = 3
others = 4.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
raising list_download_error.
endif.
call function 'LIST_TO_MEMORY'
exporting
list_index = list_index
force_write = 'X'
exceptions
list_index_invalid = 1
empty_list = 2
others = 3.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
raising list_download_error.
endif.
submit zdisplay_list and return
to sap-spool
spool parameters ls_print_parameters
without spool dynpro.
commit work and wait. "// Wait until the spool is completely generated
"// Get the generated spool job number
select max( rqident ) from tsp01 into lv_spool_nr
where
rqclient = sy-mandt and
rq2name = lv_listname and
rqowner = sy-uname.
if sy-subrc <> 0.
message 'Spool job not generated' type 'E'
raising list_download_error.
endif.
"//
"// (3) Convert the spool output to PDF
"//
call function 'CONVERT_ABAPSPOOLJOB_2_PDF'
exporting
src_spoolid = lv_spool_nr
no_dialog = 'X'
tables
pdf = lt_pdf
exceptions
err_no_abap_spooljob = 1
err_no_spooljob = 2
err_no_permission = 3
err_conv_not_possible = 4
err_bad_destdevice = 5
user_cancelled = 6
err_spoolerror = 7
err_temseerror = 8
err_btcjob_open_failed = 9
err_btcjob_submit_failed = 10
err_btcjob_close_failed = 11
others = 12.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
raising list_download_error.
endif.
"//
"// (4) Save the PDF file
"//
call function 'GUI_DOWNLOAD'
exporting
filename = lv_fullpath
filetype = 'BIN'
tables
data_tab = lt_pdf
exceptions
invalid_type = 03
no_batch = 04
unknown_error = 05
others = 99.
if sy-subrc ne 0.
message id sy-msgid type sy-msgty number sy-msgno
raising list_download_error.
endif.
endfunction.
5 – Copy the function module LIST_DOWNLOAD to a new function module.
This function module will replace the standard LIST_DOWNLOAD
.
Add the PDF format option and add the call to our new function module.
FUNCTION ZLIST_DOWNLOAD_NEW.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(LIST_INDEX) LIKE SY-LSIND DEFAULT SLIST_INDEX_DEFAULT
*" VALUE(METHOD) TYPE C DEFAULT SPACE
*" EXCEPTIONS
*" LIST_DOWNLOAD_ERROR
*"----------------------------------------------------------------------
DATA: ANSWER.
DATA: CHOICES LIKE SPOPLI OCCURS 3 WITH HEADER LINE.
DATA: FLAG_NO_POPUP VALUE SPACE.
AUTHORITY-CHECK OBJECT 'S_GUI'
ID 'ACTVT' FIELD '61'.
IF SY-SUBRC NE 0.
MESSAGE I013 WITH SY-SUBRC.
EXIT.
ENDIF.
IF LIST_INDEX = SLIST_INDEX_DEFAULT.
LIST_INDEX = SY-LSIND.
ENDIF.
CASE METHOD.
WHEN 'NOCO'.
ANSWER = '1'.
FLAG_NO_POPUP = 'X'.
WHEN 'DAT'.
ANSWER = '2'.
FLAG_NO_POPUP = 'X'.
WHEN 'RTF'.
ANSWER = '3'.
FLAG_NO_POPUP = 'X'.
WHEN 'HTML'.
ANSWER = '4'.
FLAG_NO_POPUP = 'X'.
ENDCASE.
CHOICES-VAROPTION = 'unkonvertiert'(ASC). APPEND CHOICES.
CHOICES-VAROPTION = 'Tabellenkalkulation'(DAT). APPEND CHOICES.
CHOICES-VAROPTION = 'Rich Text Format'(RTF). APPEND CHOICES.
CHOICES-VAROPTION = 'HTML Format'(HTM). APPEND CHOICES.
CHOICES-VAROPTION = 'In die Zwischenablage'(CLP). APPEND CHOICES.
CHOICES-VAROPTION = 'PDF format'(PDF). APPEND CHOICES. "// abapninja
IF FLAG_NO_POPUP NE 'X'.
CALL FUNCTION 'POPUP_TO_DECIDE_LIST'
EXPORTING
CURSORLINE = 1
* mark_max = 1
TITEL = 'Liste sichern in Datei...'(DL0)
TEXTLINE1 = 'In welchem Format soll die Liste'(DL1)
TEXTLINE2 = 'gesichert werden ?'(DL2)
* textline3 = text-dl3
IMPORTING
ANSWER = ANSWER
TABLES
T_SPOPLI = CHOICES.
ENDIF.
CASE ANSWER.
WHEN 'A'. EXIT.
WHEN '1'.
CALL FUNCTION 'DOWNLOAD_LIST'
EXPORTING
LIST_INDEX = LIST_INDEX
EXCEPTIONS
LIST_DOWNLOAD_ERROR
OTHERS.
IF SY-SUBRC <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
RAISING LIST_DOWNLOAD_ERROR.
ENDIF.
WHEN '2'.
PERFORM GET_LISTLEVEL_TABLES IN PROGRAM SAPLSYSF
USING
PAGES[]
LIST[]
FMBS[]
FMBX[]
FSEL[]
FPOS[]
LIST_INDEX.
CALL FUNCTION 'LIST_CONVERT_TO_DAT'
EXPORTING
PAGES = PAGES[]
TABLES
LIST = LIST[]
FMBS = FMBS[]
FMBX = FMBX[]
FSEL = FSEL[].
WHEN '3'.
PERFORM GET_LISTLEVEL_TABLES IN PROGRAM SAPLSYSF
USING
PAGES[]
LIST[]
FMBS[]
FMBX[]
FSEL[]
FPOS[]
LIST_INDEX.
CALL FUNCTION 'LIST_CONVERT_TO_RTF'
TABLES
LIST = LIST
FMBS = FMBS
FMBX = FMBX
FSEL = FSEL
FPOS = FPOS
EXCEPTIONS
DOWNLOAD_FILE_WRITE_ERROR
DOWNLOAD_NO_BATCH
DOWNLOAD_UNKNOWN_ERROR
OTHERS.
IF SY-SUBRC <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
RAISING LIST_DOWNLOAD_ERROR.
ENDIF.
WHEN '4'.
CALL FUNCTION 'LIST_DOWNLOAD_HTML'
EXPORTING
LIST_INDEX = LIST_INDEX
EXCEPTIONS
LIST_INDEX_INVALID = 1
DOWNLOAD_ERROR = 2
OTHERS = 3.
IF SY-SUBRC NE 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
RAISING LIST_DOWNLOAD_ERROR.
ENDIF.
when '5'.
CALL FUNCTION 'DOWNLOAD_LIST'
EXPORTING
LIST_INDEX = LIST_INDEX
copy_to_clipboard = 'X'
EXCEPTIONS
LIST_DOWNLOAD_ERROR
OTHERS.
IF SY-SUBRC <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
RAISING LIST_DOWNLOAD_ERROR.
ENDIF.
when '6'. "// PDF format
CALL FUNCTION 'ZDOWNLOAD_LIST_PDF'
EXPORTING
LIST_INDEX = LIST_INDEX
EXCEPTIONS
LIST_DOWNLOAD_ERROR
OTHERS.
IF SY-SUBRC <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
RAISING LIST_DOWNLOAD_ERROR.
ENDIF.
ENDCASE.
ENDFUNCTION.
6 – Create a new enhancement implementation at the beginning of function module LIST_DOWNLOAD.
This enhancement implementation will detour the execution of the LIST_DOWNLOAD
function module to our Z replacement with the PDF option:
FUNCTION LIST_DOWNLOAD.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""$"$\SE:(1) Function Module LIST_DOWNLOAD, Start A
*$*$-Start: (1)---------------------------------------------------------------------------------$*$*
ENHANCEMENT 1 ZNINJA_LISTS. "active version
* Detour execution to the new list download function
call function 'ZLIST_DOWNLOAD_NEW'
exporting
list_index = list_index
method = method
exceptions
list_download_error = 1
others = 2.
RETURN.
ENDENHANCEMENT.
*$*$-End: (1)---------------------------------------------------------------------------------$*$*
...
Done!
Enjoy exporting your lists to lightweight PDFs! 🙂
This enhancement has a very small footprint, so you can transport it to productive systems (it’s specially useful in productive systems). But you might even make it less obtrusive, for example checking for a user parameter before detouring to the new function.
If you have any ideas, suggestions or ramblings, please leave a comment. 🙂