Вызвать метод класса из представления ABAP CDS?

#sapui5 #abap #sap-fiori #cds

#abap #opensql #cds

Вопрос:

Я хотел бы вызвать метод из класса в существующем представлении CDS, чтобы получить определенные данные, которые могут быть вызваны только этим методом. Итак, я хочу вызвать метод из представления CDS.

Какой самый простой способ сделать это?

Я был бы очень рад примеру с кодом.

Комментарии:

1. узнайте о функциях таблицы CDS

2. Табличная функция — это AMDP, который в основном является сценарием HANA SQL. не ABAP. виртуальный элемент или пользовательская сущность — это правильный путь .

Ответ №1:

ПРИМЕЧАНИЕ: ваша логика abap будет выполняться только тогда, когда представление CDS используется чем-то, что обрабатывает аннотации, т.Е. Отображается как служба Odata, но не в транзакции SE16N или в предварительном просмотре в Eclipse. На самом деле есть два способа. Первый вариант:

 @AbapCatalog.sqlViewName: 'ZV_TEST_ABAP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'ABAP code in cds'
@OData.publish: true
define view YCDS_WITH_ABAP as select from sflight
{

  //sflight
  key carrid,
  key connid,
  key fldate,
      seatsocc_f,
      @ObjectModel.readOnly: true
      @ObjectModel.virtualElement: true 
      @ObjectModel.virtualElementCalculatedBy: 'ABAP:YCL_CDS_FUNCTION' //ycl_cds_function 
      cast( '' as abap.char(255)) as text
    
}where connid = '0017'
  

Ваш класс abap:

 CLASS ycl_cds_function DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .



  PUBLIC SECTION.
    INTERFACES: if_sadl_exit_calc_element_read.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS ycl_cds_function IMPLEMENTATION.

 METHOD if_sadl_exit_calc_element_read~calculate.

    DATA:
      lt_calculated_data TYPE STANDARD TABLE OF ZV_TEST_ABAP .

    " it_original_data -> data that comes from cds
    " lt_calculated_data -> data that you will manipulate
    MOVE-CORRESPONDING it_original_data TO lt_calculated_data.

    " do your extra logic and append/update your cds view data
    LOOP AT lt_calculated_data ASSIGNING FIELD-SYMBOL(<fs_data>).
        <fs_data>-text = 'hello from abap!'.
    ENDLOOP.

    MOVE-CORRESPONDING lt_calculated_data TO ct_calculated_data.

  ENDMETHOD.

  METHOD if_sadl_exit_calc_element_read~get_calculation_info.

  ENDMETHOD.

ENDCLASS.
  

Просмотр в eclipse:
введите описание изображения здесь
Просмотр в odata:

   ...,{
                "__metadata": {
                    "id": "lalala')",
                    "uri": "blablabla')",
                    "type": "YCDS_WITH_ABAP_CDS.YCDS_WITH_ABAPType"
                },
                "carrid": "AA",
                "connid": "0017",
                "fldate": "/Date(1535068800000)/",
                "seatsocc_f": 20,
                "text": "hello from abap!"
   },...
  

Второй вариант:

Второй способ — изменить класс DPC вашего сервиса на свой пользовательский класс, который наследует этот стандартный класс, и выполнить вашу пользовательскую логику в этих переопределенных методах. Лично я бы выбрал второй вариант. Я не пробовал, но у меня такое чувство, что производительность будет лучше. 🙂

введите описание изображения здесь

Для получения дополнительной информации, пожалуйста, проверьте: https://blogs.sap.com/2020/05/11/abap-code-exits-in-cds-views /

Ответ №2:

Хотя ответ @Oguz стоит знать с точки зрения OData, существует также чистое решение CDS, которое работает в каждом компоненте, который выбирает из представлений CDS, независимо от того, поддерживают ли они аннотации или нет.

Сначала вы указываете представление CDS как SELECT FROM <table function> :

 @AbapCatalog.sqlViewName: 'MYCDSVIEW'
define view MY_CDS_VIEW as select from MY_TABLE_FUNCTION {    
    A,
    B
}
  

Затем вы определяете табличную функцию. Табличные функции похожи на CDS view, только их логика выполнения реализована в ABAP, а не в SQL Script:

 define table function MY_TABLE_FUNCTION
returns
{
  A : some_type;
  B : some_type;
}
implemented by method
  cl_my_table_function=>provide_data_for_tf_test;
  

Наконец, вы предоставляете класс ABAP, который реализует функцию table:

 CLASS cl_my_table_function DEFINITION
    PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS provide_data FOR TABLE FUNCTION MY_TABLE_FUNCTION.
ENDCLASS.

CLASS cl_my_table_function IMPLEMENTATION.

  METHOD provide_data 
    BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT
    USING some_table.

    RETURN
      SELECT A, B
       FROM some_table;

  ENDMETHOD.

ENDCLASS.
  

Когда вы делаете что-то подобное, выделите дополнительное время для тестирования обработки клиента. Эта комбинация способов часто приводит к автоматическим добавлениям клиента, которые пользователи ABAP знают из инструкции SELECT и обычных представлений CDS. Есть вероятность, что вам понадобятся аннотации, подобные @ClientHandling: { type: #CLIENT_DEPENDENT } включенным представлениям CDS, и чтобы функция таблицы явно предоставляла столбцы CLIENT или MANDT.