Skip to content

ABAP Cloud Certification Practice — Worked Solutions ​

System-Based Assessment — C_ABAPD-style practice (2601)

Spoiler — solutions

Complete the practice assessment before consulting this page. This is an independently developed reference solution, not SAP's official grading key or a copy of the certification solution. The implementation has not been activated in a live BTP trial tenant; validate the examples in your own ABAP system.

How to use these solutions ​

Use your two uppercase initials followed by a two-digit attempt number. For example, a student with initials H.P. uses HP01 on the first attempt and HP02 on the second. In all object names and ABAP source below, replace #### with that four-character ID.

Reference nameFirst attempt for H.P.
ZABAP_####ZABAP_HP01
ZCL_####_FLIGHTZCL_HP01_FLIGHT
ZCL_####_PASSENGER_FLIGHTZCL_HP01_PASSENGER_FLIGHT
ZZ####TRAVELZZHP01TRAVEL
Z####_AGENCYZHP01_AGENCY
Z####_CUSTOMERZHP01_CUSTOMER

Reading the source

Each ABAP class or CDS object shown in a separate code block is a separate repository object. Do not paste several global classes into one ADT class. Repository object names are case-insensitive in ABAP source but must be named correctly in ADT. The #### token is a teaching placeholder, not valid ABAP syntax until replaced.

Task 1: Context — Solution ​

The context task requires configuration, not ABAP source.

  1. Create an ABAP Cloud Project in Eclipse/ADT for your BTP trial ABAP instance.
  2. Locate the existing /DMO/CONNECTION, /DMO/FLIGHT, /DMO/AGENCY, and /DMO/CUSTOMER tables; these are part of the ABAP Flight Reference Scenario.
  3. Verify that the supplied practice fixture objects from the preparation section are available.
  4. Record your four-character ID and use it consistently, without the example value HP01 unless it is actually yours.

The trial does not provide the exam-specific access URL, examination group number, or grading/submission process.

Task 2: Create a Package — Solution ​

In ADT, create an ABAP Package with these properties:

PropertyValue
NameZABAP_####
DescriptionABAP Cloud certification practice
SuperpackageZLOCAL
Transport requestThe request offered or created by your trial system

Use this package for Tasks 3–8. There is no equivalent ABAP source statement to create the package as part of an ordinary ABAP class.

Task 3: Create a Class Hierarchy — Solution ​

