<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ABAP for Agents</title>
    <description>The latest articles on DEV Community by ABAP for Agents (@abapforagents).</description>
    <link>https://dev.to/abapforagents</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4210550%2Fab96a2bc-7c52-45c9-88c1-a6b71eac6d53.png</url>
      <title>DEV Community: ABAP for Agents</title>
      <link>https://dev.to/abapforagents</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abapforagents"/>
    <language>en</language>
    <item>
      <title>Column totals in a Fiori Elements List Report with RAP: more than @Aggregation.default</title>
      <dc:creator>ABAP for Agents</dc:creator>
      <pubDate>Tue, 27 Oct 2026 10:14:45 +0000</pubDate>
      <link>https://dev.to/abapforagents/column-totals-in-a-fiori-elements-list-report-with-rap-more-than-aggregationdefault-1252</link>
      <guid>https://dev.to/abapforagents/column-totals-in-a-fiori-elements-list-report-with-rap-more-than-aggregationdefault-1252</guid>
      <description>&lt;p&gt;"How do I show the sum of a column in my Fiori List Report?" comes up again and again in ABAP forums, and the usual first answer is "add &lt;code&gt;@Aggregation.default: #SUM&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;That's only half of the answer. In SAP Fiori elements for OData V4 the total row belongs to one table type, the &lt;strong&gt;analytical table&lt;/strong&gt;. That table needs a service that supports data aggregation, and on ABAP that has its own RAP feature, its own annotation and its own release requirements.&lt;/p&gt;

&lt;p&gt;This post walks through the RAP and CDS side, the Fiori elements side, and a checklist for when the total doesn't appear. Every behaviour described here is taken from SAP's RAP documentation on the SAP Help Portal and the SAP Fiori elements documentation in the SAPUI5 SDK, linked in each section. &lt;strong&gt;The code samples are illustrative and haven't been run on a real system&lt;/strong&gt;, so adapt names and types to your own data model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Fiori elements for OData V4, totals come from the analytical table. Responsive and grid tables don't calculate sums.&lt;/li&gt;
&lt;li&gt;On the RAP side, add &lt;code&gt;@OData.applySupportedForAggregation: #FULL&lt;/code&gt; to the projection view header and &lt;code&gt;@Aggregation.default: #SUM&lt;/code&gt; to each measure in the same projection view.&lt;/li&gt;
&lt;li&gt;SAP documents RAP analytical tables for read-only business objects on a list report page, and on recent releases only (SAP BTP ABAP environment and S/4HANA Cloud from 2511).&lt;/li&gt;
&lt;li&gt;Annotate amounts and quantities with &lt;code&gt;@Semantics.amount.currencyCode&lt;/code&gt; or &lt;code&gt;@Semantics.quantity.unitOfMeasure&lt;/code&gt;. Mixed currencies are totalled per currency in a popup.&lt;/li&gt;
&lt;li&gt;If the sum is missing, check &lt;code&gt;$metadata&lt;/code&gt; for &lt;code&gt;Aggregation.ApplySupported&lt;/code&gt;, the table type in &lt;code&gt;manifest.json&lt;/code&gt;, the &lt;code&gt;total&lt;/code&gt; list in your presentation variant, and the &lt;code&gt;$apply&lt;/code&gt; in the network request.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why the sum doesn't show in a normal List Report
&lt;/h2&gt;

&lt;p&gt;The SAPUI5 documentation for SAP Fiori elements for OData V4 lists four table types: responsive table, grid table, analytical table and tree table. Responsive and analytical tables can group rows, but only the analytical table is described with data aggregation ("automatically calculate sums, averages, and other aggregate functions"), and the &lt;a href="https://ui5.sap.com/#/topic/d344c5aa5c81483482dbbed5b3abb142" rel="noopener noreferrer"&gt;Table Groupings&lt;/a&gt; page says it directly: "For analytical tables, you can also define totals."&lt;/p&gt;

&lt;p&gt;So switching a List Report to &lt;code&gt;GridTable&lt;/code&gt; does not give you a totals row. You need an analytical table, and the analytical table needs an analytical service. According to &lt;a href="https://ui5.sap.com/#/topic/b51afc2c1c9a41bb8ac6055ccce2baab" rel="noopener noreferrer"&gt;Annotating a Service as an Analytical Service&lt;/a&gt;, that means the entity set supports &lt;code&gt;@Aggregation.ApplySupported&lt;/code&gt; and, for ABAP-based services, all of these transformations: &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;identity&lt;/code&gt;, &lt;code&gt;orderby&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;groupby&lt;/code&gt;, &lt;code&gt;concat&lt;/code&gt; and &lt;code&gt;aggregate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In RAP you don't write &lt;code&gt;Aggregation.ApplySupported&lt;/code&gt; yourself. One CDS annotation generates it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your release first
&lt;/h2&gt;

