Why CALL TRANSACTION fails in automatic/background mode for certain transactions
This is one of those bugs that makes you doubt your own code: automation via CALL TRANSACTION works perfectly when you test it in dialog, works perfectly for most transactions in background… and fails, quietly or loudly, for one specific transaction.
The symptom
The job finishes “fine” (no dump), but the document isn’t created, or it’s created half-complete, or BDCMSGCOLL returns messages that make no sense compared to what you see running the transaction by hand. Sometimes it’s worse: CALL TRANSACTION simply hangs the job until timeout.
The real cause
CALL TRANSACTION simulates a user navigating screens: it fills dynpro fields and “presses” whichever button you tell it to (ENTER, BACK, etc.), based on the BDC mapping you pass in. This assumes the transaction behaves the same in front of a user as it does in front of a batch input. That’s not always true.
Many transactions — especially ones with custom logic in user-exits, BAdIs, or just old code — explicitly check the execution mode:
IF sy-batch = abap_true.
" different behavior: a validation is skipped,
" no POPUP is triggered, the screen flow changes...
ENDIF.
IF sy-binpt = abap_true.
" sy-binpt means "we're in batch input",
" and it's easy to find code here that assumes
" certain fields are already filled in from a
" previous screen that doesn't exist in your mapping
ENDIF.
When the transaction has a conditional CALL SCREEN (say, a confirmation popup that shows up in dialog mode but gets skipped or auto-confirmed with a default value in batch input — one that isn’t what you expected), your field mapping stops matching the actual screen sequence. The result is exactly the kind of silent failure described above.
How to confirm it
Before spending hours blindly tweaking the BDC mapping:
- Run the transaction by hand in “show all screens” mode, recording the same sequence you’re trying to automate via SHDB, and compare the number and order of screens against your mapping.
- Check whether the transaction calls any known BAdI/user-exit that reads
sy-batchorsy-binpt— a “where used” search (SE24/SE18) on those system fields inside the transaction’s includes usually gives it away fast. - Check which
CALL TRANSACTIONmode you’re using:'A'(all screens, for debugging),'E'(errors only), or'N'(no screens, the one you’d actually use in background). Behavior can differ between these three.
The fix that actually works
Once you confirm the transaction has execution-mode-dependent logic, keeping on with BDC is fighting the standard. The alternatives that actually work, from best to worst:
- Use the equivalent BAPI or standard function module, if one exists, instead of simulating screens. Most document-creation transactions (orders, invoices, materials) have a BAPI behind them that doesn’t depend on dynpros or on
sy-batch. - If there’s no BAPI, isolate the problem with a batch-mode-specific BDC mapping (sometimes the fix is as simple as passing a different field value only for that scenario, not rewriting all the logic).
- As a last resort, and only if nothing above is viable,
CALL TRANSACTIONin mode'A'with exception handling for the specific popup — more fragile, but explicit about what you’re forcing.
The lesson
CALL TRANSACTION isn’t “record and replay”: it’s simulating an interaction with a screen that can behave differently depending on the execution context. When something only fails in background, your first suspicion shouldn’t be your mapping — it should be how the transaction handles sy-batch and sy-binpt.