2

首先,我在 ECC 中使用 ABAP 7.50 和 Oracle DB 进行开发。我有一个 BRF+ 规则,对于给定的邮政编码,我会返回一个特定的承包商 ID。

只有 2 个可能的承包商 ID,但每个的邮政编码是一组基于范围和唯一值的规则。

简化规则示例:

IF postalCode >= 1000 and postalCode <= 2000 THEN Contractor1
ELSE postalCode = 2001 THEN Contractor2
ELSE postalCode = 2002 THEN Contractor1
ELSE Contractor2

现在我有一个返回工作订单信息的 ABAP CDS,我还需要它在标题中返回供应商 ID。我可以以某种方式使用工作订单邮政编码调用 BRF+ 并仅使用 CDS 获取供应商 ID 吗?

我想这样做是因为 CDS 直接作为 ODATA 服务公开。否则我可以使用 OpenSQL 来查询数据库,然后填写剩余的字段。

编辑:我将豪杰的答案标记为正确,即使它只能从 7.51 版本开始。对于较低版本 - 据我所知 - 除了从 CDS 视图读取后添加逻辑(在网关中或不直接从视图创建 ODATA 服务,而是使用 ABAP 添加缺失的信息)之外,没有其他解决方案。

4

3 回答 3

1

您可以使用ABAP CDS 虚拟元素

您需要在 Work Order CDS 之上构建另一个 CDS 视图,并创建一个新的人工字段(如 VendorID)并对其进行注释。

 define view my_cds_view 
    as select from WorkOrder
{
    ...
     @ObjectModel.readOnly: true
     @ObjectModel.virtualElement
     @ObjectModel.virtualElementCalculatedBy: 'cl_brf_plus_vendor_id'
    cast('' as abap.lifnr ) as VendorID       
    ...
 } 

创建一个 Class cl_brf_plus_vendor_id 来实现 if_sadl_exit_calc_element_read

CLASS cl_brf_plus_vendor_id DEFINITION
    PUBLIC
    FINAL
    CREATE PUBLIC .

    PUBLIC SECTION.
    INTERFACES:
    if_sadl_exit_calc_element_read.

    PROTECTED SECTION.
    PRIVATE SECTION.
ENDCLASS.


CLASS cl_brf_plus_vendor_id IMPLEMENTATION.

   METHOD if_sadl_exit_calc_element_read~get_calculation_info.

   ENDMETHOD.


   METHOD if_sadl_exit_calc_element_read~calculate.

       CHECK NOT it_original_data IS INITIAL.

       DATA lt_calculated_data TYPE STANDARD TABLE OF my_cds_view WITH DEFAULT KEY.

       MOVE-CORRESPONDING it_original_data TO lt_calculated_data.

       LOOP AT lt_calculated_data ASSIGNING FIELD-SYMBOL(<ls_calculated_data>).
         **"Get the postal code and call BRF+ to 
           "have the value of artificial field VendorID.** 

       ENDLOOP.

       MOVE-CORRESPONDING lt_calculated_data TO ct_calculated_data.

    ENDMETHOD.

  ENDCLASS.

将 my_cds_view 作为数据源添加到您的网关项目。

于 2019-08-31T00:55:50.247 回答
0

您可以将 CDS 表函数用于您的任务以及它们将中间结果存储在内部表中的能力。自 AMDP 发布时的 7.40 SP05 以来它仍然可用,并且自 7.50 以来表函数可用。

假设您有带有订单的 CDS 视图,由表函数实现zcl_cds_ord

@EndUserText.label: 'BRF function'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define table function ZCDS_ORD_FUNC
returns {
  mandt       :mandt;
  ebeln       :ebeln;
  bstyp       :ebstyp;
  vendor_id   :lifnr;
}
implemented by method zcl_cds_ord=>get_vendor;

您想通过 BRF+ 按订单 ID 获取每个订单的供应商 ID。

要完成表函数实现类中的任务,您应该创建单独的方法,该方法将调用 BRF+ 并更新中间 itab,并在主表函数方法中将内部表重新读取到最终 CDS 视图中。

AMDP 类的可能实现:

CLASS zcl_cds_ord DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_orders,
             mandt     TYPE mandt,
             ebeln     TYPE ebeln,
             bstyp     TYPE ebstyp,
             vendor_id TYPE lifnr,
           END OF ty_orders,
           tty_orders TYPE STANDARD TABLE OF ty_orders.

    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS get_vendor FOR TABLE FUNCTION zcds_ord_func.
    METHODS call_brf CHANGING it_orders TYPE tty_orders.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_cds_ord IMPLEMENTATION.
  METHOD get_vendor BY DATABASE FUNCTION
          FOR HDB
          LANGUAGE SQLSCRIPT
          OPTIONS READ-ONLY.

    itab_orders = SELECT mandt,
                         ebeln,
                         bstyp,
                         '' AS vendor_id
                  FROM ekko;

    CALL call_brf CHANGING itab_orders.

    RETURN SELECT mandt, ebeln, bstyp, vendor_id
    FROM :itab_orders.
  ENDMETHOD.

  METHOD call_brf.
    DATA: lo_fuction    TYPE REF TO if_fdt_function.

* Get BRFplus function
    lo_fuction ?= cl_fdt_factory=>if_fdt_factory~get_instance( )->get_function( '50E549C2C40B1ED6A69FCB34B9365358' ).

* Set the BRFplus function context ( input variables )
    DATA(lo_context) = lo_fuction->get_process_context( ).

    LOOP AT it_orders ASSIGNING FIELD-SYMBOL(<fs_order>).
      lo_context->set_value( : iv_name  = 'ORDER_ID' ia_value = <fs_order>-ebeln   ) .
* Process the BRFplus function
      lo_fuction->process( EXPORTING io_context =  lo_context
                           IMPORTING eo_result  =  DATA(lo_result) ).

* Retrieve the BRFplus function result
      lo_result->get_value( IMPORTING ea_value =  <fs_order>-vendor_id ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

请注意,在 CDS 实现方法(if_amdp_marker_hdb接口)中,您只能使用SQLScript语句,但在其他方法中,您可以使用 ABAP。

于 2019-10-29T00:24:56.480 回答
0

上面答案中给出的以下代码片段在我看来不起作用。您不能在 AMDP 方法中调用 ABAP 方法,在这种情况下 CALL ... CHANGING 甚至不是语法的一部分,它看起来像是 SQLscript 和 ABAP 的混合体。

  METHOD get_vendor BY DATABASE FUNCTION
          FOR HDB
          LANGUAGE SQLSCRIPT
          OPTIONS READ-ONLY.

    itab_orders = SELECT mandt,
                         ebeln,
                         bstyp,
                         '' AS vendor_id
                  FROM ekko;

    CALL call_brf CHANGING itab_orders.

    RETURN SELECT mandt, ebeln, bstyp, vendor_id
    FROM :itab_orders.
  ENDMETHOD.
于 2021-03-05T15:27:07.650 回答