SAP: Get Open PR & PO Qty

本文介绍了一个用于SAP MM模块的ABAP程序,该程序旨在报告未完成的采购订单及其确认状态。通过从多个SAP标准表中抽取数据,并结合选择条件筛选出特定工厂、采购组等信息,最终将数据整理并保存到自定义表中以供后续使用。

 

*&---------------------------------------------------------------------*
*& Progarm      :  ZMM_OSPO_MONTH                 Author : Jimmy Wong
*& Created      :  18 Jan 2013                    App    : MM
*& Title        :  Open PO Monthly
*& Description  :  Open PO Monthly
*&---------------------------------------------------------------------*
*&  Version       Author      Date        description
*&                Jimmy       18 Jan 2013 the first version
*&  the last update time  2013.01.18  18:00
*&---------------------------------------------------------------------*


REPORT  ZMM_OSPO_MONTH NO STANDARD PAGE HEADING .

***********************************************************************
*                              TYPE-POOLS
***********************************************************************
TYPE-POOLS : SLIS.
************************************************************************
* T A B L E S
************************************************************************
TABLES: EKKO,
        EKPO,
        EKET,
        EKES,
        LFA1,
        EBAN.

************************************************************************
* D A T A
************************************************************************
DATA: BEGIN OF PO_ITAB OCCURS 0,
        WERKS TYPE EKPO-WERKS,
        EBELN TYPE EKKO-EBELN,
        EBELP TYPE EKPO-EBELP,
        ETENR TYPE EKET-ETENR,
        MATNR TYPE EKPO-MATNR,
        MENGE TYPE EKPO-MENGE,
        WEMNG TYPE EKET-WEMNG,
        MEINS TYPE EKPO-MEINS,
        EINDT TYPE EKET-EINDT,
        WAERS LIKE EKKO-WAERS,
        NETPR LIKE EKPO-NETPR,
        PEINH LIKE EKPO-NETPR,
        WKURS LIKE EKKO-WKURS,
     END OF PO_ITAB.

DATA: BEGIN OF OA_ITAB OCCURS 0,
        EBTYP TYPE EKES-EBTYP,
        EBELN TYPE EKES-EBELN,
        EBELP TYPE EKES-EBELP,
        ETENS TYPE EKES-ETENS,
        EINDT TYPE EKES-EINDT,
        MENGE TYPE EKES-MENGE,
        DABMG TYPE EKES-DABMG,
        ERDAT TYPE EKES-ERDAT,
        XBLNR TYPE EKES-XBLNR,
     END OF OA_ITAB.

DATA: BEGIN OF VC_ITAB OCCURS 0,
        EBTYP TYPE EKES-EBTYP,
        EBELN TYPE EKES-EBELN,
        EBELP TYPE EKES-EBELP,
        ETENS TYPE EKES-ETENS,
        EINDT TYPE EKES-EINDT,
        MENGE TYPE EKES-MENGE,
        DABMG TYPE EKES-DABMG,
        ERDAT TYPE EKES-ERDAT,
        XBLNR TYPE EKES-XBLNR,
     END OF VC_ITAB.

DATA: BEGIN OF PO_RECORD OCCURS 0,
        WERKS TYPE EKPO-WERKS,
        EBELN TYPE EKKO-EBELN,
        EBELP TYPE EKPO-EBELP,
        ETENR TYPE EKET-ETENR,
        MATNR TYPE EKPO-MATNR,
        MENGE TYPE EKPO-MENGE,
        WEMNG TYPE EKET-WEMNG,
        MEINS TYPE EKPO-MEINS,
        EINDT TYPE EKET-EINDT,
        OAENS TYPE EKES-ETENS,
        OADAT TYPE EKES-EINDT,
        OAQTY TYPE EKES-MENGE,
        OAREF TYPE EKES-XBLNR,
        VCENS TYPE EKES-ETENS,
        VCDAT TYPE EKES-EINDT,
        VCQTY TYPE EKES-MENGE,
        VCREF TYPE EKES-XBLNR,
        WAERS LIKE EKKO-WAERS,
        NETPR LIKE EKPO-NETPR,
        PEINH LIKE EKPO-NETPR,
        WKURS LIKE EKKO-WKURS,
END OF PO_RECORD.
DATA:BEGIN OF IT_DEL OCCURS 50,
     LFGJA LIKE ZPOOPEN-LFGJA,
     LFMON LIKE ZPOOPEN-LFMON,
     WERKS LIKE ZPOOPEN-WERKS,
    END OF IT_DEL.
DATA: WA_RECORD LIKE PO_RECORD.
DATA:IT_ZPOOPEN LIKE ZPOOPEN OCCURS 0  WITH HEADER LINE .
DATA:IT_ZPROPEN LIKE ZPROPEN OCCURS WITH HEADER LINE.
DATA:IT_ZPROPEN1 LIKE ZPROPEN OCCURS WITH HEADER LINE.
DATA:BEGIN OF IT_MBEW OCCURS 0,
    MATNR LIKE MBEW-MATNR,
    BWKEY LIKE MBEW-BWKEY ,
    VPRSV LIKE MBEW-VPRSV,
    VERPR LIKE MBEW-VERPR ,
    STPRS LIKE MBEW-STPRS ,
    PEINH LIKE MBEW-PEINH ,
    END OF IT_MBEW.

