Generate this example Choose a template and create a fresh report with the demo service.

xtt->merge( iv_block_name = 'R' is_block =

JSON
{"TITLE":"Title","T":[{"GROUP":"GRP A","CAPTION":"<Caption 1 />","DATE":"2020-10-21","SUM1":5971.44,"SUM2":5021.46},{"GROUP":"GRP C","CAPTION":"<Caption 2 />","DATE":"2020-10-19","SUM1":2276.75,"SUM2":7717.2},{"GROUP":"GRP B","CAPTION":"<Caption 3 />","DATE":"2020-10-20","SUM1":3031.38,"SUM2":445.22},{"GROUP":"GRP A","CAPTION":"<Caption 4 />","DATE":"2020-10-21","SUM1":9476.79,"SUM2":3683.27},{"GROUP":"GRP A","CAPTION":"<Caption 5 />","DATE":"2020-10-21","SUM1":4604.0,"SUM2":5525.85},{"GROUP":"GRP C","CAPTION":"<Caption 6 />","DATE":"2020-10-19","SUM1":2159.71,"SUM2":2260.94},{"GROUP":"GRP B","CAPTION":"<Caption 7 />","DATE":"2020-10-20","SUM1":2490.3,"SUM2":6388.81},{"GROUP":"GRP A","CAPTION":"<Caption 8 />","DATE":"2020-10-21","SUM1":5476.81,"SUM2":406.18},{"GROUP":"GRP D","CAPTION":"<Caption 9 />","DATE":"2020-10-18","SUM1":689.66,"SUM2":518.6},{"GROUP":"GRP C","CAPTION":"<Caption 10 />","DATE":"2020-10-19","SUM1":5451.87,"SUM2":4061.85},{"GROUP":"GRP D","CAPTION":"<Caption 11 />","DATE":"2020-10-18","SUM1":4573.55,"SUM2":5436.0},{"GROUP":"GRP C","CAPTION":"<Caption 12 />","DATE":"2020-10-19","SUM1":1196.35,"SUM2":522.46},{"GROUP":"GRP C","CAPTION":"<Caption 13 />","DATE":"2020-10-19","SUM1":7686.95,"SUM2":2727.98},{"GROUP":"GRP D","CAPTION":"<Caption 14 />","DATE":"2020-10-18","SUM1":978.18,"SUM2":295.55},{"GROUP":"GRP D","CAPTION":"<Caption 15 />","DATE":"2020-10-18","SUM1":71.12,"SUM2":8878.56}],"DATE":"2020-10-21","TIME":"12:12:12","DATETIME":"20201021121212"}

).


Generate demo 130

COND #( ) operator

Request preview

Purpose

Demo ZCL_XTT_DEMO_130 evaluates small ABAP expressions inside a marker. Use ;cond= for presentation logic that returns one value - choosing a label, formatting a derived value, or reading a component without adding a dedicated field to the report context.

Keep business rules and data access in ABAP classes. A template is a view, and expressions are most maintainable when they remain short and side-effect free.

Why ABAP expressions

JavaScript, FormCalc and VBA. Which language is most convenient for generating reports?

image

“Should I write the condition in parentheses?”, “This, me or self?”, “THEN or curly braces?”, “.Value, or is it still .rawValue to get the value?”. “super or duper?”

Hundreds of lines without any highlighting in a particularly ancient and “mega fancy” LiveCycle report will help you to understand all the intricacies of scripting languages. (Even if you don’t want it at all)
Of course, things are better in VBA, and it doesn’t hurt to know several languages.
But you must admit it would be convenient to use the language that you understand without translation and a dictionary. Without remembering and googling every line of writing.

For example, for Russian speakers this piece of code is also as understandable as ABAP for English speakers image

Therefore, in my opinion, using ABAP instead of JavaScript (which stopped developing after version 1.5) would be justified due to its understandability for SAP developers

