欢迎来到萧静默的博客

书山有路勤为径,学海无涯苦作舟。

外围系统读取SAP采购信息程序(怎么把单值或者表里的值转换为SQL里where里的多条件值)

背景:面向用户的系统是一个智能体,用户会提他们想要的问题,通过NPL处理后,形成对于SAP的入参,由于入参是单个数据或者多个数据,条件也是不定的。

比如用户可能会问2025年创建了多少采购订单,对于这种提问智能体会按照2025年去查所有采购订单;用户问XX供应商和XX供应商发生了多少采购订单,智能体会传2个供应商编码给SAP去查,所以对于SAP来说条件还是需要使用range类型,怎么把智能体的入参转为range类型是关键。经过摸索,做了粗陋的代码如下:

DATA:LS_ZTMM023 TYPE ZSMM023,
         LT_ZTMM023 TYPE TABLE OF ZSMM023.
    DATA:T_PURINFO TYPE STANDARD TABLE OF ZSMM023.
    DATA:E_SUCC    TYPE  CHAR1,
         E_MESSAGE TYPE  MSGTX.
    DATA:EBELN TYPE  EBELN,
         BSART TYPE  BSART,
         EKORG TYPE  EKORG,
         EKOTX TYPE  EKOTX,
         BUKRS TYPE  BUKRS,
         BUTXT TYPE  BUTXT,
         LIFNR TYPE  LIFNR,
         FDATE TYPE  BEDAT,
         EDATE TYPE  BEDAT,
         NAME1 TYPE  NAME1,
         MATNR TYPE  MATNR,
         MAKTX TYPE  MAKTX.

    DATA: LR_EBELN TYPE RANGE OF EBELN. " 范围内表:存储单值对应的范围
    DATA: LR_BSART TYPE RANGE OF BSART. " 范围内表:存储单值对应的范围
    DATA: LR_EKORG TYPE RANGE OF EKORG. " 范围内表:存储单值对应的范围
    DATA: LR_BUKRS TYPE RANGE OF BUKRS. " 范围内表:存储单值对应的范围
    DATA: LR_LIFNR TYPE RANGE OF LIFNR. " 范围内表:存储单值对应的范围
    DATA: LR_MATNR TYPE RANGE OF MATNR. " 范围内表:存储单值对应的范围
    DATA: LR_DATE TYPE RANGE OF BEDAT. " 开始日期范围内表:存储单值对应的范围

    IF INPUT-MT_GET_PURINFO_REQ IS NOT INITIAL.
      IF INPUT-MT_GET_PURINFO_REQ-EBELN_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-EBELN_REQ INTO DATA(LS_EBELN).
          LR_EBELN = VALUE #( BASE LR_EBELN    ( SIGN = 'I' OPTION = 'EQ' LOW = LS_EBELN-EBELN HIGH = '' )  ).
        ENDLOOP.
        SORT LR_EBELN BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_EBELN COMPARING LOW.
        DELETE LR_EBELN WHERE LOW = ''.
      ELSE.
        CLEAR LR_EBELN[]."这个很关键,如果没有值,要清空,才能算没有条件
      ENDIF.

      IF INPUT-MT_GET_PURINFO_REQ-BSART_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-BSART_REQ INTO DATA(LS_BSART).
          LR_BSART = VALUE #( BASE LR_BSART    ( SIGN = 'I' OPTION = 'EQ' LOW = LS_BSART-BSART HIGH = '' )  ).
        ENDLOOP.
        SORT LR_BSART BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_BSART COMPARING LOW.
        DELETE LR_BSART WHERE LOW = ''.
      ELSE.
        CLEAR LR_EBELN[].
      ENDIF.

      IF INPUT-MT_GET_PURINFO_REQ-EKORG_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-EKORG_REQ INTO DATA(LS_EKORG).
          LR_EKORG = VALUE #( BASE LR_EKORG    ( SIGN = 'I' OPTION = 'EQ' LOW = LS_EKORG-EKORG HIGH = '' )  ).
        ENDLOOP.
        SORT LR_EKORG BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_EKORG COMPARING LOW.
        DELETE LR_EKORG WHERE LOW = ''.
      ELSE.
        CLEAR LR_EKORG[].
      ENDIF.

      IF INPUT-MT_GET_PURINFO_REQ-BUKRS_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-BUKRS_REQ INTO DATA(LS_BUKRS).
          LR_BUKRS = VALUE #( BASE LR_BUKRS    ( SIGN = 'I' OPTION = 'EQ' LOW = LS_BUKRS-BUKRS HIGH = '' )  ).
        ENDLOOP.
        SORT LR_BUKRS BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_BUKRS COMPARING LOW.
        DELETE LR_BUKRS WHERE LOW = ''.
      ELSE.
        CLEAR LR_BUKRS[].
      ENDIF.

      IF INPUT-MT_GET_PURINFO_REQ-LIFNR_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-LIFNR_REQ INTO DATA(LS_LIFNR).
          LIFNR = LS_LIFNR-LIFNR .
          LIFNR = |{ LIFNR ALPHA = IN }|.
          LR_LIFNR = VALUE #( BASE LR_LIFNR    ( SIGN = 'I' OPTION = 'EQ' LOW = LIFNR HIGH = '' )  ).
        ENDLOOP.
        SORT LR_LIFNR BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_LIFNR COMPARING LOW.
        DELETE LR_LIFNR WHERE LOW = ''.
      ELSE.
        CLEAR LR_LIFNR[].
      ENDIF.

      IF INPUT-MT_GET_PURINFO_REQ-MATNR_REQ IS NOT INITIAL.
        LOOP AT INPUT-MT_GET_PURINFO_REQ-MATNR_REQ INTO DATA(LS_MATNR).
          MATNR = LS_MATNR-MATNR.
          MATNR = |{ MATNR ALPHA = IN WIDTH = 18 }|.
          LR_MATNR = VALUE #( BASE LR_MATNR    ( SIGN = 'I' OPTION = 'EQ' LOW = MATNR HIGH = '' )  ).
        ENDLOOP.
        SORT LR_MATNR BY LOW. " 可选:排序去重以优化性能
        DELETE ADJACENT DUPLICATES FROM LR_MATNR COMPARING LOW.
        DELETE LR_MATNR WHERE LOW = ''.
      ELSE.
        CLEAR LR_MATNR[].
      ENDIF.