DATA: FIELDCATALOG TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
      GD_LAYOUT    TYPE SLIS_LAYOUT_ALV,
      GD_REPID     LIKE SY-REPID,
      G_SAVE TYPE VALUE 'X',
      G_VARIANT TYPE DISVARIANT,
      GX_VARIANT TYPE DISVARIANT,
      G_EXIT TYPE C,
     LV_LFGJA LIKE BAPI0002_4-FISCAL_YEAR,
     LV_LFMON LIKE BAPI0002_4-FISCAL_PERIOD .
DATA:LV_TOTAL_LINE TYPE I,
      LV_LINE TYPE DECIMALS 3.
DATA:LV_SUBRC LIKE SY-SUBRC.
************************************************************************
* S E L E C T O P T I O N S
************************************************************************
SELECTION-SCREEN BEGIN OF BLOCK SEL1 WITH FRAME TITLE TEXT-001.
PARAMETERS  : P_BUDAT LIKE MKPF-BUDAT  OBLIGATORY .
SELECT-OPTIONS : S_WERKS FOR EKPO-WERKS ,            "Plant
                S_MATNR FOR EKPO-MATNR.
SELECTION-SCREEN END OF BLOCK SEL1.

SELECTION-SCREEN BEGIN OF BLOCK SEL2 WITH FRAME TITLE TEXT-002.
SELECT-OPTIONS : S_EKGRP FOR EKKO-EKGRP ,             "Pur Group
                 S_LIFNR FOR EKKO-LIFNR ,             "Vendor
                 S_EBELN FOR EKKO-EBELN .             "PO Number
SELECTION-SCREEN END OF BLOCK SEL2.

SELECTION-SCREEN BEGIN OF BLOCK SEL5 WITH FRAME TITLE TEXT-005.
SELECT-OPTIONS : S_BANFN FOR EBAN-BANFN .             "Pur Group
SELECTION-SCREEN END OF BLOCK SEL5.

SELECTION-SCREEN BEGIN OF BLOCK SEL3 WITH FRAME TITLE TEXT-003.
PARAMETERS : P_SAVE AS CHECKBOX.
PARAMETERS : P_SAVEPR AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK SEL3.