&lt;p&gt;SAP calls this feature &lt;strong&gt;RAP analytical tables&lt;/strong&gt;. The &lt;a href="https://help.sap.com/docs/abap-cloud/abap-rap/rap-analytical-tables" rel="noopener noreferrer"&gt;RAP documentation&lt;/a&gt; describes them as available "in read-only scenarios and on a list report page", modelled on a projection view annotated with &lt;code&gt;@OData.applySupportedForAggregation: #FULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;SAP's &lt;a href="https://github.com/SAP-samples/abap-platform-codejam-latest-features-2602/wiki/Analytical-Table" rel="noopener noreferrer"&gt;ABAP CodeJam material for the feature&lt;/a&gt; lists the availability as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SAP BTP, ABAP environment as of 2511&lt;/li&gt;
&lt;li&gt;SAP S/4HANA Cloud as of 2511&lt;/li&gt;
&lt;li&gt;SAP S/4HANA and SAP S/4HANA Cloud, private edition as of 2027&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the annotation isn't accepted in your system, the release is the first thing to check. An SAP Community thread on exactly this problem was resolved by moving from 2508 to a newer release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: the interface view
&lt;/h2&gt;

&lt;p&gt;Model the measures in the interface (or base) view and give every amount its currency and every quantity its unit. Fiori elements needs that reference to total each currency or unit separately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;AccessControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authorizationCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;NOT_REQUIRED&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;EndUserText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Sales order items (illustrative)'&lt;/span&gt;
&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;ZI_SalesItemTotals&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;zsales_item&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="n"&gt;item_uuid&lt;/span&gt;     &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ItemUUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;sales_order&lt;/span&gt;   &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SalesOrder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;customer&lt;/span&gt;      &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;material&lt;/span&gt;      &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;Material&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Semantics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currencyCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Currency'&lt;/span&gt;
      &lt;span class="n"&gt;net_amount&lt;/span&gt;    &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;NetAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;currency&lt;/span&gt;      &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Semantics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unitOfMeasure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'OrderUnit'&lt;/span&gt;
      &lt;span class="n"&gt;order_qty&lt;/span&gt;     &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;OrderQuantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;order_unit&lt;/span&gt;    &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;OrderUnit&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need two different aggregations of the same field, for example a minimum and a maximum, the documentation's reference scenario selects the field twice under different aliases. Only one aggregate function can be used per element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: the projection view exposed by the service
&lt;/h2&gt;

&lt;p&gt;This is where the aggregation is switched on. Both annotations go on the projection view that the service definition exposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;AccessControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authorizationCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;NOT_REQUIRED&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;EndUserText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Sales item totals (illustrative)'&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allowExtensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;OData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;applySupportedForAggregation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;FULL&lt;/span&gt;
&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;ZC_SalesItemTotals&lt;/span&gt;
  &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;transactional_query&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;projection&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;ZI_SalesItemTotals&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ItemUUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;SalesOrder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;Material&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Aggregation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;
      &lt;span class="n"&gt;NetAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Aggregation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;
      &lt;span class="n"&gt;OrderQuantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;OrderUnit&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then expose it in an OData V4 UI service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;ZUI_SALES_ITEM_TOTALS&lt;/span&gt;
  &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;contracts&lt;/span&gt; &lt;span class="n"&gt;odata_v4_ui&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;expose&lt;/span&gt; &lt;span class="n"&gt;ZC_SalesItemTotals&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SalesItem&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What SAP's &lt;a href="https://help.sap.com/docs/abap-cloud/abap-rap/annotating-aggregate-functions-in-cds" rel="noopener noreferrer"&gt;Annotating Aggregate Functions in CDS&lt;/a&gt; page says about these annotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The supported functions are &lt;code&gt;#SUM&lt;/code&gt;, &lt;code&gt;#MIN&lt;/code&gt;, &lt;code&gt;#MAX&lt;/code&gt;, &lt;code&gt;#AVG&lt;/code&gt; and &lt;code&gt;#COUNT_DISTINCT&lt;/code&gt;. &lt;code&gt;#MIN&lt;/code&gt; and &lt;code&gt;#MAX&lt;/code&gt; also work on dates.&lt;/li&gt;
