Link Search Menu Expand Document

COND #( ) operator

Refinement of reports using scripts

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


‘;cond=’ addition

For now, suppose we have a structure of the following form

image

Earlier in the report for the TIME field, you had to add an additional variable to display (for example) the am or pm texts.
Now, you can put it in a more concise way by simply creating this variable on the fly, as we do in ABAP.

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

where value is the structure described earlier.

Only this time, such a variable can be created in the report itself 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

For convenience {R;cond=WHEN value-time GE ‘120000’ THEN ‘pm’ ELSE ‘am’} can be abbreviated to {R:WHEN v-time GE ‘120000’ THEN ‘pm’ ELSE ‘am’}

*See templates 131

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)


FAQ

  • All examples are in Excel. Does it work only in it?
    Word, Pdf and Html are of course supported too

image


  • What about compatibility with older ABAP versions? COND () is not in my system.
    at 7.01 I hope it will work. Although for ZABAPGIT the minimum version is 7.02 (and without it, you can’t install any opensource package). 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 if the expression throws an exception?
    For example, should line_exists() be checked before table [key]? image

Exceptions 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” (unless of course there are no critical important errors)

image


  • COND # () only? SWITCH or VALUE?
    Yes in ‘;cond=’ addition any ABAP expression that is exactly to the left of the sign ‘=’ is allowed.
    Those expressions that can be assigned to a variable, including the CONV, REDUCE and COND statements.
    Just imho, the most useful will be exactly condition for displaying the value, therefore it is ;cond=WHEN
    If the expression does not start with WHEN, there will be a simple assignment to result =, without wrapping it in = COND string( ), more precisely IF-ELSE-ENDIF.

  • Can I then write REDUCE to calculate totals?
    It is possible (there is even example 13-03), but I think it is not necessary.
    In total, there are 5 (with REDUCE already 6) more readable ways to calculate totals (3 of which are available only in Excel, because they use formulas).
    The simplest (and therefore preferable) of them, which, moreover, works in all formats, and does not require writing additional code from the ABAP side is:
    writing {R-T;group=} anywhere in the template (;group=BUKRS if you need subtotals for Company Code), which will transform the table {R-T} into a tree.
    The ‘Total for all’ node (level=0) will be the top node, and level=1 will be directly the table data itself. At in the grouping level=0 you can write something like that {R-T-DMBTR;func=SUM| AVERAGE | COUNT | FIRST }

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=’ is 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, 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


  • Can a method be called in an expression?
    Yes, you can call any static methods with a RETURNING parameter. But that’s not quite right.
    Template is a View and it should abstract from Model as much as possible. So the SELECT statements in this method will violate this rule.
    In addition, the Z* method can have a special operator introduced in 7.70 STEAL MONEY
    I even thought about writing a ban on the sequence of characters ‘=>’, but changed my mind.
    I leave it to your discretion.