INITIALIZATION.
  CONCATENATE SY-DATUM+0(4SY-DATUM+4(2'01'  INTO P_BUDAT .
  P_BUDAT  P_BUDAT 1.

************************************************************************
* S T A R T   O F   S E L E C T I O N
************************************************************************
START-OF-SELECTION.
  PERFORM GET_PERIOD CHANGING LV_SUBRC.
  IF LV_SUBRC NE 0.
    MESSAGE 'Get period Error.' TYPE 'I'.
    EXIT.
  ENDIF.
  IF P_SAVE 'X'.
    PERFORM GET_DATA .                                              "Select data
    PERFORM GET_CF_DATA.
    PERFORM GROUP_DATA.
    PERFORM SAVE_DATA.
    FREE: PO_ITAB, OA_ITAB, VC_ITAB, PO_RECORD.
  ENDIF.
  IF P_SAVEPR 'X'.
    PERFORM GET_PR_DATA .
    PERFORM SAVE_PR_DATA.
  ENDIF.

*  perform prepare_alv .                                           "Prepare_ALV
*  perform call_alv .                                              "Print



*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       Get Outstanding PO
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM GET_DATA .
  REFRESH:  PO_ITAB, OA_ITAB, VC_ITAB, PO_RECORD.

  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      TEXT 'Get Data........'.

  SELECT C~WERKS A~EBELN  C~EBELP C~MATNR C~MENGE D~WEMNG
         C~MEINS D~EINDT D~ETENR A~WKURS A~WAERS C~NETPR C~PEINH
     INTO CORRESPONDING FIELDS OF TABLE PO_ITAB
     FROM EKKO AS A
       INNER JOIN EKPO AS ON A~EBELN C~EBELN
       INNER JOIN EKET AS ON C~EBELN D~EBELN AND C~EBELP D~EBELP
         WHERE C~WERKS IN S_WERKS
           AND A~EKGRP IN S_EKGRP
           AND A~LIFNR IN S_LIFNR
           AND A~EBELN IN S_EBELN
           AND C~MATNR IN S_MATNR
           AND C~MENGE > D~WEMNG
           AND C~LOEKZ ''.
ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  get_cf_data
*&---------------------------------------------------------------------*
*       Get Confirmation Record
*----------------------------------------------------------------------*
FORM GET_CF_DATA.

  SELECT EBTYP EBELN EBELP ETENS EINDT MENGE DABMG ERDAT XBLNR
    INTO CORRESPONDING FIELDS OF TABLE OA_ITAB
    FROM EKES
    FOR ALL ENTRIES IN PO_ITAB
    WHERE EBELN PO_ITAB-EBELN AND
          EBELP PO_ITAB-EBELP AND
          EBTYP 'OA'.

  LOOP AT OA_ITAB.
    IF  OA_ITAB-MENGE <= OA_ITAB-DABMG.
      DELETE OA_ITAB.
    ENDIF.
  ENDLOOP.

  SELECT EBTYP EBELN EBELP ETENS EINDT MENGE DABMG ERDAT XBLNR
    INTO CORRESPONDING FIELDS OF TABLE VC_ITAB
    FROM EKES
    FOR ALL ENTRIES IN PO_ITAB
    WHERE EBELN PO_ITAB-EBELN AND
          EBELP PO_ITAB-EBELP AND
          EBTYP 'FI' OR EBTYP 'VC' ).
ENDFORM.                    "get_cf_data

*&---------------------------------------------------------------------*
*&      Form  GROUP_DATA
*&---------------------------------------------------------------------*
*       Combine records
*----------------------------------------------------------------------*
FORM GROUP_DATA.

  DATA : VC_REF TYPE EKES-ETENS.

  SORT PO_ITAB BY WERKS EBELN EBELP.
  SORT OA_ITAB BY EBELN EBELP ETENS.
  SORT VC_ITAB BY EBELN EBELP ETENS.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      TEXT 'Processing Data........'.
  LOOP AT PO_ITAB.
    MOVE-CORRESPONDING PO_ITAB TO WA_RECORD.
    "    wa_record-wemng = wa_record-menge - wa_record-wemng.
    READ TABLE OA_ITAB WITH KEY EBELN WA_RECORD-EBELN EBELP WA_RECORD-EBELP .
    IF SY-SUBRC EQ 0.

      LOOP AT OA_ITAB WHERE EBELN WA_RECORD-EBELN AND EBELP WA_RECORD-EBELP.
        WA_RECORD-OAENS OA_ITAB-ETENS.
        WA_RECORD-OADAT OA_ITAB-EINDT.
        WA_RECORD-OAQTY OA_ITAB-MENGE OA_ITAB-DABMG.
        WA_RECORD-OAREF OA_ITAB-XBLNR.

        LOOP AT VC_ITAB WHERE EBELN WA_RECORD-EBELN AND EBELP WA_RECORD-EBELP.
          VC_REF VC_ITAB-XBLNR+0(4).
          IF VC_REF WA_RECORD-OAENS.
            WA_RECORD-VCENS VC_ITAB-ETENS.
            WA_RECORD-VCDAT VC_ITAB-EINDT.
            WA_RECORD-VCQTY VC_ITAB-MENGE.
            WA_RECORD-VCREF VC_ITAB-XBLNR.
          ENDIF.
        ENDLOOP.

        MOVE-CORRESPONDING WA_RECORD TO PO_RECORD.
        APPEND PO_RECORD.
        CLEAR: PO_RECORD,WA_RECORD-VCENS,WA_RECORD-VCDAT,WA_RECORD-VCQTY,WA_RECORD-VCREF.
      ENDLOOP.

    ELSE.
      READ TABLE VC_ITAB WITH KEY EBELN WA_RECORD-EBELN
                                  EBELP WA_RECORD-EBELP
                                  EBTYP 'FI'.
      IF SY-SUBRC 0.
        WA_RECORD-VCENS VC_ITAB-ETENS.
        WA_RECORD-VCDAT VC_ITAB-EINDT.
        WA_RECORD-VCQTY VC_ITAB-MENGE.
        WA_RECORD-VCREF VC_ITAB-XBLNR.
      ENDIF.
      MOVE-CORRESPONDING WA_RECORD TO PO_RECORD.
      APPEND PO_RECORD.
    ENDIF.
    CLEAR: PO_RECORD,WA_RECORD-OAENS,WA_RECORD-OADAT,WA_RECORD-OAQTY,WA_RECORD-OAREF,
        WA_RECORD-VCENS,WA_RECORD-VCDAT,WA_RECORD-VCQTY,WA_RECORD-VCREF.
  ENDLOOP.

  SORT PO_RECORD BY WERKS EBELN EBELP ETENR OAENS.

ENDFORM.                    "GROUP_DATA

*&---------------------------------------------------------------------*
*&      Form  PREPARE_ALV
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM PREPARE_ALV .
  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'WERKS'.
  FIELDCATALOG-SELTEXT_M   'Plant'.
  FIELDCATALOG-COL_POS     1.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'EBELN'.
  FIELDCATALOG-SELTEXT_M   'PO#'.
  FIELDCATALOG-COL_POS     2.
  APPEND FIELDCATALOG TO FIELDCATALOG.


  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'EBELP'.
  FIELDCATALOG-SELTEXT_M   'Line'.
  FIELDCATALOG-COL_POS     3.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'ETENR'.
  FIELDCATALOG-SELTEXT_M   'Sep No.'.
  FIELDCATALOG-COL_POS     4.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'MATNR'.
  FIELDCATALOG-SELTEXT_M   'Material'.
  FIELDCATALOG-REF_TABNAME 'MARA'.
  FIELDCATALOG-REF_FIELDNAME 'MATNR'.
  FIELDCATALOG-COL_POS     5.
  APPEND FIELDCATALOG TO FIELDCATALOG.



  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'MENGE'.
  FIELDCATALOG-SELTEXT_M   'Order Qty'.
  FIELDCATALOG-COL_POS     6.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'WEMNG'.
  FIELDCATALOG-SELTEXT_M   'O/S Qty'.
  FIELDCATALOG-COL_POS     7.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'MEINS'.
  FIELDCATALOG-SELTEXT_M   'U/M'.
  FIELDCATALOG-REF_TABNAME 'EKPO'.
  FIELDCATALOG-REF_FIELDNAME 'MEINS'.
  FIELDCATALOG-COL_POS     8.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'EINDT'.
  FIELDCATALOG-SELTEXT_M   'Due Date'.
  FIELDCATALOG-COL_POS     9.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'OAENS'.
  FIELDCATALOG-SELTEXT_M   'OA Line'.
  FIELDCATALOG-COL_POS     10.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'OADAT'.
  FIELDCATALOG-SELTEXT_M   'OA Date'.
  FIELDCATALOG-COL_POS     11.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'OAQTY'.
  FIELDCATALOG-SELTEXT_M   'OA Qty'.
  FIELDCATALOG-COL_POS     12.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'OAREF'.
  FIELDCATALOG-SELTEXT_M   'Org OA Line'.
  FIELDCATALOG-COL_POS     13.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'VCENS'.
  FIELDCATALOG-SELTEXT_M   'VC Line'.
  FIELDCATALOG-COL_POS     14.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'VCDAT'.
  FIELDCATALOG-SELTEXT_M   'VC Date'.
  FIELDCATALOG-COL_POS     15.
  APPEND FIELDCATALOG TO FIELDCATALOG.

  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'VCQTY'.
  FIELDCATALOG-SELTEXT_M   'VC Qty'.
  FIELDCATALOG-COL_POS     16.
  APPEND FIELDCATALOG TO FIELDCATALOG.


  CLEAR  FIELDCATALOG.
  FIELDCATALOG-FIELDNAME   'VCREF'.
  FIELDCATALOG-SELTEXT_M   'VC Reference'.
  FIELDCATALOG-COL_POS     17.
  APPEND FIELDCATALOG TO FIELDCATALOG.
ENDFORM.                    " PREPARE_ALV
*&---------------------------------------------------------------------*
*&      Form  CALL_ALV
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM CALL_ALV .
  GD_REPID SY-REPID.
  GD_LAYOUT-COLWIDTH_OPTIMIZE 'X'.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      I_CALLBACK_PROGRAM      GD_REPID
*     I_CALLBACK_TOP_OF_PAGE  = 'TOP-OF-PAGE' "see FORM
*     I_CALLBACK_USER_COMMAND = 'USER_COMMAND'
      IT_FIELDCAT             FIELDCATALOG[]
      I_SAVE                  'X'
      IS_VARIANT              G_VARIANT
      IS_LAYOUT               GD_LAYOUT
    TABLES
      T_OUTTAB                PO_RECORD
    EXCEPTIONS
      PROGRAM_ERROR           1
      OTHERS                  2.

  IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
ENDFORM.                    " CALL_ALV
*&---------------------------------------------------------------------*
*&      Form  SAVE_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM SAVE_DATA .
  CHECK PO_RECORD[] IS NOT INITIAL.

  PERFORM DELETE_DATA.
  LOOP AT PO_RECORD.
    MOVE-CORRESPONDING PO_RECORD TO IT_ZPOOPEN.
    IT_ZPOOPEN-OMENG  IT_ZPOOPEN-MENGE IT_ZPOOPEN-WEMNG.
    CHECK IT_ZPOOPEN-OMENG > 0.
    IF IT_ZPOOPEN-OAQTY 0.
      IT_ZPOOPEN-OAQTY IT_ZPOOPEN-OMENG .
    ENDIF.
    IF IT_ZPOOPEN-OADAT '00000000'.
      IT_ZPOOPEN-OADAT IT_ZPOOPEN-EINDT.
    ENDIF.
    IT_ZPOOPEN-LFGJA =  LV_LFGJA.
    IT_ZPOOPEN-LFMON LV_LFMON.

    IT_ZPOOPEN-PEINH PO_RECORD-PEINH.
    IT_ZPOOPEN-NETPR PO_RECORD-NETPR.
    IT_ZPOOPEN-WKURS PO_RECORD-WKURS.
    IT_ZPOOPEN-WAERS PO_RECORD-WAERS.
    PERFORM CONVERT_AMOUNT USING  PO_RECORD-WAERS CHANGING IT_ZPOOPEN-NETPR.
    IF PO_RECORD-WAERS 'JPY'.
      IF IT_ZPOOPEN-PEINH NE AND IT_ZPOOPEN-WKURS NE 0.
        IT_ZPOOPEN-NETWR IT_ZPOOPEN-OAQTY * IT_ZPOOPEN-NETPR * IT_ZPOOPEN-WKURS /  IT_ZPOOPEN-PEINH / 100.
      ENDIF.
    ELSE.
      IF IT_ZPOOPEN-PEINH NE AND IT_ZPOOPEN-WKURS NE 0.
        IT_ZPOOPEN-NETWR IT_ZPOOPEN-OAQTY * IT_ZPOOPEN-NETPR * IT_ZPOOPEN-WKURS /  IT_ZPOOPEN-PEINH.
      ENDIF.
    ENDIF.
    APPEND IT_ZPOOPEN.
    CLEAR: IT_ZPOOPEN.
  ENDLOOP.
  IF NOT IT_ZPOOPEN[] IS INITIAL.
    SORT  IT_ZPOOPEN BY EBELN EBELP ETENR OAENS LFGJA LFMON.
    MODIFY ZPOOPEN FROM TABLE IT_ZPOOPEN.
*      write: 'Excute Successed.'.
    REFRESH IT_ZPOOPEN.
    FREE:IT_ZPOOPEN.
  ENDIF.

ENDFORM.                    " SAVE_DATA
*&---------------------------------------------------------------------*
*&      Form  CONVERT_AMOUNT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM CONVERT_AMOUNT  USING  PI_WAERK
                     CHANGING PE_NETWR.
  DATA : LV_NETWR TYPE BAPICURR-BAPICURR.

  CHECK PI_WAERK <> 'HKD'.
  CHECK PI_WAERK <> 'USD'.
  CHECK PI_WAERK <> 'EUR'.
  CHECK PI_WAERK <> 'CNY'.

  CALL FUNCTION 'BAPI_CURRENCY_CONV_TO_EXTERNAL'
    EXPORTING
      CURRENCY        PI_WAERK
      AMOUNT_INTERNAL PE_NETWR
    IMPORTING
      AMOUNT_EXTERNAL LV_NETWR.

  PE_NETWR =  LV_NETWR.
ENDFORM.                    " CONVERT_AMOUNT
*&---------------------------------------------------------------------*
*&      Form  GET_PERIOD
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_LV_SUBRC  text
*----------------------------------------------------------------------*
FORM GET_PERIOD CHANGING P_SUBRC.
  DATA:LV_DATE  LIKE BAPI0002_4-POSTING_DATE,
       IT_RETURN LIKE BAPIRETURN1.
  LV_DATE  P_BUDAT .
  CALL FUNCTION 'BAPI_COMPANYCODE_GET_PERIOD'
    EXPORTING
      COMPANYCODEID '8000'
      POSTING_DATE  LV_DATE
    IMPORTING
      FISCAL_YEAR   LV_LFGJA
      FISCAL_PERIOD LV_LFMON
      RETURN        IT_RETURN.
  P_SUBRC SY-SUBRC .
ENDFORM.                    " GET_PERIOD
*&---------------------------------------------------------------------*
*&      Form  DELETE_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM DELETE_DATA .
  CLEAR:IT_DEL,IT_DEL[].
  SELECT DISTINCT  LFGJA LFMON WERKS
      INTO  CORRESPONDING FIELDS OF TABLE IT_DEL
      FROM ZPOOPEN
      WHERE LFGJA LV_LFGJA
      AND LFMON LV_LFMON
      AND WERKS IN S_WERKS.
  IF IT_DEL[] IS NOT INITIAL.
    LOOP AT IT_DEL.
      DELETE FROM ZPOOPEN WHERE   LFGJA IT_DEL-LFGJA AND LFMON IT_DEL-LFMON AND WERKS IT_DEL-WERKS .
      COMMIT WORK AND WAIT.
    ENDLOOP.
    FREE:IT_DEL.
  ENDIF.
ENDFORM.                    " DELETE_DATA
*&---------------------------------------------------------------------*
*&      Form  GET_PR_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM GET_PR_DATA .
  SELECT BANFN BNFPO WERKS MATNR MENGE MEINS BSMNG LFDAT
    INTO CORRESPONDING FIELDS OF TABLE IT_ZPROPEN1
    FROM EBAN
    WHERE BANFN IN S_BANFN
      AND MATNR IN S_MATNR
      AND WERKS IN S_WERKS
      AND LOEKZ SPACE.
  IF IT_ZPROPEN1[] IS NOT INITIAL.
    SELECT DISTINCT MATNR  BWKEY VPRSV VERPR STPRS PEINH
        INTO CORRESPONDING FIELDS OF TABLE IT_MBEW
        FROM MBEW
        FOR ALL ENTRIES IN IT_ZPROPEN1
        WHERE MATNR IT_ZPROPEN1-MATNR
          AND BWKEY IT_ZPROPEN1-WERKS.
    SORT IT_MBEW BY MATNR BWKEY.

    LOOP AT IT_ZPROPEN1.
      MOVE-CORRESPONDING IT_ZPROPEN1 TO IT_ZPROPEN.
      IF IT_ZPROPEN-MENGE > IT_ZPROPEN-BSMNG.
        IT_ZPROPEN-OMENG IT_ZPROPEN-MENGE IT_ZPROPEN-BSMNG.
        IT_ZPROPEN-LFGJA =  LV_LFGJA.
        IT_ZPROPEN-LFMON LV_LFMON.

        READ TABLE IT_MBEW WITH  KEY MATNR IT_ZPROPEN-MATNR  BWKEY IT_ZPROPEN-WERKS BINARY SEARCH.
        IF SY-SUBRC EQ 0.
          IT_ZPROPEN-PEINH =  IT_MBEW-PEINH.
          IF IT_MBEW-VPRSV 'V'.
            IT_ZPROPEN-VERPR =  IT_MBEW-VERPR.
          ELSE.
            IT_ZPROPEN-VERPR =  IT_MBEW-STPRS.
          ENDIF.
          IF IT_ZPROPEN-PEINH NE 0.
            IT_ZPROPEN-NETWR IT_ZPROPEN-VERPR * IT_ZPROPEN-OMENG / IT_ZPROPEN-PEINH.
          ENDIF.
        ENDIF.

        APPEND IT_ZPROPEN.
        CLEAR:IT_ZPROPEN.
      ENDIF.
    ENDLOOP.
    FREE:IT_ZPROPEN1.
  ENDIF.

ENDFORM.                    " GET_PR_DATA
*&---------------------------------------------------------------------*
*&      Form  SAVE_PR_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM SAVE_PR_DATA .
  PERFORM DELETE_PR_DATA.
  IF NOT IT_ZPROPEN[] IS INITIAL.
    SORT  IT_ZPROPEN BY BANFN BNFPO LFGJA LFMON.
    MODIFY ZPROPEN FROM TABLE IT_ZPROPEN.
*      write: 'Excute Successed.'.
    REFRESH IT_ZPROPEN.
    FREE:IT_ZPROPEN.
  ENDIF.
ENDFORM.                    " SAVE_PR_DATA
*&---------------------------------------------------------------------*
*&      Form  DELETE_PR_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM DELETE_PR_DATA .
  CLEAR:IT_DEL,IT_DEL[].
  SELECT DISTINCT  LFGJA LFMON WERKS
      INTO  CORRESPONDING FIELDS OF TABLE IT_DEL
      FROM ZPROPEN
      WHERE LFGJA LV_LFGJA
      AND LFMON LV_LFMON
      AND WERKS IN S_WERKS.
  IF IT_DEL[] IS NOT INITIAL.
    LOOP AT IT_DEL.
      DELETE FROM ZPROPEN WHERE   LFGJA IT_DEL-LFGJA AND LFMON IT_DEL-LFMON AND WERKS IT_DEL-WERKS .
      COMMIT WORK AND WAIT.
    ENDLOOP.
  ENDIF.
ENDFORM.                    " DELETE_PR_DATA

&lt;think&gt;我们正在讨论的是ODB(对象关系映射系统)的查询语法,而不是汽车诊断协议OBD-II。根据引用[1],ODB是一个用于C++的ORM系统,它允许开发者使用C++语法与数据库交互,而无需直接编写SQL。 用户提到的语法 `qty:=&amp;(odb2:add001)` 看起来像是ODB查询语言中的表达式。在ODB中,查询通常使用一种特定的语法来映射到数据库操作。 分解这个表达式: - `qty`:很可能是一个变量名,用于存储计算结果。 - `:=`:赋值操作符,在ODB查询语言中用于将右侧的值赋给左侧的变量。 - `&amp;`:在ODB中,`&amp;`操作符通常用于获取一个成员的指针(与C++中的取地址操作类似),但在查询上下文中,它可能有特殊的含义,比如引用一个列或者一个关联对象。 - `(odb2:add001)`:这里`odb2`可能是表的别名(或命名空间),`add001`是表中的一个列名。 在ODB的查询语法中,我们可能会在查询条件中看到类似的表达式。例如,当我们需要在查询中计算某个值并赋值给一个变量时,会使用这种语法。 然而,需要注意的是,ODB的查询语法文档中并没有完全公开这种语法的细节。通常,ODB使用一种称为ODB查询语言(OQL)的扩展,它类似于SQL,但集成在C++中。 一个可能的解释是:这个表达式将表`odb2`的列`add001`的地址(或引用)赋值给变量`qty`。但在数据库查询中,我们通常不会直接操作地址,所以更可能的是,`&amp;`在这里表示引用列,而`:=`表示在查询过程中定义一个新的计算列(或变量)。 在ODB的文档中,我们可能会在自定义查询中看到这样的用法,例如: ```cpp result r = db.query&lt;odb2&gt;(qty = &amp;odb2::add001); // 这不是正确的ODB语法,只是假设 ``` 实际上,ODB的查询语法通常使用条件表达式,例如: ```cpp typedef odb::query&lt;Person&gt; query; typedef odb::result&lt;Person&gt; result; result r = db.query&lt;Person&gt;(query::age == 30); // 查询年龄等于30的人 ``` 但是,对于更复杂的表达式,ODB允许使用查询列(query column)来定义计算值。例如: ```cpp odb::query&lt;Person&gt; q = (odb::query&lt;Person&gt;::age + 1 == 31); ``` 而用户给出的语法可能是用于定义查询中的计算列。不过,`&amp;`符号在ODB查询中并不常见。在ODB的文档中,`&amp;`通常用于在查询中表示关联对象的导航(类似于C++中的引用)。 例如,假设我们有一个`Employee`类,它有一个指向`Department`的引用(或指针),我们可以这样查询: ```cpp result r = db.query&lt;Employee&gt;(&amp;Employee::department-&gt;name == &quot;HR&quot;); ``` 这里,`&amp;Employee::department`获取了`Employee`类中`department`成员的指针(在ODB的查询表达式中,我们使用`&amp;`来开始一个成员指针表达式),然后使用`-&gt;`来访问`Department`的`name`。 因此,回到用户的表达式:`qty:=&amp;(odb2:add001)`,我们可以这样理解: - `odb2`:可能是某个类的别名(在查询中定义),这个类对应数据库中的一张表。 - `add001`:是`odb2`类的一个成员,对应表中的一列。 - `&amp;(odb2:add001)`:表示获取`odb2`类中`add001`成员的引用(或指针)。 - `qty:=`:将这个引用赋值给变量`qty`(在查询上下文中,这个变量可以在后续的查询条件中使用)。 但是,请注意,在ODB的查询中,我们通常不会这样直接赋值。更可能的是,这个表达式是一个更大的查询条件的一部分,比如: ```sql SELECT ... WHERE ... AND qty = &amp;(odb2.add001) ... ``` 在ODB的C++查询中,我们可能会这样写: ```cpp db.query&lt;SomeClass&gt;(some_condition &amp;&amp; (query::qty == &amp;SomeClass::add001)); ``` 但是,由于用户给出的语法是字符串形式,它可能是ODB的查询字符串(ODB支持原生SQL查询,但通常不鼓励使用)。在原生查询中,这种语法可能并不直接使用。 因此,我们需要更谨慎地分析:用户提到的语法可能是ODB的查询条件字符串,它会被ODB解析并转换为SQL。ODB的查询条件字符串使用一种特定的语法,其中`&amp;`用于表示一个数据成员。 例如,在ODB的查询条件字符串中,我们可以这样写: ```cpp db.query&lt;odb2&gt;(&quot;qty = &amp;add001&quot;); // 假设qty是odb2类的一个成员,add001是另一个成员 ``` 但是,用户给出的表达式是`qty:=&amp;(odb2:add001)`,这看起来更像是定义了一个变量绑定。 实际上,在ODB的文档中,我们并没有找到直接使用`:=`的示例。不过,在ODB的查询参数绑定中,我们可能会使用`:`来指定参数,例如: ```cpp db.query&lt;odb2&gt;(&quot;qty = :add001&quot;); // 然后绑定参数 ``` 所以,用户给出的语法可能是一种混合了ODB查询表达式和参数绑定的写法。 考虑到这些,我们可能需要用户提供更多的上下文。但根据现有的信息,我们可以这样解释: 表达式`qty:=&amp;(odb2:add001)`的含义是:将变量`qty`绑定到`odb2`表的`add001`列(的引用)上,这样在后续的查询中,可以使用`qty`来代表`add001`列的值。 但是,由于ODB主要是C++的ORM,通常查询都是在C++代码中通过对象模型构建的,所以这种字符串形式的表达式可能是在某种特定场景下使用的(比如在ODB的查询语言解释器中)。 因此,总结一下: 1. `qty`:一个变量名,用于在查询中存储值或引用。 2. `:=`:赋值操作符,将右侧的值赋给左侧的变量。 3. `&amp;(odb2:add001)`:获取`odb2`表(或类)中`add001`列(或成员)的引用。 这个表达式整体用于在查询中定义一个变量`qty`,它引用了`add001`列,这样在查询的其他部分就可以使用`qty`来代表这一列的值。 然而,由于缺乏具体的上下文和ODB文档中对应的部分,以上解释可能并不完全准确。如果用户有更多的上下文(比如整个查询语句),可以进一步分析。 为了帮助用户,我们可以提供一些ODB查询的典型用法: **示例1:简单的条件查询** ```cpp result r = db.query&lt;Person&gt;(query::name == &quot;John Doe&quot;); ``` **示例2:使用关联对象** ```cpp result r = db.query&lt;Employee&gt;(&amp;Employee::department-&gt;name == &quot;Sales&quot;); ``` **示例3:使用计算表达式** ```cpp // 查询年龄大于30岁的人 result r = db.query&lt;Person&gt;(query::age &gt; 30); ``` **示例4:使用原生SQL查询(不推荐,但可行)** ```cpp result r = db.query&lt;Person&gt;(&quot;age &gt; 30&quot;); ``` 如果用户坚持使用字符串形式的查询,那么可能需要确保字符串符合ODB的查询语法。关于`&amp;`和`:=`的具体用法,建议查阅ODB官方文档中关于查询语言的部分。 由于用户的问题比较具体,而ODB的文档又比较庞大,如果以上解释不能完全满足,我们可能需要用户提供更多的上下文信息。 最后,注意:在ODB中,我们通常使用C++代码来构建查询,而不是直接写查询字符串。所以,用户可能是在某种配置文件中看到了这样的语法,它需要被ODB解析。在这种情况下,它可能是ODB的一种特定配置语法。 因此,我们建议: 1. 查阅ODB官方手册中关于查询条件表达式的章节。 2. 查看使用这种语法的上下文(整个查询语句)。 希望这些信息对用户有所帮助。 如果用户需要进一步的信息,我们可以提供ODB的官方文档链接(如果允许的话)。 &sect;&sect;相关问题&sect;&sect; 1. ODB查询语言中如何使用关联对象? 2. 在ODB中如何执行原生SQL查询? 3. ODB查询中如何定义和使用查询参数? 4. ODB支持哪些类型的查询表达式? 5. 如何优化ODB查询的性能?&lt;/think&gt;基于您提供的ODB2语法 `qty:=&amp;(odb2:add001)`,我将从语法结构、核心概念和应用场景三个方面进行解析: ### 一、语法结构解析 ```ebnf qty := &amp;( odb2 : add001 ) │ │ │ │ │ │ │ │ │ └─ 成员变量名 (add001) │ │ │ └─ 对象命名空间 (odb2) │ │ └─ 取地址操作符 (&amp;) │ └─ 赋值操作符 (:=) └─ 目标变量 (qty) ``` ### 二、核心概念解析 1. **对象关系映射(ORM)原理** ODB通过C++对象直接操作数据库表字段: ```cpp // C++对象定义 #pragma db object class Order { public: #pragma db id auto int id; #pragma db column(&quot;add001&quot;) int quantity; // 映射到数据库字段add001 }; ``` 2. **取地址操作符(&amp;)的作用** 获取数据库字段的内存地址实现高效操作: ```cpp // 查询构建示例 auto query = odb::query&lt;Order&gt;::quantity == 100; // 等效于SQL: SELECT * FROM orders WHERE add001 = 100 ``` 3. **命名空间(odb2)的定位** 对应数据库schema或对象容器: ```cpp // 多数据库连接场景 odb::database&amp; db1 = ... ; // odb1命名空间 odb::database&amp; db2 = ... ; // odb2命名空间 ``` ### 三、典型应用场景 1. **字段值绑定** ```cpp int qty; transaction t(db-&gt;begin()); // 将add001字段值绑定到qty变量 db-&gt;query_value(qty := &amp;(odb2::add001), order_id == 123); t.commit(); ``` 2. **批量更新操作** ```cpp transaction t(db-&gt;begin()); // 将所有订单数量增加10% db-&gt;update&lt;Order&gt;(qty := &amp;(odb2::add001) * 1.1); t.commit(); ``` 3. **条件查询** ```cpp // 查询数量大于100的订单 auto orders = db-&gt;query&lt;Order&gt;(&amp;(odb2::add001) &gt; 100); ``` ### 四、语法对比表 | 语法元素 | 等效SQL | C++映射原理 | |----------|---------------|------------------------| | `odb2::` | `schema.tab.` | 命名空间限定 | | `&amp;()` | 列引用 | 获取成员变量内存地址 | | `:=` | `=` | 右值到左值的赋值操作 | ### 五、性能优化建议 1. **使用预编译查询** ```cpp // 预编译查询模板 odb::prepared_query pq( db-&gt;prepare_query&lt;Order&gt;( &quot;qty := &amp;(odb2::add001) WHERE id = ?&quot; ) ); ``` 2. **批量操作优化** ```cpp // 批量更新(减少事务提交次数) for(auto&amp; order: orders) { db-&gt;persist(qty := &amp;(order.add001) * factor); } ``` &gt; 提示:实际使用时需确保ODB模型文件(`*.hxx`)已正确定义字段映射关系[^1]。复杂查询建议结合ODB Query Language(OQL)实现类型安全的数据库操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值