&lt;li&gt;Only measures can carry an aggregation annotation, and only elements with numerical data types (plus dates for min and max).&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;#SUM&lt;/code&gt;, use a numeric type large enough for the total.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#COUNT_DISTINCT&lt;/code&gt; needs &lt;code&gt;@Aggregation.referenceElement: ['...']&lt;/code&gt;. SAP recommends a dedicated element for it, because a single row always counts as 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elements without &lt;code&gt;@Aggregation.default&lt;/code&gt; become groupable automatically in a service with &lt;code&gt;@OData.applySupportedForAggregation: #FULL&lt;/code&gt;, as the SAPUI5 page &lt;a href="https://ui5.sap.com/#/topic/9062f11fb94f4781a61a7437a70e62fe" rel="noopener noreferrer"&gt;Defining Groupable Properties&lt;/a&gt; notes. You don't annotate dimensions separately.&lt;/p&gt;

&lt;p&gt;The base view in this example has no behavior definition, so the business object is read-only, which is the scenario SAP documents. SAP's &lt;a href="https://help.sap.com/docs/abap-cloud/abap-rap/developing-read-only-rap-analytical-tables" rel="noopener noreferrer"&gt;Developing Read-Only RAP Analytical Tables&lt;/a&gt; follows the same pattern with the &lt;code&gt;/DMO/C_TRAVEL_ANA&lt;/code&gt; reference objects from the ABAP Flight Reference Scenario. The same page notes that CDS entities annotated for RAP analytical tables aren't enabled for extensibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: grouping and the totals list
&lt;/h2&gt;

&lt;p&gt;By default, Fiori elements groups the records by the columns the user sees, because those are the elements in &lt;code&gt;$select&lt;/code&gt;. If you want every row to stay at item level, SAP's documentation suggests requesting the technical key in the presentation variant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;presentationVariant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="n"&gt;requestAtLeast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'ItemUUID'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
                            &lt;span class="n"&gt;visualizations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;AS_LINEITEM&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="n"&gt;annotate&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;ZC_SalesItemTotals&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lineItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="k"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;  &lt;span class="n"&gt;SalesOrder&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lineItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="k"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;  &lt;span class="k"&gt;Customer&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lineItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="k"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;  &lt;span class="n"&gt;NetAmount&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lineItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="k"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;  &lt;span class="n"&gt;OrderQuantity&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The presentation variant also decides which columns get a total. From &lt;a href="https://ui5.sap.com/#/topic/d344c5aa5c81483482dbbed5b3abb142" rel="noopener noreferrer"&gt;Table Groupings&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without a presentation variant, every column with an aggregatable property gets a total.&lt;/li&gt;
&lt;li&gt;With a presentation variant, only the properties in its &lt;code&gt;total&lt;/code&gt; list get a total. If &lt;code&gt;total&lt;/code&gt; is missing, all aggregatable columns get one. If &lt;code&gt;total&lt;/code&gt; is defined but empty, none do.&lt;/li&gt;
&lt;li&gt;The presentation variant must have a &lt;code&gt;visualizations&lt;/code&gt; entry, or it is ignored.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So a presentation variant copied from another app with &lt;code&gt;total: []&lt;/code&gt; silently removes your sums. You can also set default groups and totals explicitly, for example &lt;code&gt;groupBy: [ 'Customer' ], total: [ 'NetAmount' ]&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Currencies and units
&lt;/h2&gt;

&lt;p&gt;Totals across currencies don't make sense, and Fiori elements doesn't add them up. The same Table Groupings page explains that if a group contains several units or currencies, the table shows a &lt;strong&gt;Show Details&lt;/strong&gt; link that opens a popup with the total or subtotal per unit or currency.&lt;/p&gt;

&lt;p&gt;On the model side, the &lt;a href="https://ui5.sap.com/#/topic/7d914317c0b64c23824bf932cc8a4ae1" rel="noopener noreferrer"&gt;OData V4 data aggregation documentation&lt;/a&gt; describes how each aggregatable property can carry its unit or currency, which returns a single value when there's only one, and &lt;code&gt;null&lt;/code&gt; in a "multi-unit situation". In RAP that reference comes from &lt;code&gt;@Semantics.amount.currencyCode&lt;/code&gt; and &lt;code&gt;@Semantics.quantity.unitOfMeasure&lt;/code&gt;. Without it, the framework can't tell 100 EUR from 100 USD.&lt;/p&gt;

&lt;p&gt;If users need one grand total in a single currency, the totals have to be converted in the back end first. SAP Fiori elements also documents analytical parameters for converting to a target currency at runtime, which is beyond the scope of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  The table type in manifest.json
&lt;/h2&gt;