Of course Abap is not a script language and was very verbose 10 years ago.
A lot of water has flowed under the bridge since then, and now it has become more laconic and you can often write complex expressions in one line.
And such expressions can be very useful in reports, where this role is often played by scripting programming languages.
Fortunately, for the most part, most of the tasks boil down to conditional output from several fields of some information that has already been generated by ABAP earlier.

  if root-flag = abap_true.
   result = root-A.
  else.
   result = root-B.
  endif.

Or hiding part of the template by condition.

  block.Visible = False

But more on that next time


The ;cond= directive

Assume the report receives the following structure:

image

Instead of adding a separate field for an am or pm label, derive it in the marker with the same expression you would use in ABAP:

DATA(result) = COND #( WHEN value-time GE '120000'
                       THEN 'post meridiem'
                       ELSE 'ante meridiem' ).

Within ;cond=, value refers to the current report context.

The template can therefore calculate the display value directly: image (* hereinafter, the highlighting in the template was introduced purely for demonstration purposes, but I think ABAPers can easily understand the code without it) — and in general, why transfer the date (R-DATE) and time (R-TIME) if we need system fields of sy structure?
You can just omit the WHEN clause and write something like.

image

  • But then in the case of ABAP 6.40 run from the project your system will not understand the report and will ask you for it Herr programmer, Was ist das?
  • For backward compatibility see FAQ

Additional variable for numbering table rows? You can also throw her overboard image

*;type=integer is needed so that Excel does not have unnecessary questions about the sy-tabix data type.
By default all expressions in ‘;cond=’ are converted to strings (;type=string)
I removed the backlighting in the last example, I want to believe that the main idea is more or less clear.

Shorthand

{R;cond=WHEN value-time GE '120000' THEN 'pm' ELSE 'am'} can be shortened to {R:WHEN v-time GE '120000' THEN 'pm' ELSE 'am'}.

See demo 131 for complete XLSX and DOCX form examples.

In order to reduce the number of possible technical questions, I give a short FAQ in my view (for lack of real questions)
(*The list will be extended if necessary)


Behavior and compatibility

Is the directive limited to Excel?

No. Word, PDF, and HTML output are supported as well.

image


What about older ABAP releases?

The library targets the releases supported by the installation package. Before generating the subroutine pool, XTT translates supported COND patterns to IF/ELSEIF/ENDIF and can translate simple concatenation expressions. 1) COND # ( ) itself before entering to GENERATE SUBROUTINE POOL is translated to IF-ELSEIF-ENDIF 1) if the expression does not have a leading WHEN and contains && the expression is converted to CONCATENATE.
Therefore, in order to avoid errors, in newer versions it is preferable to use String Templates instead of double ampersand


What happens when an expression raises an exception?

For example, must LINE_EXISTS( ) be checked before a table expression? image

XTT catches expression exceptions and returns the initial value of the requested type. Development and quality systems display a warning; production processing remains quiet unless the error is critical. Treat a blank result as a possible error, not only as missing data.

image


Is COND the only supported expression?

No. Any supported ABAP expression that can appear on the right side of an assignment may be used, including SWITCH, VALUE, CONV, and REDUCE. An expression beginning with WHEN is wrapped as a condition; other expressions are assigned directly.


Should REDUCE calculate report totals?

It can, but tree aggregation is usually clearer and works across output formats. Convert the table to a tree with {R-T;group=...} and place ;func=SUM, AVG, COUNT, or FIRST on the appropriate level.

for Excel, in general, you can use an ListObject in conjunction with ‘=SUBTOTAL(109, [SUM 1])’
More details are here 02-02, 02-03
This digression (as well as the article as a whole) probably already tired the reader :)

image


Is ;cond= fast enough?

Measurement results in tr. SAT report for a table with 150.000 lines (examples 02-01 and 13-01)
30 and 45 seconds respectively

image

;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.

image

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, precompute values in ABAP and benchmark with representative data. Word and PDF documents usually contain fewer repeated rows, so the expression overhead is often less significant.


Can an expression call a method?

Static methods with a returning parameter can be called, but keep templates separate from data access and business behavior. A method that performs SELECT statements from a marker makes the report harder to test, audit, and tune. For deliberate object-method calls, use the ;call= directive.