"起始日期为2000年,终止日期为9999年
      IF INPUT-MT_GET_PURINFO_REQ-FDATE IS INITIAL AND INPUT-MT_GET_PURINFO_REQ-EDATE IS NOT INITIAL.
        LR_DATE = VALUE #( BASE LR_DATE    ( SIGN = 'I' OPTION = 'BT' LOW = '20000000' HIGH = INPUT-MT_GET_PURINFO_REQ-EDATE )  ).
      ELSEIF INPUT-MT_GET_PURINFO_REQ-FDATE IS NOT INITIAL AND INPUT-MT_GET_PURINFO_REQ-EDATE IS  INITIAL.
        LR_DATE = VALUE #( BASE LR_DATE    ( SIGN = 'I' OPTION = 'BT' LOW = INPUT-MT_GET_PURINFO_REQ-FDATE HIGH = '99999999' )  ).
      ELSEIF INPUT-MT_GET_PURINFO_REQ-FDATE IS INITIAL AND INPUT-MT_GET_PURINFO_REQ-EDATE IS  INITIAL.
        LR_DATE = VALUE #( BASE LR_DATE    ( SIGN = 'I' OPTION = 'BT' LOW = '20000000' HIGH = '99999999' )  ).
      ELSEIF INPUT-MT_GET_PURINFO_REQ-FDATE IS NOT INITIAL AND INPUT-MT_GET_PURINFO_REQ-EDATE IS NOT INITIAL.
        LR_DATE = VALUE #( BASE LR_DATE    ( SIGN = 'I' OPTION = 'BT' LOW = INPUT-MT_GET_PURINFO_REQ-FDATE HIGH = INPUT-MT_GET_PURINFO_REQ-EDATE   )  ).
      ENDIF.


      SELECT EKPO~EBELN,
         EKPO~EBELP,
         EKKO~BUKRS,
         T001~BUTXT,
         EKKO~EKORG,
         T024E~EKOTX,
         EKKO~BSART,
         EKKO~LIFNR,
         LFA1~NAME1,
         EKKO~BEDAT,
         EKPO~MATNR,
         MAKT~MAKTX,
         EKPO~MENGE,
         EKPO~MEINS,
         EKPO~PEINH,
         EKPO~NETWR AS SUMPRICE_NO_TAX,"未税总值
         EKPO~BRTWR AS SUMPRICE_TAX, "含税总值
         EKPO~MWSKZ,
