###### Technical Articles

# ABAP CDS Cheat Sheet: Amounts and Quantities in ABAP CDS

In ABAP CDS, a special handling for amounts and quantities is implemented. If differs from DDIC amount and quantity handling and it has recently been overhauled. Read this blog post and learn about ABAP CDS amount and quantity fields, conversion functions, and handling of amounts and quantities in expressions.

Contents:

- CDS Amount Field
- CDS Quantity Field
- CDS Calculated Quantity with Calculated Unit
- Unit and Currency Conversion Functions
- Amounts and Quantities in Expressions
- Amounts and quantities in arithmetic expressions
- Amounts and quantities in aggregate functions
- Amounts and quantities in simple and complex case expressions
- Amounts and quantities in comparisons
- Amounts and quantities in UNION views and INTERSECT views

## CDS Amount Field

- Field that stores an amount in a specific currency.
- Possible data types: CURR, DECFLOAT34, DEC, and FLTP.
- Reference to a currency key using the annotation
*@Semantics.amount.currencyCode*is mandatory. - A currency key must have data type CUKY and it can contain a currency ID from the DDIC database table TCURC.

Further details: ABAP CDS – Amount Fields on SAP Help Portal.

## CDS Quantity Field

- Field that stores a quantity in a specific unit.
- Possible data types: QUAN, DECFLOAT16, DECFLOAT34, DEC, FLTP, INT1, INT2, or INT4.
- Reference to a unit of measurement key using the annotation
*@Semantics.quantity.unitOfMeasure*is mandatory. - A unit of measurement key must have data type UNIT and can contain a unit ID from the DDIC database table T006.

Further details: ABAP CDS – Quantity Fields on SAP Help Portal.

## CDS Calculated Quantity with Calculated Unit

This is a new feature that was first released with kernel release 7.84, SAP BTP ABAP Environment 2105, ABAP release 7.56. It is available in CDS view entities (DEFINE VIEW ENTITY).

- A calculated quantity is a field that stores a quantity in a self-defined unit.
- It is always the result of a calculation using amounts and quantities.
- A calculated quantity always has data type DECFLOAT34.
- A reference to a calculated unit using the annotation
*@Semantics.quantity.unitOfMeasure: ‘calculatedUnit’*is mandatory. - A calculated unit has data type CHAR and specifies a self-defined unit, such as €/m
^{2}(cost per square meter of an apartment, for example).

Further details:

- ABAP CDS – Calculated Quantity with Calculated Unit on SAP Help Portal.
- CDS view entities are feature complete, Part l: New features | SAP Blogs (Item 3)

**Example**

Arithmetic expression |
Result |

770 € (Amount) / 100m² (Quantity) | 7,70€/m² (Calculated Quantity) |

The arithmetic expression 770€ / 100 m^{2 }calculates cost per square meter. It divides an amount by a quantity. The result of this calculation is a calculated quantity that has calculated unit reference assigned. This calculated unit is not registered in the unit check table T006.

**Example**

In the following CDS view entity, the field *rent_per_size* divides the amount of the rent for an apartment by the apartment size. The result is the cost per square meter.

- Field
*rent_decfloat34*has data type DECFLOAT34 and a currency key reference. - Field
*apartment_size*has data type QUAN(10,2) and a unit key reference. - The calculated unit is defined by means of a concatenation of a currency code, a forward slash, and the apartment unit. The resulting calculated unit is EUR/MTK, MTK being the unit ID for square meter.

```
@AccessControl.authorizationCheck: #NOT_ALLOWED
@EndUserText.label: 'CDS view entity, calculated quantity'
define view entity DEMO_CDS_CALCULATED_QUANTITY
as select from demo_rent
{
key apartment_id as ApartmentId,
apartment_size as ApartmentSize,
apartment_unit as ApartmentUnit,
currency as Currency,
// currency field and unit field in arith expression
@Semantics.quantity.unitOfMeasure: 'calculatedUnit'
rent_decfloat34 / apartment_size as rent_per_size,
concat( concat(currency, '/' ), apartment_unit )
as calculatedUnit
}
```