&lt;p&gt;With an analytical service, you usually don't need to configure anything. &lt;a href="https://ui5.sap.com/#/topic/3fd4c37ff7964db9b00f80841f7a7bce" rel="noopener noreferrer"&gt;Determining the Default Table Type&lt;/a&gt; says the List Report defaults to the analytical table when the entity set has &lt;code&gt;Aggregation.ApplySupported&lt;/code&gt; with all the transformations listed above, and to a responsive table otherwise.&lt;/p&gt;

&lt;p&gt;If the app was generated earlier with an explicit table type, it may still say &lt;code&gt;ResponsiveTable&lt;/code&gt; or &lt;code&gt;GridTable&lt;/code&gt;. Set it as described in &lt;a href="https://ui5.sap.com/#/topic/7f844f1021cd4791b8f7408eac7c1cec" rel="noopener noreferrer"&gt;Setting the Table Type&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"SalesItemList"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Component"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sap.fe.templates.ListReport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"controlConfiguration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"@com.sap.vocabularies.UI.v1.LineItem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"tableSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AnalyticalTable"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The documented catch: if you set &lt;code&gt;AnalyticalTable&lt;/code&gt; and the entity set has no analytical capabilities, the result is an &lt;strong&gt;empty table&lt;/strong&gt;. So a List Report that shows no rows right after a table-type change usually means the service side isn't done yet.&lt;/p&gt;

&lt;p&gt;A few documented restrictions of analytical tables that are worth knowing before you promise them to users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The table only displays properties that are groupable or aggregatable. Anything else isn't requested and stays empty.&lt;/li&gt;
&lt;li&gt;Navigation properties aren't supported. A &lt;code&gt;LineItem&lt;/code&gt; column pointing to one stays empty.&lt;/li&gt;
&lt;li&gt;Micro charts, multi-line content such as &lt;code&gt;FieldGroup&lt;/code&gt; columns, and multi-input fields aren't supported.&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;aggregationOnLeafLevel: true&lt;/code&gt;, navigation and bound actions are only enabled when all key properties are visible in the table (&lt;a href="https://ui5.sap.com/#/topic/d230e371357b402fba3c3af8dfd0538e" rel="noopener noreferrer"&gt;Aggregation Based on Visible Properties&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Draft and transactional apps
&lt;/h2&gt;

&lt;p&gt;This is the most common disappointment. RAP's documentation scopes RAP analytical tables to read-only business objects. The SAPUI5 SDK does describe &lt;a href="https://ui5.sap.com/#/topic/8ad8d795e0b14ce79325cc0a4b383dcc" rel="noopener noreferrer"&gt;analytical tables with a draft-enabled service&lt;/a&gt;: only active entities are shown, the Editing Status filter is hidden, and the combination isn't available in the flexible column layout. Those are general Fiori elements rules, though, and they don't change what RAP supports for your ABAP service.&lt;/p&gt;

&lt;p&gt;In practice, if your users need both an editable List Report and totals, plan for a separate read-only projection and service for the analytical list, and keep the transactional app as it is. Check the ABAP platform roadmap and the release notes for your system before you design around anything newer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the service before you blame the UI
&lt;/h2&gt;

