Technical Articles
Dynamic scripts in ABAP? Where and How
Where
Even if you don’t familiar with JavaScript templating engines which of the following statements is more straight forward and clear?
JavaScript language in templating engine & LiveCycle Designer
In the left part of the image is easy to find IF statement. On the right part we have to “drilldown” to the source code and then try to refresh our memory JS syntax (or even FormCalc). Maybe in SAP world instead of these scripting languages ABAPScript would be more suitable?
How
Perhaps in reports already prepared data will be the best choice for templates (or views in MVC terminology).
Imagine we already have the structure like that
and just want to add a.m. or p.m. texts for the TIME field. We can easily create new “TIME_AMPM TYPE STRING” field to a model.
But a view already has necessary the TIME field. So could we change responsibility from a model to a view?
In the other words is it possible to move ABAP code to a Pdf or Excel template itself?
DATA(result) = COND #( WHEN value-time GE '120000'
THEN 'post meridiem'
ELSE 'ante meridiem' ).
Do you think a view like that will be more readable than FormCalc script. Don’t you?
No FormCalc nor JavaScript
No VBA. Just familiar COND #( )
In dynamic script the special “value” filed refers to the whole structure.
Let’s take a look to the R-T table. Usually there was a special field in ts_rand_data structure for numeration. Something like that “index TYPE sytabix,”
" Random table data
BEGIN OF ts_rand_data,
group TYPE string,
caption TYPE string,
date TYPE d,
sum1 TYPE bf_rbetr, " P with sign
sum2 TYPE bf_rbetr, " P with sign
END OF ts_rand_data,
tt_rand_data TYPE STANDARD TABLE OF ts_rand_data WITH DEFAULT KEY,
" Document structure
BEGIN OF ts_root,
title TYPE string,
t TYPE tt_rand_data, " internal flat table ( In template {R-T} )
date TYPE d, " 8
time TYPE t, " 6
datetime TYPE cpet_reftimestamp, " 14 = date(8) + time(6)
END OF ts_root.
Now we can omit the entire condition with WHEN part and use sy-tabix system filed.
You can freely use any ABAP expression that returns a result.
Technical implementation
As you already guessed under the hood for every structure with cond expression the XTT library calls GENERATE SUBROUTINE to create SUBROUTINEs and then PERFORM them.
- a maximum of 36 temporary subroutine pools can be created. That’s why within the R structure you can use up to 36 nested tables & structures with cond expression.
- If template script doesn’t have leading WHEN statement it will be executed as is. VALUE #( ) REDUCE #( ) etc are not prohibited
- For sake of backwards compatibility COND statement converted to IF-ELSE(ELSEIF)-ENDIF. “&&” converted to CONCATENATE (string templates |{…}| remain as is)
Catching errors
What happens if the expression throws an exception?
For example, should line_exists() be checked before table [key]?
Exceptions in COND are caught. And an empty value of a certain type will be returned.
In DEV & QAS, a warning window will pop up
In PROD, the report will behave “quietly”
* If you have syntax error in COND the log will display “red” errors.
For those who are not afraid to get their hands dirty
- Direct links to templates: Excel, Word, LiveCycle Designer XDP template .
- There are also dynamic expression for hiding entire template blocks, and conditional output for table rows. But maybe more on that next time
Thanks for sharing!
It seems like an important part is missing and it is "why". 🙂 It's an interesting sort of "tech flex" exercise, like those "ABAP games" blogs etc. But is there actual practical use for this? It doesn't seem to be more readable or efficient, to be honest. So what's the point? Just because we can? I'm a bit confused...
Hi Jelena
Yep you are right. For very big Excel files it could significantly slows down execution time. Since executing perform in generated subroutine pool is obviously much slower. But the entire program is generated just 1 time. Usually for pdf & word reports it don't even matter how fast they were created. (additional 0.1 sec or 0.01 sec don't make a big deal difference)
Wrote a little FAQ (the measurement details are below)
>>is missing and it is "why".
Because is very flexible & very often FormCalc (or JS) code is very confusing for ABAP-ers.
In a view (a template) there could be small COND statements that really make it easier to understand reporting logic. Most of them look like simple ternary operator (COND in ABAP)
And because the code is "visible" (not hidden as in LiveCycle Designer) the whole report could be more clear (understandable)
------------------------------------------------------
Measurement results in tr. SAT report for a table with 150.000 lines (examples 02-01 and 13-01)
30 and 45 seconds respectively
;cond= will be slightly faster if the structure is declared in the data dictionary(SE11).
In the example 13-01 the structure is declared in the program and there is a MOVE-CORRESPONDING statement inside the dynamically created subroutine.
Result is about *=1.5 slower on the same number of lines. But the 13-01 example’s file itself is larger and therefore takes longer to process.
For large Excel reports, it may be worth doing the old-fashioned way and making calculations statically with ABAP.
For Word or Pdf reports, additional calls of a Perform in SUBROUTINE POOL will not be very significant, since there is usually relatively small amount of processed data
Hi Birzhan,
First of all, thanks a million for such an amazing tool, designed in such a clean and understandable way =)
This is a huge timesaver!
One stupid question: is there an explicit way to suppress warnings in DEV/QAS?
Thanks in advance, Alice.
Hi Alice, thank you
for WFs there is a special iv_no_warning parameter
but probaly you have ZSY_XTT 013 messages in word. Right?
in that case just press Repair the template buttun (if you don't see it please update xtt to the last version)
which tries to use first char '{' format for entire {R-TITLE} anchor
XTT doesn't replace implicitly all anchors like that (and you have to press the button manually) since maybe in rare cases you receive unexpected formatting or even the template could be broken
Oh! =)
Got it =) Thank you!
I had it in the "footer" of the .html template, which then used as an email.
BTW, I've added the markdown support (with this project GitHub - koemaeda/abap-markdown: ABAP Markdown) as a type=md, to use as "managed" alternative to html. (Which is crucial in case of "self-service" template).
So the typical usage would be something like:<div>{R-GREET;type=md}</div>
Not sure if you accept PR's on github, but I can try =)
Tnx again for your prompt response ^_^.
Best regards, Alice.