If data is inserted into the underlying database talbe *demo_rent*, the data preview might look as follows:

## Unit and Currency Conversion Functions

Function |
Effect |

UNIT_CONVERSION( quantity => arg1,source_unit => arg2, target_unit => arg3 [,client => arg4 ][,error_handling => arg5 ]) |
Performs a unit conversion for Has been available “forever”, i.e. since ABAP release 7.40. Available in CDS DDIC-based views and in CDS view entities. |

CURRENCY_CONVERSION(amount => arg1, source_currency => arg2, target_currency => arg3, exchange_rate_date => arg4 [,exchange_rate_type => arg5 ][,client => arg6 ][,round => arg7 ][,decimal_shift => arg8 ][,decimal_shift_back => arg9 ][,error_handling => arg10 ]) |
Performs a currency conversion for Has been available “forever”, i.e. since ABAP release 7.40. Available in CDS DDIC-based views and in CDS view entities. |

GET_NUMERIC_VALUE( arg ) |
Returns the numeric value of a currency or quantity field without its currency or unit key. Available since kernel release 7.83, SAP BTP ABAP Environment 2102, ABAP release 7.56. Available in CDS view entities. |

CURR_TO_DECFLOAT_AMOUNT( arg ) |
Converts a currency field of data type CURR into a currency field of data type DECFLOAT34. Available since kernel release 7.83, SAP BTP ABAP Environment 2102, ABAP release 7.56. Available in CDS view entities. |

**Note**: **DECIMAL_SHIFT** is available in the obsolete CDS DDIC-based views. It is not available in the “new world” of CDS view entities.

Further info on SAP Help Portal, Unit and Currency Conversion Functions

**Example**

The following CDS view entity applies the function **GET_NUMERIC_VALUE** to calculate the number of bookings. It divides the total value of current bookings (field *paymentsum*) by the price of a flight (field *price*). This would not be possible without the function **GET_NUMERIC_VALUE**, since elements of data type CURR are not allowed in arithmetic expressions.

Details on the elements:

*paymentsum*has data type CURR, a reference annotation that assigns a currency key, and it contains the total value of current bookings.*price*has data type CURR, a reference annotation that assigns a currency key, and it contains the price of a flight.*number_of_bookings*has data type DECFLOAT34 and it has no currency key assigned.

```
AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'CDS view entity, GET_NUMERIC_VALUE'
@Metadata.ignorePropagatedAnnotations: true
define view entity DEMO_CDS_GET_NUMERIC_VALUE
as select from sflight
{
key carrid,
key connid,
key fldate,
@Semantics.amount.currencyCode: 'currency'
price,
currency,
@Semantics.amount.currencyCode: 'currency'
paymentsum,
GET_NUMERIC_VALUE( paymentsum )
/ GET_NUMERIC_VALUE( price ) as number_of_bookings
}
```

## Amounts and Quantities in Expressions

In the “new world” of CDS view entities, amounts and quantities are considered in expressions, union views, and intersect views. Special rules apply how amounts and quantities can be combined:

- Amounts and quantities in arithmetic expressions
- Amounts and quantities in aggregate functions
- Amounts and quantities in simple and complex case expressions
- Amounts and quantities in comparisons
- Amounts and quantities in
**UNION**and**INTERSECT**views

**Note**: Cast expressions do not handle amounts. Only the target type CURR requires a reference to a currency key.

### Amounts and quantities in arithmetic expressions

Release info: available since kernel release 7.84, SAP BTP ABAP Environment 2105, ABAP release 7.56

operand / operator |
/ |
* |
+, – |

amount, amount | calculated quantity | calculated quantity | amount |

quantity, quantity | calculated quantity | calculated quantity | quantity |

calculated quantity, amount | calculated quantity | calculated quantity | amount |

amount, quantity | calculated quantity | calculated quantity | – |