&lt;p&gt;Two checks take a few minutes and settle most cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The $metadata document.&lt;/strong&gt; Open the service URL with &lt;code&gt;/$metadata&lt;/code&gt; (from the service binding in ADT, or from the browser's network tab). On the entity set or entity type, look for the &lt;code&gt;Aggregation.ApplySupported&lt;/code&gt; annotation and its &lt;code&gt;Transformations&lt;/code&gt; collection. It should contain all of &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;identity&lt;/code&gt;, &lt;code&gt;orderby&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;groupby&lt;/code&gt;, &lt;code&gt;concat&lt;/code&gt; and &lt;code&gt;aggregate&lt;/code&gt;. If it's missing, &lt;code&gt;@OData.applySupportedForAggregation: #FULL&lt;/code&gt; isn't on the projection view that is actually exposed, or the release doesn't support it. The SAPUI5 SDK's &lt;a href="https://ui5.sap.com/#/topic/564ac6e999a04097b227dd469c4a4d4f" rel="noopener noreferrer"&gt;Defining Aggregatable Properties&lt;/a&gt; shows how an aggregatable property looks in metadata, with &lt;code&gt;Aggregation.CustomAggregate&lt;/code&gt; qualified by the property name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The data request.&lt;/strong&gt; Open the browser's developer tools, go to the Network tab, filter for &lt;code&gt;$batch&lt;/code&gt;, and look at the GET request for your entity set inside the batch. An analytical table doesn't send a plain &lt;code&gt;$select&lt;/code&gt;. The OData V4 model derives a &lt;code&gt;$apply&lt;/code&gt; system query option from the grouping and aggregation, so you should see &lt;code&gt;$apply&lt;/code&gt; with &lt;code&gt;groupby&lt;/code&gt; and &lt;code&gt;aggregate&lt;/code&gt;. If you see a normal &lt;code&gt;$select ... $top&lt;/code&gt; request with no &lt;code&gt;$apply&lt;/code&gt;, the app isn't using the analytical table.&lt;/p&gt;

&lt;h2&gt;
  
  
  OData V2
&lt;/h2&gt;

&lt;p&gt;Most new RAP development uses OData V4 UI services, and the RAP analytical table described above is documented for OData V4. If you maintain a Fiori elements app for OData V2, the logic for the table type is different. According to the V2 page &lt;a href="https://ui5.sap.com/#/topic/5d270547f113468e83e06dd7ee408a45" rel="noopener noreferrer"&gt;Setting the Table Type&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without a configured type, an aggregate-based service gets an analytical table, and any other service gets a responsive table.&lt;/li&gt;
&lt;li&gt;For an analytical table on the List Report, the entity type must have &lt;code&gt;sap:semantics="aggregate"&lt;/code&gt;. That is a back-end setting.&lt;/li&gt;
&lt;li&gt;If you configure &lt;code&gt;AnalyticalTable&lt;/code&gt; and the entity set has no analytical capabilities, the V2 template falls back to a grid table instead of showing an empty table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The RAP documentation has a separate topic on the &lt;a href="https://help.sap.com/docs/abap-cloud/abap-rap/odata-v2-interpretation-of-aggregation-annotations" rel="noopener noreferrer"&gt;OData V2 interpretation of aggregation annotations&lt;/a&gt;. Check it for your release rather than assuming the V4 behaviour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Release.&lt;/strong&gt; Does your system support &lt;code&gt;@OData.applySupportedForAggregation&lt;/code&gt;? On BTP ABAP environment and S/4HANA Cloud it's 2511 or later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right view.&lt;/strong&gt; Are both annotations on the projection view that the service definition exposes, not only on the interface view?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-only.&lt;/strong&gt; Is the business object read-only? RAP analytical tables are documented for that scenario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Numeric measures.&lt;/strong&gt; Is the summed element numeric, with a type big enough for the total?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Currency and unit.&lt;/strong&gt; Do amounts and quantities have &lt;code&gt;@Semantics.amount.currencyCode&lt;/code&gt; or &lt;code&gt;@Semantics.quantity.unitOfMeasure&lt;/code&gt;? Mixed currencies show "Show Details" instead of one total, which is the expected behaviour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$metadata.&lt;/strong&gt; Is &lt;code&gt;Aggregation.ApplySupported&lt;/code&gt; present with all eight transformations?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table type.&lt;/strong&gt; Is &lt;code&gt;manifest.json&lt;/code&gt; forcing &lt;code&gt;ResponsiveTable&lt;/code&gt; or &lt;code&gt;GridTable&lt;/code&gt;? Remove the setting or set &lt;code&gt;AnalyticalTable&lt;/code&gt;. An empty table after this change points back to the service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentation variant.&lt;/strong&gt; Is there a &lt;code&gt;total: []&lt;/code&gt;, or a presentation variant without &lt;code&gt;visualizations&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network.&lt;/strong&gt; Does the list request contain &lt;code&gt;$apply&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Columns.&lt;/strong&gt; Are the columns groupable or aggregatable properties, not navigation properties?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why AI assistants get this wrong
&lt;/h2&gt;

&lt;p&gt;Ask a general-purpose AI assistant how to sum a column in a Fiori List Report and you'll often get &lt;code&gt;@Aggregation.default: #SUM&lt;/code&gt; on its own, &lt;code&gt;@DefaultAggregation&lt;/code&gt; from older analytical CDS views, or advice to switch to a grid table. None of these produces a totals row in an OData V4 RAP app by itself. The feature is new, depends on the release, and is spread across the RAP documentation and the SAPUI5 SDK, so it's thin in the code that models learn from.&lt;/p&gt;

&lt;p&gt;The fix is the same as for other ABAP topics: tell the assistant your release and your OData version, and keep the rule where it reads it on every request, for example "Totals in a Fiori elements V4 List Report need a read-only RAP analytical table: &lt;code&gt;@OData.applySupportedForAggregation: #FULL&lt;/code&gt; on the exposed projection view, plus &lt;code&gt;@Aggregation.default&lt;/code&gt; on the measures." For more patterns like this one, see &lt;a href="https://abapforagents.com/guides/ai-abap-mistakes/" rel="noopener noreferrer"&gt;ABAP mistakes AI coding assistants make&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Free MIT-licensed ABAP rules for Cursor, Claude Code and Copilot are on &lt;a href="https://github.com/abapforagents/abap-for-agents-lite" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and there are more guides at &lt;a href="https://abapforagents.com/guides/" rel="noopener noreferrer"&gt;abapforagents.com/guides&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>abap</category>
      <category>sap</category>
      <category>fiori</category>
      <category>odata</category>
    </item>
    <item>
      <title>9 ABAP mistakes AI coding assistants keep making (and how to prevent them)</title>
      <dc:creator>ABAP for Agents</dc:creator>
      <pubDate>Tue, 27 Oct 2026 10:14:31 +0000</pubDate>
      <link>https://dev.to/abapforagents/9-abap-mistakes-ai-coding-assistants-keep-making-and-how-to-prevent-them-35nm</link>
      <guid>https://dev.to/abapforagents/9-abap-mistakes-ai-coding-assistants-keep-making-and-how-to-prevent-them-35nm</guid>
      <description>&lt;p&gt;AI coding assistants are great at languages with millions of public examples. ABAP isn't one of them, and it trips them up in two specific ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The language changes a lot between releases.&lt;/strong&gt; Code that activates on S/4HANA 2023 can be a syntax error on an ECC system running SAP_BASIS 7.50.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most of what you call lives inside SAP systems, not on GitHub.&lt;/strong&gt; Function modules, BAPIs, CDS views and tables aren't public, so the model can't check whether they exist. It guesses, and the guesses look convincing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is a small set of mistakes that come back again and again, whether you use Cursor, Claude Code or GitHub Copilot. Here are nine of them, with the fix for each.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tell the assistant your language version, product and SAP_BASIS release first. Most wrong ABAP is valid syntax from a different release.&lt;/li&gt;
&lt;li&gt;Guard every &lt;code&gt;FOR ALL ENTRIES&lt;/code&gt; with &lt;code&gt;IF itab IS NOT INITIAL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Plausible names prove nothing. Verify every SAP object the assistant uses.&lt;/li&gt;
&lt;li&gt;Table expressions don't set &lt;code&gt;sy-subrc&lt;/code&gt;, BAPIs report errors in &lt;code&gt;RETURN&lt;/code&gt;, and RAP owns the LUW.&lt;/li&gt;
&lt;li&gt;Put these points in a short rules file and keep ATC and ABAP Unit as the real gate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Syntax from the wrong release
&lt;/h2&gt;

&lt;p&gt;The assistant doesn't know which system you're on, so it writes the newest syntax it has seen. Some availability dates worth knowing (from SAP's ABAP Keyword Documentation release notes):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Available from&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Inline declarations &lt;code&gt;DATA(...)&lt;/code&gt;, &lt;code&gt;NEW&lt;/code&gt;, &lt;code&gt;VALUE&lt;/code&gt;, table expressions&lt;/td&gt;
&lt;td&gt;7.40 SP02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ABAP SQL &lt;code&gt;@&lt;/code&gt; host variables, comma-separated lists (strict mode)&lt;/td&gt;
&lt;td&gt;7.40 SP05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inline target &lt;code&gt;INTO TABLE @DATA(...)&lt;/code&gt; in ABAP SQL&lt;/td&gt;
&lt;td&gt;7.40 SP08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;xsdbool( )&lt;/code&gt;, &lt;code&gt;REDUCE&lt;/code&gt;, &lt;code&gt;FILTER&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;7.40 SP08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RAISE EXCEPTION NEW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calculation assignments &lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;-=&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;7.54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDS view entities &lt;code&gt;define view entity&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;7.55&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;ECC 6.0 runs on SAP_BASIS 7.50 at most (EHP8), so &lt;code&gt;x += 1.&lt;/code&gt; won't compile there, and neither will a view entity. On 7.40 SP05 to SP07, this is a syntax error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vbeln&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vbak&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;date_from&lt;/span&gt;
  &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;   &lt;span class="c1"&gt;" needs 7.40 SP08&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SP05-safe version declares the target first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;ty_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;vbeln&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="n"&gt;vbak&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vbeln&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="n"&gt;vbak&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;erdat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;ty_order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;DATA&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="k"&gt;STANDARD&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;ty_order&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;EMPTY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vbeln&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vbak&lt;/span&gt;
  &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;date_from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prevention:&lt;/strong&gt; give the assistant three facts before it writes a line: language version (ABAP for Cloud Development or Standard ABAP), product (S/4HANA or ECC) and release. If you can't, tell it to assume the lowest plausible release and never mix syntax from different releases in one answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. FOR ALL ENTRIES on an empty table
&lt;/h2&gt;

&lt;p&gt;This one activates fine and passes a quick test, which is why it's dangerous. If the internal table after &lt;code&gt;FOR ALL ENTRIES IN&lt;/code&gt; is empty, the whole &lt;code&gt;WHERE&lt;/code&gt; clause is ignored and every row of the database table is read.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;keys&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;INITIAL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vbeln&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;erdat&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vbak&lt;/span&gt;
    &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;ENTRIES&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;keys&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;vbeln&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vbeln&lt;/span&gt;
    &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="k"&gt;ENDIF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;FOR ALL ENTRIES&lt;/code&gt; also removes duplicate result rows, so select all key fields or you lose data silently. There's a full walkthrough in &lt;a href="https://abapforagents.com/guides/for-all-entries-empty-table/" rel="noopener noreferrer"&gt;FOR ALL ENTRIES with an empty table&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Invented function modules, BAPIs and CDS views
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Z_GET_ORDER_STATUS&lt;/code&gt;, &lt;code&gt;I_SomethingView&lt;/code&gt;, &lt;code&gt;BAPI_WHATEVER&lt;/code&gt;: invented names follow SAP's naming conventions, so they read as real. A model will also invent parameter names for function modules that do exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prevention:&lt;/strong&gt; require the assistant to name every SAP object it relies on and to flag the ones it isn't sure about. Then check them yourself: "Open ABAP Development Object" in ADT, SE37/SE24/SE11 in SAP GUI, or SAP's Cloudification Repository for the release state. In ABAP Cloud only released objects are allowed, and an &lt;code&gt;I_&lt;/code&gt; prefix is not proof of either existence or release.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Checking sy-subrc after a table expression
&lt;/h2&gt;

&lt;p&gt;Models trained on classic &lt;code&gt;READ TABLE&lt;/code&gt; code write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="k"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="p"&gt;].&lt;/span&gt;
&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;subrc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;       &lt;span class="c1"&gt;" never reached on a miss&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;ENDIF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A table expression doesn't set &lt;code&gt;sy-subrc&lt;/code&gt;. If the line isn't found it raises &lt;code&gt;CX_SY_ITAB_LINE_NOT_FOUND&lt;/code&gt;, and without a &lt;code&gt;TRY&lt;/code&gt; block the program dumps. Use one of these instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="nb"&gt;line_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="k"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;ENDIF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="c1"&gt;" 7.40 SP08+: initial value instead of an exception&lt;/span&gt;
&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;VALUE&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="k"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;OPTIONAL&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The exception: &lt;code&gt;ASSIGN items[ id = key ] TO &amp;lt;item&amp;gt;.&lt;/code&gt; does set &lt;code&gt;sy-subrc&lt;/code&gt; and raises nothing.)&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Java, C# and JavaScript habits
&lt;/h2&gt;