Prerequisites: ZCX_C_ABAPD_NO_CONNECTION (global exception class) and ZI_CABAPD_PASSENGER (CDS view entity) from the practice-system preparation. The /DMO/* tables themselves already exist; do not copy or recreate them.

3.1 Global class ZCL_####_FLIGHT ​

Create a global class named ZCL_####_FLIGHT. Use the entire class source:

abap
CLASS zcl_####_flight DEFINITION
  PUBLIC
  CREATE PUBLIC.

  PUBLIC SECTION.
    DATA carrier_id    TYPE /dmo/carrier_id       READ-ONLY.
    DATA connection_id TYPE /dmo/connection_id    READ-ONLY.
    DATA airport_from  TYPE /dmo/airport_from_id  READ-ONLY.
    DATA airport_to    TYPE /dmo/airport_to_id    READ-ONLY.

    METHODS constructor
      IMPORTING
        i_carrier_id    TYPE /dmo/carrier_id
        i_connection_id TYPE /dmo/connection_id
        i_plane_type    TYPE /dmo/plane_type_id
      RAISING
        zcx_c_abapd_no_connection.

  PROTECTED SECTION.
    DATA plane_type TYPE /dmo/plane_type_id.

ENDCLASS.

CLASS zcl_####_flight IMPLEMENTATION.
  METHOD constructor.
    me->carrier_id    = i_carrier_id.
    me->connection_id = i_connection_id.
    me->plane_type    = i_plane_type.

    SELECT SINGLE FROM /dmo/connection
      FIELDS airport_from_id, airport_to_id
      WHERE carrier_id    = @i_carrier_id
        AND connection_id = @i_connection_id
      INTO ( @me->airport_from, @me->airport_to ).

    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_c_abapd_no_connection.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Why this meets the task: READ-ONLY makes the four public attributes readable but not externally writable. plane_type is protected, allowing direct access from subclasses. The constructor retrieves airports from the real /DMO/CONNECTION table and raises the supplied checked exception for a missing connection.

3.2 Global class ZCL_####_PASSENGER_FLIGHT ​

Create a second global class named ZCL_####_PASSENGER_FLIGHT:

abap
CLASS zcl_####_passenger_flight DEFINITION
  PUBLIC
  INHERITING FROM zcl_####_flight
  CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        i_carrier_id    TYPE /dmo/carrier_id
        i_connection_id TYPE /dmo/connection_id
        i_plane_type    TYPE /dmo/plane_type_id
      RAISING
        zcx_c_abapd_no_connection.

  PRIVATE SECTION.
    DATA seats_max TYPE /dmo/plane_seats_max.

ENDCLASS.

CLASS zcl_####_passenger_flight IMPLEMENTATION.
  METHOD constructor.
    super->constructor(
      i_carrier_id    = i_carrier_id
      i_connection_id = i_connection_id
      i_plane_type    = i_plane_type ).

    SELECT SINGLE FROM zi_cabapd_passenger
      FIELDS MaximumSeats
      WHERE PlaneType = @i_plane_type
      INTO @me->seats_max.

    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_c_abapd_no_connection.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

The subclass calls its superclass constructor first, then reads the prepared view using the plane type supplied to the constructor. The attribute seats_max remains private, as requested.

Important difference from the dedicated assessment

ZI_CABAPD_PASSENGER is not supplied by the BTP trial by default. In this independent practice, the setup view derives MaximumSeats from /DMO/FLIGHT. Its PlaneType/MaximumSeats field aliases must match the source above. A plane type without a row in the setup view raises the practice exception.

3.3 Optional executable check ​

This separate console class checks a real connection and a real plane type, rather than assuming the example carrier/connection IDs are present in every trial tenant:

abap
CLASS zcl_####_test_flight DEFINITION
  PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
ENDCLASS.

CLASS zcl_####_test_flight IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    SELECT SINGLE FROM /dmo/connection
      FIELDS carrier_id, connection_id
      INTO @DATA(connection).

    SELECT SINGLE FROM zi_cabapd_passenger
      FIELDS PlaneType
      INTO @DATA(plane_type).

    IF connection IS INITIAL OR plane_type IS INITIAL.
      out->write( 'Fixture data missing; check the setup view.' ).
      RETURN.
    ENDIF.

    TRY.
        DATA(flight) = NEW zcl_####_passenger_flight(
          i_carrier_id    = connection-carrier_id
          i_connection_id = connection-connection_id
          i_plane_type    = plane_type ).
        out->write( |From: { flight->airport_from }| ).
        out->write( |To:   { flight->airport_to }| ).
      CATCH zcx_c_abapd_no_connection.
        out->write( 'Unexpected connection / plane type error.' ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

Task 4: Read a List of Flight Connections — Solution ​

Prerequisite: The practice starter DDIC table type ZCERT_CONNECTIONS, whose row type is the structure ZCERT_CONNECTION with fields carrier_id, airport_from_id, airport_to_id, and airport_via_id.

Create global class ZCL_####_CONNECTIONS:

abap
CLASS zcl_####_connections DEFINITION
  PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS get_connections
      IMPORTING
        i_departure TYPE /dmo/airport_from_id
      RETURNING
        VALUE(r_connections) TYPE zcert_connections.
ENDCLASS.

CLASS zcl_####_connections IMPLEMENTATION.
  METHOD get_connections.

    "1. Every direct connection leaving the requested airport.
    SELECT DISTINCT FROM /dmo/connection
      FIELDS carrier_id, airport_from_id, airport_to_id
      WHERE airport_from_id = @i_departure
        AND airport_to_id   <> @i_departure
      INTO TABLE @DATA(direct_connections).

    LOOP AT direct_connections INTO DATA(direct_connection).
      APPEND VALUE #(
        carrier_id      = direct_connection-carrier_id
        airport_from_id = direct_connection-airport_from_id
        airport_to_id   = direct_connection-airport_to_id
        airport_via_id  = '-' ) TO r_connections.
    ENDLOOP.

    "2. Two legs with the same airline and matching transfer airport.
    SELECT DISTINCT FROM /dmo/connection AS first_leg
      INNER JOIN /dmo/connection AS second_leg
        ON  first_leg~carrier_id     = second_leg~carrier_id
        AND first_leg~airport_to_id = second_leg~airport_from_id
      FIELDS
        first_leg~carrier_id      AS carrier_id,
        first_leg~airport_from_id AS airport_from_id,
        second_leg~airport_to_id  AS airport_to_id,
        first_leg~airport_to_id   AS airport_via_id
      WHERE first_leg~airport_from_id = @i_departure
        AND second_leg~airport_to_id  <> @i_departure
      INTO TABLE @DATA(one_change_connections).

    LOOP AT one_change_connections INTO DATA(one_change_connection).
      APPEND VALUE #(
        carrier_id      = one_change_connection-carrier_id
        airport_from_id = one_change_connection-airport_from_id
        airport_to_id   = one_change_connection-airport_to_id
        airport_via_id  = one_change_connection-airport_via_id
      ) TO r_connections.
    ENDLOOP.

  ENDMETHOD.
ENDCLASS.

DISTINCT avoids returning exactly identical result rows when several underlying connection IDs represent the same logical itinerary. It does not discard valid alternative routes through different transfer airports. There is deliberately no ORDER BY requirement in the assessment.

4.1 Optional executable check ​

abap
CLASS zcl_####_test_connections DEFINITION
  PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
ENDCLASS.

CLASS zcl_####_test_connections IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA(reader) = NEW zcl_####_connections( ).
    DATA(result) = reader->get_connections( i_departure = 'EDI' ).

    LOOP AT result INTO DATA(connection).
      out->write(
        |{ connection-carrier_id } | &&
        |{ connection-airport_from_id } -> | &&
        |{ connection-airport_to_id } | &&
        |via { connection-airport_via_id }| ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

Check the actual result against /DMO/CONNECTION. The example rows in the assessment are illustrative and need not all be present in the trial tenant.

Task 5: Create a RAP Business Object — Solution ​

Starting point: Copy the supplied practice table ZABAPDTRAVEL to ZZ####TRAVEL, activate it, and run Generate ABAP Repository Objects → ABAP RESTful Application Programming Model: UI Service. Accept the wizard's naming proposals exactly as instructed in the exercise.

Generated objects are version-dependent

The generator creates the CDS root view, behavior definition, behavior pool, projection, service definition, service binding, and (in some workflows) draft artifacts. Do not overwrite generated artifacts with guessed class, alias, or draft-table names. The complete source below is a reference implementation for an illustrative, non-draft managed BO using the prepared practice table. For the actual exercise, keep the wizard-generated full definitions and apply the same field / determination lines and complete handler method. This distinction is necessary because the generated artifacts cannot be predicted from the task sheet alone.

5.1 Example CDS root view for reference ​

A complete, minimal CDS root view for the prepared table would be:

abap
@EndUserText.label: 'Practice travel root entity'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define root view entity ZR_Z####TRAVEL
  as select from zz####travel
{
  key travel_uuid          as TravelUUID,
      travel_id            as TravelID,
      agency_id            as AgencyID,
      customer_id          as CustomerID,
      begin_date           as BeginDate,
      end_date             as EndDate,
      status               as Status,
      local_created_by     as LocalCreatedBy,
      local_created_at     as LocalCreatedAt,
      local_last_changed_by as LocalLastChangedBy,
      local_last_changed_at as LocalLastChangedAt,
      last_changed_at      as LastChangedAt
}

Use the CDS view generated in your own system. In particular, confirm that its field really is named Status and that it maps to status in ZZ####TRAVEL.

5.2 Behavior definition ​

This is a complete non-draft reference behavior definition for the view in section 5.1. It demonstrates exactly where the two assessment-required statements belong:

abap
managed implementation in class zbp_r_z####travel unique;
strict ( 2 );

define behavior for ZR_Z####TRAVEL alias Travel
  persistent table zz####travel
  lock master
  etag master LocalLastChangedAt
{
  create;
  update;
  delete;

  field ( numbering : managed, readonly ) TravelUUID;
  field ( readonly ) Status;
  field ( readonly ) LocalCreatedBy, LocalCreatedAt,
                     LocalLastChangedBy, LocalLastChangedAt,
                     LastChangedAt;

  determination setInitialStatus on save { create; }

  mapping for zz####travel
  {
    TravelUUID        = travel_uuid;
    TravelID          = travel_id;
    AgencyID          = agency_id;
    CustomerID        = customer_id;
    BeginDate         = begin_date;
    EndDate           = end_date;
    Status            = status;
    LocalCreatedBy    = local_created_by;
    LocalCreatedAt    = local_created_at;
    LocalLastChangedBy = local_last_changed_by;
    LocalLastChangedAt = local_last_changed_at;
    LastChangedAt     = last_changed_at;
  }
}

For the wizard-generated behavior definition, retain its existing lines, including draft handling, field controls, mappings, and generated names. Ensure these lines appear in the root entity's behavior block:

abap
field ( readonly ) Status;
determination setInitialStatus on save { create; }

If Status already appears in a field-control statement, adjust that statement instead of declaring contradictory controls.

5.3 Complete determination handler method ​

In the wizard-generated behavior pool, use Ctrl+1 → Add method for determination on setInitialStatus. For a root entity with alias Travel, ADT will create a local handler method declaration like this:

abap
CLASS lhc_Travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    METHODS setInitialStatus FOR DETERMINE ON SAVE
      IMPORTING keys FOR Travel~setInitialStatus.
ENDCLASS.

In the matching local handler implementation, replace the empty method with the following complete implementation:

abap
CLASS lhc_Travel IMPLEMENTATION.
  METHOD setInitialStatus.
    READ ENTITIES OF ZR_Z####TRAVEL IN LOCAL MODE
      ENTITY Travel
        FIELDS ( Status )
        WITH CORRESPONDING #( keys )
      RESULT DATA(travels).

    "Do not overwrite a value on an already initialized instance.
    DELETE travels WHERE Status IS NOT INITIAL.
    CHECK travels IS NOT INITIAL.

    MODIFY ENTITIES OF ZR_Z####TRAVEL IN LOCAL MODE
      ENTITY Travel
        UPDATE FIELDS ( Status )
        WITH VALUE #(
          FOR travel IN travels
            ( %tky   = travel-%tky
              Status = 'N' ) )
      REPORTED DATA(update_reported).

    reported = CORRESPONDING #( DEEP update_reported ).
  ENDMETHOD.
ENDCLASS.

Handler class naming

The generated local class might be named lhc_Travel, lhc_<entity>, or something similar. Keep the class name and the FOR Travel~setInitialStatus alias generated by ADT; copy the method body into the generated method. Similarly, replace ZR_Z####TRAVEL in the two EML statements only if the actual wizard-generated interface/root behavior entity has a different name. The method uses IN LOCAL MODE because the determination needs to update a field marked read-only for ordinary consumers.

Expected behavior: Status is read-only to service consumers and is set to N when a newly created record is saved. The determination only has the create trigger; updating an existing record does not execute it for that reason. Test with the generated OData V4 UI service binding Preview.

Check the starter table's status type

The prepared table in the practice page uses /DMO/OVERALL_STATUS. Its predefined domain values may not include N. Check the domain and UI validation. If N is not allowed, the instructor should change the practice starter table status to a compatible one-character type (for example abap.char(1)) before students copy it, rather than changing the task's required literal N.

Task 6: Create a CDS Access Control — Solution ​

Copy the prepared ZC_ABAPD_AGENCY to the CDS view entity Z####_AGENCY. The content of the copied view can be:

abap
@EndUserText.label: 'Practice agency data'
@AccessControl.authorizationCheck: #CHECK
define view entity Z####_AGENCY
  as select from /dmo/agency
{
  key agency_id    as agency_id,
      name         as name,
      street       as street,
      postal_code  as postal_code,
      city         as city,
      country_code as country_code
}

6.1 Complete DCL source ​

Create a CDS Access Control named Z####_AGENCY and use:

abap
@EndUserText.label: 'Display authorization for practice agencies'
@MappingRole: true
define role Z####_AGENCY {
  grant select on Z####_AGENCY
    where ( agency_id ) =
      aspect pfcg_auth(
        ZAGC####,
        ZAGF####,
        ACTVT = '03'
      );
}

This maps the CDS element agency_id to the practice authorization field ZAGF#### within authorization object ZAGC####, and requires Display activity 03. The assessment-only /LRN/AGCY object is not guaranteed to be present in trial, so the practice uses its own preparation objects.

6.2 Authorization setup (where supported) ​

ItemExpected configuration
Authorization objectZAGC####
Agency authorization fieldZAGF####, with type corresponding to /DMO/AGENCY_ID
Activity fieldACTVT
Allowed activity03 (Display)
CDS element to protectagency_id
Authorization valuesOne or more real agency IDs from /DMO/AGENCY

The PFCG syntax is complete, but it will only activate if the relevant custom authorization object and field exist and are supported in the ABAP system. Effective filtering also requires user-role/IAM authorization assignments. Do not present activation alone as a successful authorization test. Some BTP trial accounts may not permit the end-to-end setup; record that as a limitation of the trial rather than replacing the PFCG aspect with a hard-coded filter.

Task 7: Add Exception Handling to a Method — Solution ​

Prerequisites: Practice message class ZC_ABAPD, message 002 with text Travel agency &1 could not be found., and the supplied starter class ZCL_AGENCY_MODEL.

7.1 Complete exception class ZCX_####_NO_AGENCY ​

Create a global class inheriting from CX_STATIC_CHECK. The following constructor stores the missing agency ID and selects the exception text defined by the message class. A global exception class created in ADT already inherits the necessary message interfaces from the exception base class.

abap
CLASS zcx_####_no_agency DEFINITION
  PUBLIC
  INHERITING FROM cx_static_check
  CREATE PUBLIC.

  PUBLIC SECTION.
    CONSTANTS:
      BEGIN OF agency_not_found,
        msgid TYPE symsgid VALUE 'ZC_ABAPD',
        msgno TYPE symsgno VALUE '002',
        attr1 TYPE scx_attrname VALUE 'AGENCY_ID',
        attr2 TYPE scx_attrname VALUE '',
        attr3 TYPE scx_attrname VALUE '',
        attr4 TYPE scx_attrname VALUE '',
      END OF agency_not_found.

    DATA agency_id TYPE /dmo/agency_id READ-ONLY.

    METHODS constructor
      IMPORTING
        textid    LIKE if_t100_message=>t100key OPTIONAL
        previous  LIKE previous OPTIONAL
        agency_id TYPE /dmo/agency_id OPTIONAL.
ENDCLASS.

CLASS zcx_####_no_agency IMPLEMENTATION.
  METHOD constructor.
    super->constructor( previous = previous ).
    me->agency_id = agency_id.

    CLEAR me->textid.
    IF textid IS INITIAL.
      if_t100_message~t100key = agency_not_found.
    ELSE.
      if_t100_message~t100key = textid.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Why attr1 matters: The T100 message placeholder &1 is bound to the exception object's public attribute AGENCY_ID, so the thrown exception carries the missing agency ID into its rendered message.

7.2 Complete copied class ZCL_####_AGENCY_MODEL ​

Create a copy of ZCL_AGENCY_MODEL and use this complete implementation:

abap
CLASS zcl_####_agency_model DEFINITION
  PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS get_agency
      IMPORTING
        i_agency_id TYPE /dmo/agency_id
      RETURNING
        VALUE(r_agency) TYPE /dmo/agency
      RAISING
        zcx_####_no_agency.
ENDCLASS.

CLASS zcl_####_agency_model IMPLEMENTATION.
  METHOD get_agency.
    SELECT SINGLE FROM /dmo/agency
      FIELDS *
      WHERE agency_id = @i_agency_id
      INTO @r_agency.

    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE zcx_####_no_agency
        EXPORTING
          agency_id = i_agency_id.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

7.3 Optional executable check ​

abap
CLASS zcl_####_test_agency DEFINITION
  PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
ENDCLASS.

CLASS zcl_####_test_agency IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA(model) = NEW zcl_####_agency_model( ).

    TRY.
        DATA(agency) = model->get_agency( i_agency_id = 'ZZZZZZ' ).
        out->write( agency-agency_id ).
      CATCH zcx_####_no_agency INTO DATA(error).
        out->write( error->get_text( ) ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

Choose a nonexistent agency ID appropriate to your data element's actual length. The example ZZZZZZ is only a deliberately unlikely test value; to prove the missing-record branch, verify it is absent from /DMO/AGENCY first.

Task 8: Create ABAP Dictionary Types — Solution ​

8.1 Complete structure definition Z####_CUSTOMER ​

Create an ABAP Dictionary → Structure repository object named Z####_CUSTOMER. In its source editor, use:

abap
@EndUserText.label: 'Practice customer structure'
@AbapCatalog.enhancement.category: #EXTENSIBLE_CHARACTER_NUMERIC
define structure Z####_CUSTOMER {
  customer_id  : /dmo/customer_id;
  first_name   : /dmo/first_name;
  last_name    : /dmo/last_name;
  street       : /dmo/street;
  postal_code  : /dmo/postal_code;
  city         : /dmo/city;
  country_code : land1;
}

Notice country_code : land1: use the same data element as /DMO/CUSTOMER-COUNTRY_CODE, rather than guessing a /DMO/* type from the field name. Inspect /DMO/CUSTOMER in ADT if your flight scenario version differs.

8.2 Table type Z####_T_CUST ​

ABAP Dictionary table types in ADT are maintained using a form-based Table Type editor; unlike the structure above, there is no corresponding define table type ... source to paste into a DDL editor. Enter the complete properties:

PropertyValue
NameZ####_T_CUST
Row typeZ####_CUSTOMER
Table category / access modeHashed Table
Primary key kindKey Components
Primary key componentCUSTOMER_ID
Key uniquenessUnique

This is the correct type for repeated lookup by a unique customer ID after initial population. Save and activate the table type.

The equivalent ABAP declaration for understanding the type (not a replacement for the required DDIC object) is:

abap
TYPES ty_customer_tab TYPE HASHED TABLE OF z####_customer
  WITH UNIQUE KEY customer_id.

8.3 Complete consumer example ​

Create a separate optional console class named ZCL_####_TEST_CUSTOMERS to exercise the activated DDIC table type:

abap
CLASS zcl_####_test_customers DEFINITION
  PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
ENDCLASS.

CLASS zcl_####_test_customers IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA customers TYPE z####_t_cust.

    SELECT FROM /dmo/customer
      FIELDS customer_id, first_name, last_name, street,
             postal_code, city, country_code
      INTO CORRESPONDING FIELDS OF TABLE @customers.

    "Read by the hashed table's unique primary key.
    READ TABLE customers
      WITH TABLE KEY customer_id = '000001'
      INTO DATA(customer).

    IF sy-subrc = 0.
      out->write(
        |{ customer-customer_id }: | &&
        |{ customer-first_name } { customer-last_name }| ).
    ELSE.
      out->write( 'Customer 000001 not found in this system.' ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

The precise sample customer IDs depend on your trial tenant. The required deliverables for Task 8 are the DDIC structure and the DDIC hashed table type, not the optional test class.

Final Verification Checklist ​

Sources and limitations ​

The exercise requirements and order follow the uploaded C_ABAPD 2601 task instructions and the accompanying independent trial practice assignment. The implementations on this page are original worked examples, not supplied official SAP solutions.

ABAP/RAP syntax and trial workflows were checked against these SAP sources:

Validation status

These are reference implementations, not tenant-tested artifacts. In particular, the RAP wizard's generated names, status-domain restrictions, and custom PFCG authorization setup must be verified in an actual BTP trial tenant. The independent practice source supplies some dependencies that do not exist as standard objects in trial.


Independent teaching material — last researched October 2026. Not affiliated with or endorsed by SAP.