calculated quantity, number | calculated quantity | calculated quantity | – |

calculated quantity, quantity, | calculated quantity | calculated quantity | quantity |

calculated quantity, calculated quantity | calculated quantity | calculated quantity | calculated quantity |

amount, number | amount | amount | – |

number, amount | calculated quantity | amount | – |

quantity, number | quantity | quantity | – |

number, quantity | calculated quantity | quantity | – |

Further details: Amounts and Quantities in Arithmetic Expressions on SAP Help Portal

### Amounts and quantities in aggregate functions

Release info: available since kernel release 7.84, SAP BTP ABAP Environment 2105, ABAP release 7.56

If the operand of an aggregate function is a CDS amount field, a CDS quantity field, or a CDS calculated quantity, the result type might require a reference annotation as well. The following table shows the result type depending on the operand type of all available aggregate functions.

Aggregate Function |
Type of Operand |
Result Type |

MAX, MIN, SUM, AVG | amount | amount |

MAX, MIN, SUM, AVG | quantity | quantity |

MAX, MIN, SUM, AVG | calculated quantity | calculated quantity |

COUNT | amount, quantity, calculated quantity | number of type INT4 |

Further details: Amounts and Quantities in Aggregate Expressions on SAP Help Portal.

### Amounts and quantities in simple and complex case expressions

Release info: available since kernel release 7.84, SAP BTP ABAP Environment 2105, ABAP release 7.56

The result data type of a case expression (simple and complex) is determined by all THEN branches and the ELSE branch. If the result data type is a CDS amount field, a CDS quantity field, or a CDS calculated quantity, a reference annotation must be assigned. The following table shows how the result data type is calculated if one or more of the operands are amount and/or quantity fields.

Operand1 / Operand2 |
Amount |
Quantity |
Calculated Quantity |
Number |

Amount |
amount | calculated quantity | calculated quantity | calculated quantity |

Quantity |
calculated quantity | quantity | calculated quantity | calculated quantity |

Calculated Quantity |
calculated quantity | calculated quantity | calculated quantity | calculated quantity |

Number |
calculated quantity | calculated quantity | calculated quantity | number |

Further details on SAP Help Portal:

**Example**

The example shows a CDS view entity with two complex case distinctions using amount and quantity fields.

```
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view entity DEMO_CDS_COMPLEX_CASE_1
as select from DEMO_CDS_CALC_QUANTITY_BASE
{
key Id,
//amounts and calculated quantities are compatible,
//result is a calculated quantity
@Semantics.quantity.unitOfMeasure: 'Calcunit'
case
when Char1 = abap.char'A'
then Dec10 //cuky reference -> amount field
when Char1 = abap.char'B'
then 100 / Dec10 //calculated quantity
else 0
end as calcQuan,
Cuky,
concat( concat( Cuky , '/' ), Unit2 ) as calcUnit,
//CURR requires conversion to DECFLOAT34
@Semantics.amount.currencyCode : 'cuky'
case when Char1 = abap.char'A'
then CURR_TO_DECFLOAT_AMOUNT( Curr102 )
else Dec10 //cuky reference
end as CurrConv
}
```

### Amounts and quantities in comparisons

Release info: available since kernel release 7.87, probably included in the next big on-prem shipment.

If one of the operands of a comparison is a CDS amount field, a CDS quantity field, or a CDS calculated quantity, special rules apply:

- Both operands must have the same reference type. Both must be either amounts, or quantities, or calculated quantities. Comparing operands with references of different types (currency key, unit key, or calculated unit) results in a syntax check warning.
- An operand of type CURR can only be compared with another operand of type CURR. The number of decimal places of both operands must match exactly.

The following table shows the possible combinations of operands in comparisons. Number refers to an operand of a numeric data type without reference annotation that turns it into an amount or quantity field.

Further details: Comparisons with Amounts and Quantities on SAP Help Portal.

### Amounts and quantities in UNION views and INTERSECT views