&lt;p&gt;ABAP looks enough like other languages for the model to slip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kt"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;          &lt;span class="c1"&gt;" wrong: ABAP uses &amp;lt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;                &lt;span class="c1"&gt;" wrong: no ++ operator&lt;/span&gt;
&lt;span class="kt"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;"text".         " wrong: " starts a comment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The correct forms are &lt;code&gt;IF a &amp;lt;&amp;gt; b.&lt;/code&gt;, &lt;code&gt;i = i + 1.&lt;/code&gt; (or &lt;code&gt;i += 1.&lt;/code&gt; from 7.54) and &lt;code&gt;s = `text`.&lt;/code&gt; with backquotes or single quotes. There is no &lt;code&gt;null&lt;/code&gt; either: use &lt;code&gt;IS INITIAL&lt;/code&gt; or &lt;code&gt;IS NOT BOUND&lt;/code&gt;. And &lt;code&gt;RETURN value.&lt;/code&gt; only exists in functional methods from 7.58 (ABAP Cloud 2211); below that, assign the returning parameter and then &lt;code&gt;RETURN.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. boolc( ) instead of xsdbool( )
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;boolc( )&lt;/code&gt; returns a &lt;code&gt;string&lt;/code&gt;, not &lt;code&gt;abap_bool&lt;/code&gt;, which can surprise you in comparisons. &lt;code&gt;xsdbool( )&lt;/code&gt; returns type &lt;code&gt;c&lt;/code&gt; length 1 and works with &lt;code&gt;abap_true&lt;/code&gt; / &lt;code&gt;abap_false&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_late&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;xsdbool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;due_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;is_late&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abap_true&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;ENDIF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Classic ABAP inside ABAP Cloud
&lt;/h2&gt;

