Introduction:
This blog explains the complete selection logic, Adobe Form integration, navigation handling, and PDF download mechanism, along with the key ABAP code snippets you can adapt in your own projects.
In many logistics processes, users often need to review and download Adobe Forms for multiple delivery documents directly from a custom report. However, the standard functionality typically allows previewing only one form at a time, which slows down user productivity, especially during high-volume operations.
Solution Overview:
I developed a custom ABAP report that provides a more user-friendly and efficient way to handle Adobe Form previews and downloads for delivery header and item data. The report includes a selection screen with checkboxes, allowing users to choose one or more delivery numbers. When the preview button is clicked, the system intelligently responds based on the user’s selection:
Single selection: The Adobe Form opens directly for the chosen delivery.
Multiple selections: The application opens the first form and provides a “Next” button, enabling users to navigate through the forms one by one without returning to the report.
After reviewing all forms, the selected Adobe Forms are automatically downloaded as PDF files, ensuring users have the final output ready for printing or further processing.
Flow Diagram To Understand This Requirement:
Start
↓
User selects delivery numbers on Selection Screen
↓
User clicks “Preview” button
↓
Is only one delivery selected?
↓ Yes ↓ No
↓ ↓
Open Adobe Form directly Open first Adobe Form
↓ ↓
End Show “Next” button
↓
User clicks “Next”
↓
Display next delivery Adobe Form
↓
More deliveries left?
↓ Yes ↓ No
↓ ↓
Go back to “Next” loop
↓
Download all selected
Adobe Forms as PDF
↓
End
Implementation:
This solution is built using a classic ALV-based ABAP report where users can select delivery documents and trigger Adobe Form generation. The report reads header data from LIKP and item data from LIPS, then displays them in an editable ALV with a checkbox column. Users select one or multiple deliveries and click Preview or PDF. The helper class lcl_adobe_helper encapsulates all Adobe Form logic—opening the SFP print job, retrieving the generated function module using FP_FUNCTION_MODULE_NAME, preparing form parameters, and calling the form for each selected delivery. For preview mode, the form opens directly in the browser, and for PDF mode, the form output is returned as an XSTRING, converted to binary, and downloaded using GUI_DOWNLOAD. The flow also supports iterating through multiple selected deliveries and generating separate PDFs for each one. This modular design keeps the report clean while ensuring flexible preview and download options for batch delivery processing.
“—————————————————————“
” Fetch Deliveries, Display in ALV with Checkbox, and Generate”
” Adobe Forms Individually for Selected Deliveries “
“—————————————————————“
TABLES : likp.
” Structure for ALV output
TYPES : BEGIN OF ty_likp,
vbeln TYPE vbeln,
ernam TYPE ernam,
erdat TYPE erdat,
checkbox TYPE char20,
END OF ty_likp.
” Selection option for Delivery Number
SELECT-OPTIONS : s_vbeln FOR likp-vbeln.
” Internal tables
DATA : lt_likp TYPE TABLE OF ty_likp WITH EMPTY KEY,
lt_lips TYPE TABLE OF zhr_str_lips,
ls_likp TYPE ty_likp.
” Field catalog for ALV
DATA(lt_fcat) = VALUE lvc_t_fcat(
( col_pos = 1 fieldname = ‘CHECKBOX’ checkbox = ‘X’ edit = ‘X’ )
( col_pos = 2 fieldname = ‘VBELN’ tabname = ‘LT_LIKP’ scrtext_l = ‘PURCHASE DOCUMENT NUMBER’ )
( col_pos = 3 fieldname = ‘ERNAM’ tabname = ‘LT_LIKP’ scrtext_l = ‘CREATED BY’ )
( col_pos = 4 fieldname = ‘ERDAT’ tabname = ‘LT_LIKP’ scrtext_l = ‘CREATED ON’ )
( col_pos = 5 fieldname = ‘MATNR’ tabname = ‘LT_LIPS’ scrtext_l = ‘MATERIAL NO’ )
( col_pos = 6 fieldname = ‘ARKTX’ tabname = ‘LT_LIPS’ scrtext_l = ‘MATERIAL DESCRIPTION’ )
( col_pos = 7 fieldname = ‘CHARG’ tabname = ‘LT_LIPS’ scrtext_l = ‘BATCH’ ) ).
” Create ALV Grid on screen container
DATA(lo_alv) = NEW cl_gui_alv_grid(
i_parent = NEW cl_gui_custom_container(
container_name = ‘CONT’ ) ).
“—————————————————————“
” Helper Class to Generate Adobe Form “
“—————————————————————“
CLASS lcl_adobe_helper DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
generate_adobe_form
IMPORTING
iv_preview TYPE abap_bool ” Preview or not
iv_getpdf TYPE abap_bool ” Download PDF or not
EXPORTING
ev_xstring TYPE xstring ” PDF content
ev_filename TYPE string. ” Output filename
ENDCLASS.
CLASS lcl_adobe_helper IMPLEMENTATION.
METHOD generate_adobe_form.
DATA: lv_fname TYPE funcname,
ls_o_p TYPE sfpoutputparams,
lt_likp_sel TYPE TABLE OF ty_likp,
lt_lips_sel TYPE TABLE OF zhr_str_lips,
lv_result_pdf TYPE fpformoutput,
lv_result_job TYPE sfpjoboutput.
” Setup Adobe Output Parameters
CLEAR ls_o_p.
ls_o_p-preview = iv_preview.
ls_o_p-getpdf = iv_getpdf.
ls_o_p-nodialog = abap_true.
ls_o_p-noprint = abap_true.
ls_o_p-noarchive = abap_true.
ls_o_p-dest = ‘LP01’.
” Open Adobe Print Job
CALL FUNCTION ‘FP_JOB_OPEN’
CHANGING ie_outputparams = ls_o_p.
” Get associated Form Function Module
CALL FUNCTION ‘FP_FUNCTION_MODULE_NAME’
EXPORTING i_name = ‘ZHR_ADOB’
IMPORTING e_funcname = lv_fname.
” Loop through selected deliveries
LOOP AT lt_likp INTO DATA(ls_likp) WHERE checkbox = abap_true.
” Prepare Header
CLEAR lt_likp_sel.
APPEND ls_likp TO lt_likp_sel.
” Prepare Items
CLEAR lt_lips_sel.
LOOP AT lt_lips INTO DATA(ls_lips) WHERE vbeln = ls_likp-vbeln.
APPEND ls_lips TO lt_lips_sel.
ENDLOOP.
” Call Adobe Form
CALL FUNCTION lv_fname
EXPORTING
lt_header = lt_likp_sel
lt_item = lt_lips_sel
IMPORTING
/1bcdwb/formoutput = lv_result_pdf
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ‘Error generating Adobe form’ TYPE ‘E’.
ELSE.
” Return PDF when required
IF iv_getpdf = abap_true.
ev_xstring = lv_result_pdf-pdf.
ev_filename = |{ ls_likp-vbeln }.pdf|.
ENDIF.
ENDIF.
ENDLOOP.
” Close print job
CALL FUNCTION ‘FP_JOB_CLOSE’
IMPORTING e_result = lv_result_job.
ENDMETHOD.
ENDCLASS.
“—————————————————————“
” Fetch Data and Display ALV “
“—————————————————————“
START-OF-SELECTION.
” Fetch Header Data
SELECT vbeln ernam erdat
FROM likp
INTO TABLE lt_likp
WHERE vbeln IN s_vbeln.
” Fetch Item Data
IF lt_likp IS NOT INITIAL.
SELECT vbeln matnr arktx charg
FROM lips
INTO TABLE lt_lips
FOR ALL ENTRIES IN lt_likp
WHERE vbeln = lt_likp-vbeln.
ENDIF.
” Display ALV Output
lo_alv->set_table_for_first_display(
CHANGING
it_outtab = lt_likp
it_fieldcatalog = lt_fcat ).
CALL SCREEN 1200.
“—————————————————————“
” Handle User Actions in ALV Screen “
“—————————————————————“
INCLUDE zhr_dynamic_adobe_status_12o01.
INCLUDE zhr_dynamic_adobe_user_commi01.
PAI:
MODULE user_command_1200 INPUT.
CASE sy-ucomm.
WHEN ‘&F03’. ” Exit
LEAVE TO SCREEN 0.
WHEN ‘PREVIEW’. ” Preview Adobe Form
lo_alv->check_changed_data( ).
lcl_adobe_helper=>generate_adobe_form(
EXPORTING
iv_preview = abap_true
iv_getpdf = abap_false ).
WHEN ‘PDF’. ” Download PDF
DATA: lv_xstring TYPE xstring,
lv_filename TYPE string,
lt_pdf_data TYPE solix_tab,
lv_pdf_size TYPE i.
lo_alv->check_changed_data( ).
” Generate PDF
lcl_adobe_helper=>generate_adobe_form(
EXPORTING
iv_preview = abap_false
iv_getpdf = abap_true
IMPORTING
ev_xstring = lv_xstring
ev_filename = lv_filename ).
” Download PDF to PC
IF lv_xstring IS NOT INITIAL.
CALL FUNCTION ‘SCMS_XSTRING_TO_BINARY’
EXPORTING buffer = lv_xstring
IMPORTING output_length = lv_pdf_size
TABLES binary_tab = lt_pdf_data.
CALL FUNCTION ‘GUI_DOWNLOAD’
EXPORTING
bin_filesize = lv_pdf_size
filename = lv_filename
filetype = ‘BIN’
TABLES
data_tab = lt_pdf_data.
ENDIF.
ENDCASE.
ENDMODULE.
Conclusion:
This approach provides a complete and user-friendly solution for generating Adobe Forms directly from an ALV-based selection. By enabling users to choose specific deliveries through checkboxes and dynamically building the header and item data, the program ensures flexibility and efficiency. The integration of Adobe form FM calls, and automatic PDF download makes the process seamless, whether the user wants a quick preview or a local PDF file. Overall, this design offers a practical, scalable, and easily reusable framework for handling document generation in SAP.
Thanks for Reading, Best Wishes
Introduction:This blog explains the complete selection logic, Adobe Form integration, navigation handling, and PDF download mechanism, along with the key ABAP code snippets you can adapt in your own projects.In many logistics processes, users often need to review and download Adobe Forms for multiple delivery documents directly from a custom report. However, the standard functionality typically allows previewing only one form at a time, which slows down user productivity, especially during high-volume operations.Solution Overview: I developed a custom ABAP report that provides a more user-friendly and efficient way to handle Adobe Form previews and downloads for delivery header and item data. The report includes a selection screen with checkboxes, allowing users to choose one or more delivery numbers. When the preview button is clicked, the system intelligently responds based on the user’s selection:Single selection: The Adobe Form opens directly for the chosen delivery.Multiple selections: The application opens the first form and provides a “Next” button, enabling users to navigate through the forms one by one without returning to the report.After reviewing all forms, the selected Adobe Forms are automatically downloaded as PDF files, ensuring users have the final output ready for printing or further processing.Flow Diagram To Understand This Requirement:Start
↓
User selects delivery numbers on Selection Screen
↓
User clicks “Preview” button
↓
Is only one delivery selected?
↓ Yes ↓ No
↓ ↓
Open Adobe Form directly Open first Adobe Form
↓ ↓
End Show “Next” button
↓
User clicks “Next”
↓
Display next delivery Adobe Form
↓
More deliveries left?
↓ Yes ↓ No
↓ ↓
Go back to “Next” loop
↓
Download all selected
Adobe Forms as PDF
↓
EndImplementation:This solution is built using a classic ALV-based ABAP report where users can select delivery documents and trigger Adobe Form generation. The report reads header data from LIKP and item data from LIPS, then displays them in an editable ALV with a checkbox column. Users select one or multiple deliveries and click Preview or PDF. The helper class lcl_adobe_helper encapsulates all Adobe Form logic—opening the SFP print job, retrieving the generated function module using FP_FUNCTION_MODULE_NAME, preparing form parameters, and calling the form for each selected delivery. For preview mode, the form opens directly in the browser, and for PDF mode, the form output is returned as an XSTRING, converted to binary, and downloaded using GUI_DOWNLOAD. The flow also supports iterating through multiple selected deliveries and generating separate PDFs for each one. This modular design keeps the report clean while ensuring flexible preview and download options for batch delivery processing. “—————————————————————“
” Fetch Deliveries, Display in ALV with Checkbox, and Generate”
” Adobe Forms Individually for Selected Deliveries “
“—————————————————————“
TABLES : likp.
” Structure for ALV output
TYPES : BEGIN OF ty_likp,
vbeln TYPE vbeln,
ernam TYPE ernam,
erdat TYPE erdat,
checkbox TYPE char20,
END OF ty_likp.
” Selection option for Delivery Number
SELECT-OPTIONS : s_vbeln FOR likp-vbeln.
” Internal tables
DATA : lt_likp TYPE TABLE OF ty_likp WITH EMPTY KEY,
lt_lips TYPE TABLE OF zhr_str_lips,
ls_likp TYPE ty_likp.
” Field catalog for ALV
DATA(lt_fcat) = VALUE lvc_t_fcat(
( col_pos = 1 fieldname = ‘CHECKBOX’ checkbox = ‘X’ edit = ‘X’ )
( col_pos = 2 fieldname = ‘VBELN’ tabname = ‘LT_LIKP’ scrtext_l = ‘PURCHASE DOCUMENT NUMBER’ )
( col_pos = 3 fieldname = ‘ERNAM’ tabname = ‘LT_LIKP’ scrtext_l = ‘CREATED BY’ )
( col_pos = 4 fieldname = ‘ERDAT’ tabname = ‘LT_LIKP’ scrtext_l = ‘CREATED ON’ )
( col_pos = 5 fieldname = ‘MATNR’ tabname = ‘LT_LIPS’ scrtext_l = ‘MATERIAL NO’ )
( col_pos = 6 fieldname = ‘ARKTX’ tabname = ‘LT_LIPS’ scrtext_l = ‘MATERIAL DESCRIPTION’ )
( col_pos = 7 fieldname = ‘CHARG’ tabname = ‘LT_LIPS’ scrtext_l = ‘BATCH’ ) ).
” Create ALV Grid on screen container
DATA(lo_alv) = NEW cl_gui_alv_grid(
i_parent = NEW cl_gui_custom_container(
container_name = ‘CONT’ ) ).
“—————————————————————“
” Helper Class to Generate Adobe Form “
“—————————————————————“
CLASS lcl_adobe_helper DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
generate_adobe_form
IMPORTING
iv_preview TYPE abap_bool ” Preview or not
iv_getpdf TYPE abap_bool ” Download PDF or not
EXPORTING
ev_xstring TYPE xstring ” PDF content
ev_filename TYPE string. ” Output filename
ENDCLASS.
CLASS lcl_adobe_helper IMPLEMENTATION.
METHOD generate_adobe_form.
DATA: lv_fname TYPE funcname,
ls_o_p TYPE sfpoutputparams,
lt_likp_sel TYPE TABLE OF ty_likp,
lt_lips_sel TYPE TABLE OF zhr_str_lips,
lv_result_pdf TYPE fpformoutput,
lv_result_job TYPE sfpjoboutput.
” Setup Adobe Output Parameters
CLEAR ls_o_p.
ls_o_p-preview = iv_preview.
ls_o_p-getpdf = iv_getpdf.
ls_o_p-nodialog = abap_true.
ls_o_p-noprint = abap_true.
ls_o_p-noarchive = abap_true.
ls_o_p-dest = ‘LP01’.
” Open Adobe Print Job
CALL FUNCTION ‘FP_JOB_OPEN’
CHANGING ie_outputparams = ls_o_p.
” Get associated Form Function Module
CALL FUNCTION ‘FP_FUNCTION_MODULE_NAME’
EXPORTING i_name = ‘ZHR_ADOB’
IMPORTING e_funcname = lv_fname.
” Loop through selected deliveries
LOOP AT lt_likp INTO DATA(ls_likp) WHERE checkbox = abap_true.
” Prepare Header
CLEAR lt_likp_sel.
APPEND ls_likp TO lt_likp_sel.
” Prepare Items
CLEAR lt_lips_sel.
LOOP AT lt_lips INTO DATA(ls_lips) WHERE vbeln = ls_likp-vbeln.
APPEND ls_lips TO lt_lips_sel.
ENDLOOP.
” Call Adobe Form
CALL FUNCTION lv_fname
EXPORTING
lt_header = lt_likp_sel
lt_item = lt_lips_sel
IMPORTING
/1bcdwb/formoutput = lv_result_pdf
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ‘Error generating Adobe form’ TYPE ‘E’.
ELSE.
” Return PDF when required
IF iv_getpdf = abap_true.
ev_xstring = lv_result_pdf-pdf.
ev_filename = |{ ls_likp-vbeln }.pdf|.
ENDIF.
ENDIF.
ENDLOOP.
” Close print job
CALL FUNCTION ‘FP_JOB_CLOSE’
IMPORTING e_result = lv_result_job.
ENDMETHOD.
ENDCLASS.
“—————————————————————“
” Fetch Data and Display ALV “
“—————————————————————“
START-OF-SELECTION.
” Fetch Header Data
SELECT vbeln ernam erdat
FROM likp
INTO TABLE lt_likp
WHERE vbeln IN s_vbeln.
” Fetch Item Data
IF lt_likp IS NOT INITIAL.
SELECT vbeln matnr arktx charg
FROM lips
INTO TABLE lt_lips
FOR ALL ENTRIES IN lt_likp
WHERE vbeln = lt_likp-vbeln.
ENDIF.
” Display ALV Output
lo_alv->set_table_for_first_display(
CHANGING
it_outtab = lt_likp
it_fieldcatalog = lt_fcat ).
CALL SCREEN 1200.
“—————————————————————“
” Handle User Actions in ALV Screen “
“—————————————————————“
INCLUDE zhr_dynamic_adobe_status_12o01.
INCLUDE zhr_dynamic_adobe_user_commi01.
PAI:
MODULE user_command_1200 INPUT.
CASE sy-ucomm.
WHEN ‘&F03’. ” Exit
LEAVE TO SCREEN 0.
WHEN ‘PREVIEW’. ” Preview Adobe Form
lo_alv->check_changed_data( ).
lcl_adobe_helper=>generate_adobe_form(
EXPORTING
iv_preview = abap_true
iv_getpdf = abap_false ).
WHEN ‘PDF’. ” Download PDF
DATA: lv_xstring TYPE xstring,
lv_filename TYPE string,
lt_pdf_data TYPE solix_tab,
lv_pdf_size TYPE i.
lo_alv->check_changed_data( ).
” Generate PDF
lcl_adobe_helper=>generate_adobe_form(
EXPORTING
iv_preview = abap_false
iv_getpdf = abap_true
IMPORTING
ev_xstring = lv_xstring
ev_filename = lv_filename ).
” Download PDF to PC
IF lv_xstring IS NOT INITIAL.
CALL FUNCTION ‘SCMS_XSTRING_TO_BINARY’
EXPORTING buffer = lv_xstring
IMPORTING output_length = lv_pdf_size
TABLES binary_tab = lt_pdf_data.
CALL FUNCTION ‘GUI_DOWNLOAD’
EXPORTING
bin_filesize = lv_pdf_size
filename = lv_filename
filetype = ‘BIN’
TABLES
data_tab = lt_pdf_data.
ENDIF.
ENDCASE.
ENDMODULE.Conclusion:This approach provides a complete and user-friendly solution for generating Adobe Forms directly from an ALV-based selection. By enabling users to choose specific deliveries through checkboxes and dynamically building the header and item data, the program ensures flexibility and efficiency. The integration of Adobe form FM calls, and automatic PDF download makes the process seamless, whether the user wants a quick preview or a local PDF file. Overall, this design offers a practical, scalable, and easily reusable framework for handling document generation in SAP.Thanks for Reading, Best Wishes Read More Technology Blog Posts by Members articles
#SAP
#SAPTechnologyblog