In UNION views and INTERSECT views, the data types of elements of different branches must match. For CDS amount fields, CDS quantity fields, and CDS calculated quantities, this implies:

- Calculated quantity fields can be merged only with other calculated quantity fields.
- Amount fields and quantity fields can be merged with each other, as long as the data types match.
- For amount fields of type CURR, the number of decimal places must match exactly in all UNION branches.
- Elements of data type CURR are incompatible to any other data type. The function CURR_TO_DECFLOAT_AMOUNT can be used to convert an amount field of data type CURR into an amount field of data type DECFLOAT34.

Questions, comments, or further details required? Use the **Comments** section below. Discussions are welcome.

Don’t miss out on ABAP CDS News. Follow my profile Andrea Schlotthauer for similar blog posts.

Thanks for the detailed overview.

What would be the result of GET_NUMERIC_VALUE ( 60.00 JPY )?

(6000 JPY in external format)

Hi,

the value stays exactly the same.

The function removes the reference to a currency key and it converts the data type to DECFLOAT34. If

arghas data type CURR, an implicit decimal shift takes place.Purpose: strict checks have been implemented for calculations with amounts in expressions and with this function, some limitations can be circumvented.

Docu on SAP Help Portal.

Does that answer your question? Any further issues?

Almost.

The statement "If

arghas data type CURR, an implicit decimal shift takes place." is quite amorphic.I brought JPY as an example. The (external) value of 6000 JPY is internally stored in ABAP as 60.00 JPY. What would be the result of GET_NUMERIC_VALUE? 6000 or 60.00?

It depends how the value 60.00 JPY is stored in your system:

The decimal shift calculates the difference between the number of decimal places of the currency and the number of decimal places of the column.

JPY does not have any decimal places. Your column apparently has two decimal places.

2 - 0 = 2. The comma is shifted two places to the right. In other words, the value is multiplied by 100. The result of GET_NUMERIC_VALUE is 6000.

Thanks. That answers my question.

Hi,

I have 2 CDS Views; one read aggregation (SUM) in EKBE (Po History) for field DMBTR (CURR13.2)

DMBTR is always positive but SHKZG H or S needs to handle it positive or negative.

For a PO line I want to have the total amount of DMBTR

--> SUM DMBTR S subtracted by SUM DMBTR H into new field.

But the value of the new field is zero even if there is a value in DMBTR S.

Function GET_NUMERIC_VALUE or CURR_TO_DECFLOAT_AMOUNT are not available in Eclipse ("Specified Function xxx is not known as a predefined function")

ABAP Kernel 785 Patch Level 232

SAP_BASIS 756 0001

SAP_ABA 75G 0001

S4CORE 106 0001

How can I add these functions into CDS View? or even get the calculation done?

Best regards,

Thomas

Hi Thomas,

both functions

GET_NUMERIC_VALUEandCURR_TO_DECFLOAT_AMOUNTare available inCDS view entities(DEFINE VIEW ENTITY) as of release 7.83.I suspect your views are classic CDS views (DEFINE VIEW). Please check.

You can migrate your CDS views to CDS view entities as described in the following blog post: A new generation of CDS views: how to migrate your CDS views to CDS view entities | SAP Blogs

If you use CDS view entities and you work on release 7.85, then both functions should be available. If you get an error, it is a bug. Please open an incident on BC-DWB-DIC.

Best regards

Andrea

Hi Andrea,

thanks for the Reply.

Indeed I used the "old" CDS view for this. Now the functions are available.

because of SAP note https://launchpad.support.sap.com/#/notes/3213096 I could not use the CDS directly.

another problem was the association...when one entry is not available ( no H in EKBE ) the calculation also does not calculate 10.000 - 0 ... it just do nothing and set to 0.

I had to add a case line...when H is NULL then S ELSE do H - S (converted with CURR_TO_DECFLOAT_AMOUNT before )

So I think my problem is solved...but handling this in CDS is not very easy. with ABAP SQL it would take 4 lines of code

Thank you very much!

Best regards,

Thomas