&lt;p&gt;In ABAP for Cloud Development, &lt;code&gt;sy-datum&lt;/code&gt;, &lt;code&gt;WRITE&lt;/code&gt;, &lt;code&gt;SUBMIT&lt;/code&gt;, &lt;code&gt;CALL TRANSACTION&lt;/code&gt;, direct reads of SAP tables like &lt;code&gt;VBAK&lt;/code&gt; and non-released function modules are not allowed. Assistants reach for them first because that's what most public ABAP looks like. For the date, use the released class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cl_abap_context_info&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get_system_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;   &lt;span class="c1"&gt;" UTC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That returns the system date in UTC. For the user's local date, SAP points to the XCO library with the user time zone.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. COMMIT WORK inside a RAP handler
&lt;/h2&gt;

&lt;p&gt;In the ABAP RESTful Application Programming Model (RAP), the framework owns the logical unit of work. &lt;code&gt;COMMIT WORK&lt;/code&gt;, &lt;code&gt;ROLLBACK WORK&lt;/code&gt;, &lt;code&gt;COMMIT ENTITIES&lt;/code&gt; and &lt;code&gt;ROLLBACK ENTITIES&lt;/code&gt; don't belong in behavior handler or saver methods. Errors go back through the &lt;code&gt;failed&lt;/code&gt; and &lt;code&gt;reported&lt;/code&gt; structures, not through &lt;code&gt;MESSAGE&lt;/code&gt; or exceptions. Many classic BAPIs commit internally, so they must not be called in the interaction phase either.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Ignoring the BAPI RETURN table
&lt;/h2&gt;

