Home > front end >  WRBTR field calculation inside CASE throws error for max decimal places
WRBTR field calculation inside CASE throws error for max decimal places

Time:12-30

I have following select:

SELECT FROM bseg
LEFT JOIN aufk ON ( ltrim( aufk~aufnr, '0' ) = bseg~zuonr )
JOIN bkpf ON bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr AND bkpf~bukrs = bseg~bukrs
FIELDS bseg~bukrs, bseg~bschl, bseg~wrbtr, bseg~h_hwaer
INTO TABLE @DATA(output).

When the select is complete I loop over the output table making a calculation when bschl = '50'.

LOOP AT output ASSIGNING FIELD-SYMBOL(<output>) WHERE bschl = '50'.
  <output>-wrbtr = <output>-wrbtr * ( -1 ).
ENDLOOP.

Since ABAP 7.4 I could use CASE statements in the SQL select. This is what I want to use to get rid of the loop.

SELECT FROM bseg
LEFT JOIN aufk ON ( ltrim( aufk~aufnr, '0' ) = bseg~zuonr )
JOIN bkpf ON bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr AND bkpf~bukrs = bseg~bukrs
FIELDS bseg~bukrs,
CASE
  WHEN bseg~bschl = '50' THEN  bseg~wrbtr * ( -1 )
  ELSE bseg~wrbtr
  END AS bseg~wrbtr, bseg~h_hwaer
INTO TABLE @DATA(output).

This is on how I would deal with the requirements described above.

Unfortunately I get an error message:

The maximum possible number of places in the expression starting with WRBTR is 34 places with 2 decimal places.
There can be, however, no more than 31 places and 14 decimal places.`

I also tried to cast bseg~wrbtr:

WHEN bseg~bschl = '50' THEN  CAST( bseg~wrbtr * ( -1 ) )

-> ")" is invalid here (due to grammar).

Or

WHEN bseg~bschl = '50' THEN  CAST( bseg~wrbtr AS test ) * ( -1 ) 

-> "TEST" is invalid here (due to grammar).

Does someone know how to deal with this?

EDIT:

I have found a solution for my issue. Problem was that I converted the wrong way.

Here is a working solution for this problem.

CASE bseg~bschl
  WHEN '50' THEN CAST( bseg~wrbtr AS D34N ) * CAST( -1 AS D34N )
  ELSE CAST( bseg~wrbtr AS D34N )
  END AS wrbtr, bseg~h_hwaer,

CodePudding user response:

My answer is specific to setting a sign via * -1. It doesn't apply to multiplications with other numbers.

In ABAP 7.52 and S/4HANA 1709, BSEG-WRBTR is still a packed-7-bytes number including 2 decimals, and except END AS bseg~wrbtr which leads to the error "~" is invalid here (due to grammar) and must be replaced with END AS wrbtr, the syntax is valid in my system.

In my system, the inline declaration of the output table chooses a packed-13-bytes number including 2 decimals. It's the multiplication that makes the number of digits in the output table multiplied by 2 (from 7 bytes to 13 bytes). As a comparison, an addition would only declare a packed-8-bytes number.

I guess you have a more recent S/4HANA version with BSEG-WRBTR having many more digits (feature called "Amount Field Length Extension"), it's why the multiplication makes the inline declaration produces an invalid type with too many digits.

Workaround: if you sign without multiplying, it will keep the same number of digits (packed-7-bytes number in my case), and this syntax should also work in your case:

CASE bseg~bschl
  WHEN '50' THEN - bseg~wrbtr  "<=== negative sign, is not the same logic as * -1
  ELSE bseg~wrbtr
  END AS wrbtr

CodePudding user response:

The proper CASE syntax:

CASE bseg~bschl
  WHEN '50' THEN  bseg~wrbtr * ( -1 )
  ELSE bseg~wrbtr
  END AS bseg~wrbtr

Move bseg~bschl right after case and after WHEN mention only the values for equality

CodePudding user response:

The results of the calculation of CAST( bseg~wrbtr AS D34N ) * CAST( -1 AS D34N ) in your CASE are put into data object of type calculation type.

According to the docu, the calculation type for the WRBTR (ABAP type P) is also P, but with important remark:

A calculation type p in assignments to an inline declaration can produce the data type p with length 8 and no decimal places and this can produce unexpected results and raise exceptions

SOLUTION: remove the inline declaration INTO TABLE @DATA(output) from your select query and declare your itab in advance with a proper accuracy.

  • Related