标准:ME14单条信息记录查询(在有效期内更改的才会被记录)
查询结果如下:
用户要求的是批量查询净价,从结果中我们看到净价的字段名、涉及到表、日期、文档编号等信息。既然有变更表的内容,那就会用到CDHDR和CDPOS这两张记录表。
比对发现,其实就是这两张表的记录数据。通过文档对象、对象价值、编号、表名、字段名等信息进行提取即可。
接下来批量查询就简单了,程式只需要按提取的数据进行筛选处理。
按照用户的需求,条件设定如下:
报表执行的结果:
完整代码如下:
*&---------------------------------------------------------------------*
*& Report SAMPLE.
*&
*&---------------------------------------------------------------------*
*&Author:LIU YANG
*&Create date:2022.07.21
*&Desc.:采购信息记录价格修改日志查询
*&---------------------------------------------------------------------*
REPORT SAMPLE.
TABLES:CDHDR,EINA,EINE,A018,A017.
DATA:GT_CDHDR LIKE CDHDR OCCURS 0 WITH HEADER LINE,
GT_CDPOS LIKE CDPOS OCCURS 0 WITH HEADER LINE.
DATA:BEGIN OF GT_EINA OCCURS 0,
INFNR LIKE EINA-INFNR,
MATNR LIKE EINA-MATNR,
LIFNR LIKE EINA-LIFNR,
OBJECTID LIKE CDHDR-OBJECTID,
EKORG LIKE EINE-EKORG,
WERKS LIKE EINE-WERKS,
END OF GT_EINA.
DATA BLEN(2) TYPE N.
DATA:BEGIN OF GT_OUT OCCURS 0,
INFNR LIKE EINA-INFNR, "信息记录编号
MATNR LIKE EINA-MATNR, "物料号码
MAKTX LIKE MAKT-MAKTX, "物料描述
LIFNR LIKE EINA-LIFNR, "供应商号码
NAME1 LIKE LFA1-NAME1, "供应商名称
VALUE_NEW LIKE CDPOS-VALUE_NEW, "新值
VALUE_OLD LIKE CDPOS-VALUE_OLD, "旧值
PEINH LIKE EINE-PEINH, "价格单位
WAERS LIKE EINE-WAERS, "币别
MWSKZ LIKE EINE-MWSKZ, "税码
USERNAME LIKE CDHDR-USERNAME, "修改人
UDATE LIKE CDHDR-UDATE, "修改日期
UTIME LIKE CDHDR-UTIME, "修改时间
ZRATE(10) TYPE C, "采购价差异比率%
OBJECTCLAS LIKE CDHDR-OBJECTCLAS,
OBJECTID LIKE CDHDR-OBJECTID,
CHANGENR LIKE CDHDR-CHANGENR,
ESOKZ LIKE EINE-ESOKZ,
MATKL LIKE MARA-MATKL,
EKORG LIKE EINE-EKORG,
WERKS LIKE CDPOS-TABKEY,
KNUMH LIKE KONH-KNUMH,
ZFRA1(10) TYPE C,
ZZOA1(10) TYPE C,
ZZOD1(10) TYPE C,
END OF GT_OUT.
DATA : BEGIN OF ITAC OCCURS 0 ,
INFNR LIKE EINA-INFNR,
EKORG LIKE EINE-EKORG,
WERKS LIKE EINE-WERKS,
LIFNR LIKE EINA-LIFNR,
NAME1 LIKE LFA1-NAME1, "供应商名称
MATNR LIKE EINA-MATNR,
MAKTG LIKE MAKT-MAKTG, "物料描述
IDNLF LIKE EINA-IDNLF,
TXZ01 LIKE EINA-TXZ01,
VERKF LIKE EINA-VERKF,
ESOKZ LIKE EINE-ESOKZ,
KZABS LIKE EINE-KZABS,
APLFZ LIKE EINE-APLFZ,
EKGRP LIKE EINE-EKGRP,
WEBRE LIKE EINE-WEBRE,
MWSKZ LIKE EINE-MWSKZ,
XERSN LIKE EINE-XERSN,
MATKL LIKE EINA-MATKL,
SORTL LIKE EINA-SORTL,
DATAB LIKE A017-DATAB,
DATBI LIKE A017-DATBI,
KMEIN LIKE KONP-KMEIN,
KPEIN LIKE KONP-KPEIN,
KONWA LIKE KONP-KONWA,
KBETR LIKE KONP-KBETR,
KSCHL LIKE KONP-KSCHL,
KBETR1 TYPE P DECIMALS 2 , " 有效价格
KNUMH LIKE A017-KNUMH,
END OF ITAC.
DATA : V_FLAG(1) ,
ZFRA1 TYPE KONP-KBETR,
ZZOA1 TYPE KONP-KBETR,
ZZOD1 TYPE KONP-KBETR.
DATA:GS_LAYOUT TYPE SLIS_LAYOUT_ALV,
GT_FCAT TYPE SLIS_T_FIELDCAT_ALV WITH HEADER LINE,
GT_SORT TYPE SLIS_T_SORTINFO_ALV WITH HEADER LINE.
DATA:E_DATE LIKE SY-DATUM.
DATA AI18 LIKE TABLE OF A018 WITH HEADER LINE.
DEFINE MCR_BUILD_FIELDCAT.
gt_fcat-fieldname = &1.
gt_fcat-seltext_l = &2.
gt_fcat-seltext_m = &2.
gt_fcat-seltext_s = &2.
gt_fcat-ddictxt = 'L'.
gt_fcat-inttype = &3.
gt_fcat-intlen = &4.
if &1 = 'INFNR' or &1 = 'LIFNR' or &1 = 'MATNR'.
GT_FCAT-NO_ZERO = 'X'.
ENDIF.
APPEND gt_fcat.
CLEAR gt_fcat.
END-OF-DEFINITION.
CONSTANTS:C_OBJECTCLAS LIKE CDHDR-OBJECTCLAS VALUE 'INFOSATZ'.
***selection screen define
SELECTION-SCREEN BEGIN OF BLOCK BLC WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS:
S_EKORG FOR EINE-EKORG OBLIGATORY ,
" S_WERKS FOR EINE-WERKS,
S_MATNR FOR EINA-MATNR,
S_LIFNR FOR EINA-LIFNR,
S_INFNR FOR EINA-INFNR,
S_UDATE FOR CDHDR-UDATE OBLIGATORY.
SELECTION-SCREEN END OF BLOCK BLC.
INITIALIZATION.
CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'
EXPORTING
I_DATE = SY-DATUM
IMPORTING
E_DATE = E_DATE.
S_UDATE-SIGN = 'I'.
S_UDATE-OPTION ='BT'.
S_UDATE-LOW = SY-DATUM(6) && '01'.
S_UDATE-HIGH = E_DATE.
APPEND S_UDATE.
CLEAR S_UDATE.
START-OF-SELECTION.
PERFORM FRM_GET_DATA.
PERFORM FRM_GET_FIELDCAT.
PERFORM FRM_GET_SORT.
PERFORM FRM_OUTPUT_DATA.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM FRM_GET_DATA .
DATA:LV_PERCENT TYPE P DECIMALS 2.
DATA:N_PEINH LIKE EINE-PEINH,
N_INDEX LIKE SY-TABIX.
IF S_MATNR[] IS NOT INITIAL OR S_LIFNR[] IS NOT INITIAL OR S_INFNR[] IS NOT INITIAL .
SELECT A~INFNR A~MATNR A~LIFNR AS OBJECTID
INTO CORRESPONDING FIELDS OF TABLE GT_EINA
FROM EINA AS A
WHERE A~MATNR IN S_MATNR
AND A~LIFNR IN S_LIFNR
AND A~INFNR IN S_INFNR.
IF GT_EINA[] IS NOT INITIAL.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE GT_CDHDR
FROM CDHDR
FOR ALL ENTRIES IN GT_EINA
WHERE OBJECTCLAS = C_OBJECTCLAS
AND OBJECTID = GT_EINA-OBJECTID
AND UDATE IN S_UDATE.
ENDIF.
ELSE.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE GT_CDHDR
FROM CDHDR
WHERE OBJECTCLAS = C_OBJECTCLAS
AND UDATE IN S_UDATE.
IF GT_CDHDR[] IS NOT INITIAL.
SELECT INFNR MATNR LIFNR INFNR AS OBJECTID
INTO CORRESPONDING FIELDS OF TABLE GT_EINA
FROM EINA
FOR ALL ENTRIES IN GT_CDHDR
WHERE INFNR = GT_CDHDR-OBJECTID(10).
ENDIF.
ENDIF.
IF GT_CDHDR[] IS NOT INITIAL.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE GT_CDPOS
FROM CDPOS
FOR ALL ENTRIES IN GT_CDHDR
WHERE OBJECTCLAS = GT_CDHDR-OBJECTCLAS
AND OBJECTID = GT_CDHDR-OBJECTID
AND CHANGENR = GT_CDHDR-CHANGENR
AND TABNAME = 'EINE'
AND ( FNAME = 'NETPR' OR FNAME = 'PEINH' ).
ENDIF.
SORT GT_CDHDR BY OBJECTCLAS OBJECTID CHANGENR.
SORT GT_EINA BY INFNR.
LOOP AT GT_CDPOS WHERE FNAME = 'NETPR'.
MOVE-CORRESPONDING GT_CDPOS TO GT_OUT.
READ TABLE GT_CDHDR WITH KEY OBJECTCLAS = GT_CDPOS-OBJECTCLAS OBJECTID = GT_CDPOS-OBJECTID CHANGENR = GT_CDPOS-CHANGENR BINARY SEARCH.
IF SY-SUBRC = 0.
MOVE-CORRESPONDING GT_CDHDR TO GT_OUT.
ENDIF.
READ TABLE GT_EINA WITH KEY INFNR = GT_CDPOS-OBJECTID(10) BINARY SEARCH.
IF SY-SUBRC = 0.
MOVE-CORRESPONDING GT_EINA TO GT_OUT.
ENDIF.
SELECT SINGLE MAKTX INTO GT_OUT-MAKTX FROM MAKT WHERE MATNR = GT_OUT-MATNR AND SPRAS = SY-LANGU.
SELECT SINGLE NAME1 INTO GT_OUT-NAME1 FROM LFA1 WHERE LIFNR = GT_OUT-LIFNR.
SELECT SINGLE ESOKZ EKORG INTO (GT_OUT-ESOKZ,GT_OUT-EKORG ) FROM EINE WHERE INFNR = GT_OUT-INFNR .
SELECT SINGLE MATKL INTO GT_OUT-MATKL FROM MARA WHERE MATNR = GT_OUT-MATNR .
DESCRIBE FIELD GT_CDPOS-TABKEY LENGTH BLEN IN BYTE MODE.
SELECT SINGLE PEINH WAERS MWSKZ INTO (GT_OUT-PEINH,GT_OUT-WAERS,GT_OUT-MWSKZ) FROM EINE
WHERE INFNR = GT_OUT-INFNR AND EKORG IN S_EKORG .
GT_OUT-WERKS = GT_CDPOS-TABKEY+18(4). "7005300081525CA000CA00
APPEND GT_OUT.
CLEAR GT_OUT.
ENDLOOP.
SORT GT_OUT BY OBJECTCLAS OBJECTID UDATE DESCENDING UTIME DESCENDING.
READ TABLE GT_OUT INDEX 1.
LOOP AT GT_OUT.
N_INDEX = SY-TABIX.
N_PEINH = GT_OUT-PEINH.
READ TABLE GT_CDPOS WITH KEY FNAME = 'PEINH' OBJECTCLAS = GT_OUT-OBJECTCLAS OBJECTID = GT_OUT-OBJECTID CHANGENR = GT_OUT-CHANGENR.
IF SY-SUBRC = 0.
N_PEINH = GT_CDPOS-VALUE_OLD.
GT_OUT-VALUE_OLD = GT_OUT-VALUE_OLD / GT_CDPOS-VALUE_OLD * GT_OUT-PEINH.
GT_OUT-VALUE_NEW = GT_OUT-VALUE_NEW / GT_CDPOS-VALUE_NEW * GT_OUT-PEINH.
ELSE.
IF N_PEINH NE 0.
GT_OUT-VALUE_NEW = GT_OUT-VALUE_NEW / N_PEINH * GT_OUT-PEINH.
GT_OUT-VALUE_OLD = GT_OUT-VALUE_OLD / N_PEINH * GT_OUT-PEINH.
ENDIF.
ENDIF.
***比例
CLEAR LV_PERCENT.
CONDENSE:GT_OUT-VALUE_NEW,GT_OUT-VALUE_OLD NO-GAPS.
LV_PERCENT = GT_OUT-VALUE_NEW - GT_OUT-VALUE_OLD .
IF GT_OUT-VALUE_OLD NE 0.
LV_PERCENT = LV_PERCENT / GT_OUT-VALUE_OLD * 100.
ENDIF.
GT_OUT-ZRATE = LV_PERCENT.
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING
VALUE = GT_OUT-ZRATE.
CONCATENATE GT_OUT-ZRATE '%' INTO GT_OUT-ZRATE.
CONDENSE GT_OUT-ZRATE NO-GAPS.
MODIFY GT_OUT INDEX N_INDEX.
ENDLOOP.
LOOP AT GT_OUT.
IF GT_OUT-WERKS EQ SPACE .
SELECT KNUMH INTO GT_OUT-KNUMH FROM A018 " INTO CORRESPONDING FIELDS OF TABLE ai18
WHERE LIFNR = GT_OUT-LIFNR
AND KAPPL = 'M'
AND KSCHL = 'PB00'
AND MATNR = GT_OUT-MATNR
AND EKORG = GT_OUT-EKORG
AND ESOKZ = GT_OUT-ESOKZ
AND ( DATAB <= GT_OUT-UDATE AND DATBI >= GT_OUT-UDATE ).
ENDSELECT.
MODIFY GT_OUT.
CLEAR GT_OUT.
ELSE.
SELECT KNUMH INTO GT_OUT-KNUMH FROM A017 " INTO CORRESPONDING FIELDS OF TABLE ai18
WHERE LIFNR = GT_OUT-LIFNR
AND KAPPL = 'M'
AND KSCHL = 'PB00'
AND MATNR = GT_OUT-MATNR
AND EKORG IN S_EKORG
AND ESOKZ = GT_OUT-ESOKZ
AND WERKS = GT_OUT-WERKS
AND ( DATAB <= GT_OUT-UDATE AND DATBI >= GT_OUT-UDATE ).
ENDSELECT.
MODIFY GT_OUT.
CLEAR GT_OUT.
ENDIF.
ENDLOOP.
LOOP AT GT_OUT.
SELECT * INTO CORRESPONDING FIELDS OF TABLE ITAC
FROM KONP
WHERE KNUMH = GT_OUT-KNUMH
AND KAPPL = 'M'
AND LOEVM_KO <> 'X'.
APPEND ITAC.
LOOP AT ITAC.
IF ITAC-KSCHL = 'FRA1'.
ZFRA1 = ITAC-KBETR / 10.
GT_OUT-ZFRA1 = ZFRA1.
ELSEIF ITAC-KSCHL = 'ZOA1'.
ZZOA1 = ITAC-KBETR / 10.
GT_OUT-ZZOA1 = ZZOA1.
ELSEIF ITAC-KSCHL = 'ZOD1' .
ZZOD1 = ITAC-KBETR / 10.
GT_OUT-ZZOD1 = ZZOD1.
ENDIF.
ENDLOOP.
MODIFY GT_OUT.
CLEAR GT_OUT.
CLEAR : ZFRA1,ZZOA1,ZZOD1.
ENDLOOP.
DELETE GT_OUT WHERE EKORG NOT IN S_EKORG.
SORT GT_OUT BY UDATE.
ENDFORM. " FRM_GET_DATA
*&---------------------------------------------------------------------*
*& Form FRM_GET_FIELDCAT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM FRM_GET_FIELDCAT .
MCR_BUILD_FIELDCAT:
'UDATE' '修改日期' 'D' '8',
'UTIME' '修改时间' 'T' '6',
'INFNR' '信息记录编号' 'C' '10',
'WERKS' '工厂' 'C' '6',
'EKORG' '采购组织' 'C' '10',
'ESOKZ' '分类' 'C' '2',
'MATKL' '物料组' 'C' '10',
'MATNR' '物料号码' 'C' '18',
'MAKTX' '物料描述' 'C' '40',
'LIFNR' '供应商号码' 'C' '10',
'NAME1' '供应商名称' 'C' '35',
'VALUE_OLD' '旧值B' 'C' '30',
'VALUE_NEW' '新值A' 'C' '30',
'ZRATE' '采购价差异比率(A-B)/B' 'C' '10',
'ZFRA1' '运费%' 'C' '10',
'ZZOA1' '关税%' 'C' '10',
'ZZOD1' '特许权使用费%' 'C' '10',
'PEINH' '价格单位' 'I' '5',
'WAERS' '币别' 'C' '5',
'MWSKZ' '税码' 'C' '2',
'USERNAME' '修改人' 'C' '12'.
GS_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
GS_LAYOUT-ZEBRA = 'X'.
ENDFORM. " FRM_GET_FIELDCAT
*&---------------------------------------------------------------------*
*& Form FRM_GET_SORT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM FRM_GET_SORT .
REFRESH GT_SORT.
GT_SORT-FIELDNAME = 'UDATE'.
GT_SORT-UP = 'X'.
APPEND GT_SORT.
CLEAR GT_SORT.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_OUTPUT_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM FRM_OUTPUT_DATA .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
IS_LAYOUT = GS_LAYOUT
IT_FIELDCAT = GT_FCAT[]
TABLES
T_OUTTAB = GT_OUT[]
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
ENDFORM. " FRM_OUTPUT_DATA