&lt;p&gt;BAPIs don't raise exceptions or set &lt;code&gt;sy-subrc&lt;/code&gt; for business errors. They fill a &lt;code&gt;RETURN&lt;/code&gt; table, so read it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="k"&gt;STANDARD&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;bapiret2&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;EMPTY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;" ... call the BAPI, passing return ...&lt;/span&gt;
&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="nb"&gt;line_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'E'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="nb"&gt;line_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'A'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;
  &lt;span class="c1"&gt;" handle the error, do not commit&lt;/span&gt;
&lt;span class="k"&gt;ENDIF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit separately with &lt;code&gt;BAPI_TRANSACTION_COMMIT&lt;/code&gt;, and not once per record inside a loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to stop repeating these corrections
&lt;/h2&gt;

&lt;p&gt;You can paste these reminders into every prompt, but it's easier to put them in the file your tool reads automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor:&lt;/strong&gt; project rules in &lt;code&gt;.cursor/rules/*.mdc&lt;/code&gt; (&lt;a href="https://abapforagents.com/guides/cursor-rules-sap-abap/" rel="noopener noreferrer"&gt;setup guide&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code, Codex and other agents:&lt;/strong&gt; &lt;code&gt;AGENTS.md&lt;/code&gt;, imported from &lt;code&gt;CLAUDE.md&lt;/code&gt; (&lt;a href="https://abapforagents.com/guides/claude-code-agents-md-abap/" rel="noopener noreferrer"&gt;guide&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot:&lt;/strong&gt; &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; plus path-specific instructions (&lt;a href="https://abapforagents.com/guides/github-copilot-instructions-abap/" rel="noopener noreferrer"&gt;guide&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep these files short. Every always-on line costs context, and long instruction files are followed less reliably. A good rules file states the target release, forbids invented objects, lists the traps above and ends with a self-check the assistant runs before answering.&lt;/p&gt;

&lt;p&gt;Rules are guidance, not enforcement. The assistant can still ignore them, so keep the syntax check, ATC and ABAP Unit as your gate, and run them on everything AI-generated before it reaches a transport.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Free MIT-licensed ABAP rules for Cursor, Claude Code and Copilot are on &lt;a href="https://github.com/abapforagents/abap-for-agents-lite" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and there are more guides at &lt;a href="https://abapforagents.com/guides/" rel="noopener noreferrer"&gt;abapforagents.com/guides&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>abap</category>
      <category>sap</category>
      <category>ai</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
