Adobe Forms Part 5: The Driver Program Pattern
Write a production-grade Adobe Form driver: selection, data preparation per document, FP JOB OPEN once, FP FUNCTION MODULE NAME, per-document calls with SFPDOCPARAMS (language, country), error handling with exceptions and messages, FP JOB CLOSE with result, and the output-control entry routine.
Explanation
📌 KEY POINTS
✅ One FP_JOB_OPEN before the loop, one generated FM call per document, one FP_JOB_CLOSE after — all documents in one spool job.
✅ SFPDOCPARAMS sets language (LANGU) and country (COUNTRY) per document — they control translations and locale formatting.
✅ In output control, the driver's ENTRY routine reads NAST (document, printer, language) just like with Smart Forms.
⚠️ If FP_JOB_OPEN fails or the job is not closed, the whole run fails — handle exceptions and always close.
━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE
Part 4 designed the interface. Now the driver fills it and runs the job.
━━━━━━━━━━━━━━━━━━━━
▶ 1. STRUCTURE
- Selection (documents, printer, preview/PDF).
- FP_JOB_OPEN with SFPOUTPUTPARAMS (dest, nodialog, preview, getpdf, reqimm).
- FP_FUNCTION_MODULE_NAME.
- Loop: prepare data → set SFPDOCPARAMS → call FM → handle errors.
- FP_JOB_CLOSE (optionally with result: number of pages, spool IDs).
━━━━━━━━━━━━━━━━━━━━
▶ 2. OUTPUT CONTROL VARIANT
- FORM entry USING return_code us_screen: NAST-OBJKY, NAST-SPRAS, NAST-LDEST, TNAPR-SFORM (the "PDF/SmartForm Form" field of the processing routine, with form type PDF).
- Set return_code and write NAST_PROTOCOL_UPDATE messages.
━━━━━━━━━━━━━━━━━━━━
▶ 3. DATA PREPARATION
A class or FORM per document: read header, items, partner addresses, texts; compute presentation values. Reusable for Smart Forms and Adobe forms during migration.
━━━━━━━━━━━━━━━━━━━━
▶ 4. ERROR HANDLING
- FP_FUNCTION_MODULE_NAME raises class-based exceptions (CX_FP_API_*).
- The generated FM has classic exceptions (USAGE_ERROR, SYSTEM_ERROR, INTERNAL_ERROR) — sy-msg fields contain the reason (often ADS errors).
- Continue with the next document on error in batch runs; report failures.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
- Build the driver from the code example for your form.
- Print 3 documents in one job and check SP01.
- Force an error (inactive form) and verify the message handling.
✅ CHECKPOINT: you can write a robust Adobe Form driver for reports and output control.
Code example
REPORT zaf_invoice_driver. TABLES vbrk.SELECT-OPTIONS s_vbeln FOR vbrk-vbeln OBLIGATORY.PARAMETERS: p_dest TYPE rspopname DEFAULT 'LP01', p_prev AS CHECKBOX DEFAULT 'X'. DATA: lv_fm TYPE rs38l_fnam, ls_outpar TYPE sfpoutputparams, ls_docpar TYPE sfpdocparams, ls_result TYPE fpformoutput, lt_vbrk TYPE STANDARD TABLE OF vbrk, ls_vbrk TYPE vbrk, ls_header TYPE zaf_inv_header, lt_items TYPE ztt_inv_items, lv_errors TYPE i. START-OF-SELECTION. SELECT * FROM vbrk INTO TABLE lt_vbrk WHERE vbeln IN s_vbeln. CHECK lt_vbrk IS NOT INITIAL. * ===== Step 1: one job for all documents ===== ls_outpar-dest = p_dest. ls_outpar-nodialog = 'X'. ls_outpar-preview = p_prev. CALL FUNCTION 'FP_JOB_OPEN' CHANGING ie_outputparams = ls_outpar EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. MESSAGE 'Print job could not be opened' TYPE 'E'. ENDIF. * ===== Step 2: FM name ===== TRY. CALL FUNCTION 'FP_FUNCTION_MODULE_NAME' EXPORTING i_name = 'ZAF_INVOICE' IMPORTING e_funcname = lv_fm. CATCH cx_fp_api_repository cx_fp_api_usage cx_fp_api_internal. CALL FUNCTION 'FP_JOB_CLOSE' EXCEPTIONS OTHERS = 1. MESSAGE 'Form ZAF_INVOICE not available' TYPE 'E'. ENDTRY. * ===== Step 3: one call per document ===== LOOP AT lt_vbrk INTO ls_vbrk. PERFORM prepare_data USING ls_vbrk CHANGING ls_header lt_items. CLEAR ls_docpar. ls_docpar-langu = ls_header-spras. " document language ls_docpar-country = ls_header-land1. " locale formatting CALL FUNCTION lv_fm EXPORTING /1bcdwb/docparams = ls_docpar is_header = ls_header it_items = lt_items IMPORTING /1bcdwb/formoutput = ls_result EXCEPTIONS usage_error = 1 system_error = 2 internal_error = 3 OTHERS = 4. IF sy-subrc <> 0. lv_errors = lv_errors + 1. WRITE: / 'Error for', ls_vbrk-vbeln. ENDIF. ENDLOOP. * ===== Step 4: close ===== CALL FUNCTION 'FP_JOB_CLOSE' EXCEPTIONS OTHERS = 1. WRITE: / 'Documents with errors:', lv_errors. FORM prepare_data USING is_vbrk TYPE vbrk CHANGING cs_header TYPE zaf_inv_header ct_items TYPE ztt_inv_items. CLEAR: cs_header, ct_items. cs_header-vbeln = is_vbrk-vbeln. cs_header-fkdat = is_vbrk-fkdat. cs_header-waerk = is_vbrk-waerk. cs_header-spras = sy-langu. cs_header-land1 = is_vbrk-land1. SELECT posnr arktx fkimg vrkme netwr FROM vbrp INTO CORRESPONDING FIELDS OF TABLE ct_items WHERE vbeln = is_vbrk-vbeln.ENDFORM.Real project scenario
A migrated billing driver opened and closed an Adobe job per invoice. The nightly run of 8,000 invoices produced 8,000 spool requests and took four hours, mostly ADS connection overhead.
Refactoring to one job with per-document calls reduced it to one spool and 50 minutes. The driver also started passing the customer's language and country, fixing date and number formats for foreign customers.
Common mistakes
- One job per document in mass runs.
- Not closing the job after errors.
- Ignoring SFPDOCPARAMS language/country.
- Hard-coded form name instead of TNAPR/parameter.
- Stopping the whole run on one document error.
Best practices
- One job, many documents.
- Always close the job.
- Language and country per document.
- Data preparation in a reusable unit.
- Report per-document errors and continue.
Interview angle
Questions: "Explain an Adobe Form driver.", "How do you print multiple documents in one spool?", "How is the language controlled?"
Strong answer: FP_JOB_OPEN (SFPOUTPUTPARAMS) once, FP_FUNCTION_MODULE_NAME with CX_FP_API exceptions, per-document FM call with /1BCDWB/DOCPARAMS (LANGU, COUNTRY) and data, handle exceptions, FP_JOB_CLOSE; output-control ENTRY with NAST/TNAPR and return code.
Practice this lesson
Quick check
1. How should 5,000 invoices be printed with an Adobe Form driver?
2. Print job must be bracketed by:
3. In an ABAP print program, why is the language parameter passed when opening Adobe Form processing significant for the output?
Interview questions
1. How do you call an Adobe Form from an ABAP driver program?
Answer it in your own words first, then compare.
2. How do you call an Adobe Form from ABAP?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- Adobe Forms Part 1: What SAP Interactive Forms by Adobe Are
- Adobe Forms Part 10: Migrating Smart Forms to Adobe Forms
- Adobe Forms Part 2: SFP Form Design and Layout Basics
- Adobe Forms Part 3: Print Runs, Interactive Forms and Troubleshooting Overview
- Adobe Forms Part 4: Interface and Context Design
- Adobe Forms Part 6: Tables, Subforms and Repeating Item Data
- Adobe Forms Part 7: Texts, Logos, Barcodes and Images
- Adobe Forms Part 8: Output Parameters, PDF Return and Spool Handling