*         EKPO~EBELP AS ZTAX,
         EKKO~WAERS,
         EKPO~NETPR AS UNPRICE_NO_TAX, "未税单价
          DIVISION( EKPO~BRTWR ,EKPO~MENGE,3 ) AS UNPRICE_TAX,"含税单价
         EKKO~LANDS
    FROM EKPO
    INNER JOIN EKKO ON EKKO~EBELN = EKPO~EBELN
    LEFT JOIN MAKT ON MAKT~MATNR = EKPO~MATNR
    LEFT JOIN T024E ON T024E~EKORG = EKKO~EKORG
    LEFT JOIN LFA1 ON LFA1~LIFNR = EKKO~LIFNR
    LEFT JOIN T001 ON T001~BUKRS = EKKO~BUKRS

    WHERE EKKO~EBELN IN @LR_EBELN
          AND  EKKO~BSART IN @LR_BSART
          AND  EKKO~EKORG IN @LR_EKORG
          AND  EKKO~BUKRS IN @LR_BUKRS
          AND  EKKO~LIFNR IN @LR_LIFNR
          AND  EKPO~MATNR IN @LR_MATNR
          AND EKKO~BEDAT IN @LR_DATE
       INTO CORRESPONDING FIELDS OF TABLE @T_PURINFO.

      LOOP AT T_PURINFO INTO DATA(LS_PURINFO).
        SELECT SINGLE KNUMH INTO @DATA(LS_KNUMH) FROM A003 WHERE MWSKZ = @LS_PURINFO-MWSKZ AND ALAND = @LS_PURINFO-LANDS.
        SELECT SINGLE KBETR INTO @DATA(LS_KBETR) FROM KONP WHERE KNUMH = @LS_KNUMH.
        LS_PURINFO-ZTAX = LS_KBETR / 1000.
        MODIFY T_PURINFO FROM LS_PURINFO.
        CLEAR:LS_PURINFO,LS_KNUMH,LS_KBETR.
      ENDLOOP.

      IF T_PURINFO IS NOT INITIAL.
        OUTPUT-MT_GET_PURINFO_RES-E_SUCC = 'S'.
        OUTPUT-MT_GET_PURINFO_RES-E_MESSAGE = '成功查到数据!'.
        OUTPUT-MT_GET_PURINFO_RES-DATA_RES = CORRESPONDING #( T_PURINFO ).
      ELSE.
        OUTPUT-MT_GET_PURINFO_RES-E_SUCC = 'E'.
        OUTPUT-MT_GET_PURINFO_RES-E_MESSAGE = '没有查到数据!'.
      ENDIF.
    ELSE.

      OUTPUT-MT_GET_PURINFO_RES-E_SUCC = 'E'.
      OUTPUT-MT_GET_PURINFO_RES-E_MESSAGE = '没有收到数据!'.
    ENDIF.

ZSMM023结构如下

image

 PO接口如下

image

 返回如下

image

 

posted @ 2025-08-20 17:28  萧静默  阅读(34)  评论(0)    收藏  举报