通过二次开发在SAP R/3中实现库存日清功能
作者:冯强
大型电子制造企业大多采用按生产计划配送物料的方式,配送中心通过产品物料清单(BOM)、计划、实时库存进行MRP运算的结果,按生产线(成本中心)齐套物料。保管员、配套员的日常工作非常饱满,每个工作日后的盘存(日清)就显得非常重要,库存准确与否将对下一个工作日配套质量产生重要的影响。SAP R/3有标准的盘点流程,但在实际操作中应用于日清盘存过于繁琐,它更适用于财务月度(年度)的盘存。
日清盘存由于只能在日常收货、配发工作完成后进行,所以对时间的要求很严格,应该做到简洁和高效。按照常规的盘存要求,应对库存地所有物料进行清点,但这在日清盘存中是绝对做不到的。我们采取的日清盘存方式,是根据保管员当日的收货、发货、转储物料凭证,对发生过库存变更的物料进行统计,打印出日清盘存表供保管员清点实物。由于当日发生过库存变更的物料占库存物料种类的比例一般不会太高,这样在大幅减轻日清盘存工作量的情况下,可以尽可能的提高盘存的精确度。
程序清单如下,用ABAP开发,在SAP R/3 4.5D上测试通过,关于程序说明见程序注解。
PROGRAM ZMTHD NO STANDARD PAGE HEADING LINE-SIZE 164 MESSAGE-ID Z1.
*$-------------------------------------------------------------------
*& 查询并导出当日有收发的保管员库存清单 Author: Frank Feng(FQ)
*& (不分批次) 2003.10.15
*& last modify: 2004.06.15
*$-------------------------------------------------------------------
TABLES:MSEG,MKPF,MARD,MARA,MAKT,T001W.
*MSEG:物料凭证表,收货、发货、转储凭证均保存在这个表中
*MKPF:物料凭证抬头表,凭证日期是保存在这个表中,根据日期汇集物料凭证,
* 然后根据物料凭证在MSEG中获得物料凭证明细
*MARD:库存地物料库存
*MARA:常规物料数据,包括物料代码、计量单位、旧物料号等
*MAKT:物料描述
*T001W:工厂部门数据,用于权限检查
* 定义数据结构
TYPES: BEGIN OF SFKC_TYPE,
B_MBLNR LIKE MSEG-MBLNR, "物料凭证编号
B_WERKS LIKE MSEG-WERKS, "工厂
B_LGORT LIKE MSEG-LGORT, "库存地
B_MATNR LIKE MSEG-MATNR, "物料代码
B_BISMT LIKE MARA-BISMT, "旧物料号
B_MAKTX LIKE MAKT-MAKTX, "物料描述
B_MEINS(4), "基本计量单位
B_LABST LIKE MARD-LABST, "非限制库存
B_INSME LIKE MARD-INSME, "质检库存
B_SPEME LIKE MARD-SPEME, "冻结库存
B_LGPBE LIKE MARD-LGPBE, "我们是用“仓位”记录保管员姓名
END OF SFKC_TYPE.
TYPES: BEGIN OF LIST_TYPE,
B_WERKS LIKE MSEG-WERKS, "工厂
B_LGORT LIKE MSEG-LGORT, "库存地
B_MATNR LIKE MSEG-MATNR, "物料代码
B_BISMT LIKE MARA-BISMT, "旧物料号
B_MAKTX LIKE MAKT-MAKTX, "物料描述
B_MEINS(4), "基本计量单位
B_LABST LIKE MARD-LABST, "非限制库存
B_INSME LIKE MARD-INSME, "质检库存
B_SPEME LIKE MARD-SPEME, "冻结库存
B_LGPBE LIKE MARD-LGPBE, "仓位-->保管员
END OF LIST_TYPE.
DATA: FQ_ITAB TYPE STANDARD TABLE OF SFKC_TYPE WITH HEADER LINE,
LI_ITAB TYPE STANDARD TABLE OF LIST_TYPE WITH HEADER LINE.
DATA: BEGIN OF IWERKS OCCURS 0,
WERKS LIKE T001W-WERKS,
END OF IWERKS.
DATA: TOTALLINE(5) TYPE N VALUE 0. "日清表的总行数(记录数)
*&------------------------------------------------------------------
*日清表条件输入(我们默认工厂是2010,可以根据实际需求更改)
SELECTION-SCREEN BEGIN OF BLOCK FQ WITH FRAME TITLE TEXT-001.
SELECTION-SCREEN SKIP 1.
SELECT-OPTIONS: V_WERKS FOR MSEG-WERKS MEMORY ID WRK NO INTERVALS
OBLIGATORY DEFAULT '2010', "工厂
V_LGORT FOR MSEG-LGORT MEMORY ID LAG, "库存地
V_LGPBE FOR MARD-LGPBE, "仓位-->保管员
JZ_DATE FOR MKPF-BUDAT DEFAULT SY-DATUM TO SY-DATUM.
"记帐日期
PARAMETERS: V_MJAHR(4) DEFAULT SY-DATUM(4).
SELECTION-SCREEN END OF BLOCK FQ.
*&-------------------------------------------------------------------
INCLUDE .
START-OF-SELECTION.
* 根权限对象ZAUTHOR进行权限检查,如不要求,可以去除
SELECT WERKS FROM T001W INTO TABLE IWERKS WHERE WERKS IN V_WERKS.
LOOP AT IWERKS.
AUTHORITY-CHECK OBJECT 'ZAUTHOR'
ID 'ZQQ_WERKS' FIELD IWERKS-WERKS.
IF SY-SUBRC NE 0.
MESSAGE A722 WITH IWERKS-WERKS.
ENDIF.
ENDLOOP.
CLEAR T001W.
CLEAR IWERKS.
*根据记账日期区间汇集相关物料凭证
SELECT * FROM MKPF
WHERE MJAHR = V_MJAHR AND BUDAT IN JZ_DATE.
IF SY-SUBRC = 0.
FQ_ITAB-B_MBLNR = MKPF-MBLNR.
APPEND FQ_ITAB.
ENDIF.
ENDSELECT.
CLEAR MKPF.
LOOP AT FQ_ITAB.
SELECT * FROM MSEG WHERE MBLNR = FQ_ITAB-B_MBLNR AND "more lines
MJAHR = SY-DATUM(4).
IF SY-SUBRC EQ 0.
LI_ITAB-B_WERKS = MSEG-WERKS.
LI_ITAB-B_LGORT = MSEG-LGORT.
LI_ITAB-B_MATNR = MSEG-MATNR.
APPEND LI_ITAB.
ENDIF.
ENDSELECT.
ENDLOOP.
CLEAR FQ_ITAB.
CLEAR FQ_ITAB[].
CLEAR MSEG.
*删除不符的凭证明细
DELETE LI_ITAB WHERE NOT ( B_WERKS IN V_WERKS AND B_LGORT IN V_LGORT )
OR B_WERKS IS INITIAL OR B_LGORT IS INITIAL.
SORT LI_ITAB BY B_WERKS B_LGORT B_MATNR.
*压缩内表,保证按工厂、库存地、物料号关键字记录唯一
DELETE ADJACENT DUPLICATES FROM LI_ITAB
COMPARING B_WERKS B_LGORT B_MATNR.
CONDENSE TOTALLINE.
* 遍历汇集的工厂库存地物料库存,写入表中
LOOP AT LI_ITAB.
SELECT * FROM MARD WHERE WERKS = LI_ITAB-B_WERKS AND
LGORT = LI_ITAB-B_LGORT AND
MATNR = LI_ITAB-B_MATNR.
IF SY-SUBRC EQ 0 AND MARD-LVORM IS INITIAL.
LI_ITAB-B_LABST = MARD-LABST.
LI_ITAB-B_INSME = MARD-INSME.
LI_ITAB-B_SPEME = MARD-SPEME.
LI_ITAB-B_LGPBE = MARD-LGPBE.
ENDIF.
ENDSELECT.
SELECT * FROM MARA WHERE MATNR = LI_ITAB-B_MATNR.
IF SY-SUBRC = 0.
LI_ITAB-B_BISMT = MARA-BISMT.
LI_ITAB-B_MEINS = MARA-MEINS.
ENDIF.
ENDSELECT.
SELECT * FROM MAKT WHERE MATNR = LI_ITAB-B_MATNR
AND SPRAS = SY-LANGU.
IF SY-SUBRC = 0.
LI_ITAB-B_MAKTX = MAKT-MAKTX.
ENDIF.
ENDSELECT.
MODIFY LI_ITAB.
ENDLOOP.
IF NOT V_LGPBE IS INITIAL.
DELETE LI_ITAB WHERE NOT ( B_LGPBE IN V_LGPBE ).
ENDIF.
CLEAR MARD.
CLEAR MARA.
CLEAR MAKT.
LOOP AT LI_ITAB.
TOTALLINE = TOTALLINE + 1.
ENDLOOP.
END-OF-SELECTION.
IF TOTALLINE EQ 0.
WRITE: / '没有满足选定条件的物料' COLOR 3.
ELSE.
SORT LI_ITAB BY B_WERKS B_LGORT B_LGPBE B_MATNR.
WRITE: /3 ICON_GREEN_LIGHT,'程序运行成功,共',
TOTALLINE,'项'.
PERFORM LISTOUT. "执行日清表写屏程序
ENDIF.
START-OF-SELECTION.
SET PF-STATUS 'LIST'.
AT USER-COMMAND.
CASE SY-UCOMM.
WHEN 'DOWNLOAD'.
PERFORM DOWNLOAD. "下载日清表格到文本
WHEN 'TOXLS'.
PERFORM TOEXCEL. "导出日清表格到Excel
ENDCASE.
END-OF-SELECTION.
*&--------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& Form LISTOUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 在屏幕上写日清表
FORM LISTOUT.
SET LEFT SCROLL-BOUNDARY COLUMN 33.
ULINE 0(162).
WRITE:/73 '保管员库存日清核对表' .
WRITE:/.
ULINE 1(162).
WRITE: AT /1 SY-VLINE, AT 2 '工厂',
6 SY-VLINE, 7 '库存地',
13 SY-VLINE, 14 '物料代码',
32 SY-VLINE, 33 '旧物料号',
51 SY-VLINE, 52 '物料描述',
92 SY-VLINE, 93 '单位',
97 SY-VLINE, 98 '非限制库存',
115 SY-VLINE, 116 '质检库存',
133 SY-VLINE, 134 '冻结库存',
151 SY-VLINE, 152 '保管员',162 SY-VLINE.
ULINE 0(162).
DATA: COLORCH TYPE I VALUE 0.
LOOP AT LI_ITAB.
IF COLORCH EQ 0.
WRITE: /1 SY-VLINE, 2 LI_ITAB-B_WERKS COLOR 1,
6 SY-VLINE, 7 ' ' COLOR 1,8 LI_ITAB-B_LGORT COLOR 1,
12 ' ' COLOR 1,
13 SY-VLINE, 14 LI_ITAB-B_MATNR COLOR 1,
32 SY-VLINE, 33 LI_ITAB-B_BISMT COLOR 1," delete by FQ
51 SY-VLINE, 52 LI_ITAB-B_MAKTX COLOR 1,
92 SY-VLINE, 93 LI_ITAB-B_MEINS COLOR 1,76 ' ' COLOR 1,
97 SY-VLINE, 98 LI_ITAB-B_LABST COLOR 1,
115 SY-VLINE,116 LI_ITAB-B_INSME COLOR 1,
133 SY-VLINE,134 LI_ITAB-B_SPEME COLOR 1,
151 SY-VLINE,152 LI_ITAB-B_LGPBE COLOR 1,162 SY-VLINE.
COLORCH = 1.
ELSE.
WRITE: /1 SY-VLINE, 2 LI_ITAB-B_WERKS COLOR 2,
6 SY-VLINE, 7 ' ' COLOR 2,8 LI_ITAB-B_LGORT COLOR 2,
12 ' ' COLOR 2,
13 SY-VLINE, 14 LI_ITAB-B_MATNR COLOR 2,
32 SY-VLINE, 33 LI_ITAB-B_BISMT COLOR 2,"delete by fq
51 SY-VLINE, 52 LI_ITAB-B_MAKTX COLOR 2,
92 SY-VLINE,93 LI_ITAB-B_MEINS COLOR 2,76 ' ' COLOR 2,
97 SY-VLINE, 98 LI_ITAB-B_LABST COLOR 2,
115 SY-VLINE,116 LI_ITAB-B_INSME COLOR 2,
133 SY-VLINE,134 LI_ITAB-B_SPEME COLOR 2,
151 SY-VLINE,152 LI_ITAB-B_LGPBE COLOR 2,162 SY-VLINE.
COLORCH = 0.
ENDIF.
ENDLOOP.
ULINE 0(162).
ENDFORM. " LISTOUT
*&---------------------------------------------------------------------*
*& Form DOWNLOAD
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
*下载日清表到文本
FORM DOWNLOAD.
DATA: CANCELUSER TYPE C,OUTFILE LIKE RLGRAP-FILENAME.
CALL FUNCTION 'DOWNLOAD'
EXPORTING
FILENAME = 'd:\bgcheck.txt'
FILETYPE = 'DAT'
ITEM = '输出日清表(不分批次)'
MODE = ' '
IMPORTING
ACT_FILENAME = OUTFILE "user out filename
CANCEL = CANCELUSER
TABLES
DATA_TAB = LI_ITAB .
IF SY-SUBRC EQ 0.
IF CANCELUSER EQ SPACE. " not press the X button
MESSAGE S683 WITH OUTFILE.
ENDIF.
ENDIF.
ENDFORM. " DOWNLOAD
*&---------------------------------------------------------------------*
*& Form TOEXCEL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
*导出日清表到Excel
FORM TOEXCEL.
*&---------------------define data for Function!---------------------
DATA: XMPL_HEADER LIKE GXXLT_P-TEXT VALUE 'Fenq Software'.
DATA BEGIN OF XMPLT_O OCCURS 1. " For further explanation, please
INCLUDE STRUCTURE GXXLT_O. " \ refer to report XXLFTEST.
DATA END OF XMPLT_O. " \ This report is similar in
" \ structure to XXLFTEST, but
DATA BEGIN OF XMPLT_P OCCURS 1. " \ avoids any special features in
INCLUDE STRUCTURE GXXLT_P. " \ order to demonstrate the
DATA END OF XMPLT_P. " \ applicability of XXL_SIMPLE_API
" \ in straight-forward situations.
DATA BEGIN OF XMPLT_V OCCURS 1.
INCLUDE STRUCTURE GXXLT_V.
DATA END OF XMPLT_V.
*&------------------------------------define data end!-------------
*$--------------------------set field for report------------------------
XMPLT_V-COL_NO = 1.
XMPLT_V-COL_NAME = '工厂'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 2.
XMPLT_V-COL_NAME = '库存地'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 3.
XMPLT_V-COL_NAME = '物料代码'.
APPEND XMPLT_V.
* when cpzx not use this then delete
XMPLT_V-COL_NO = 4.
XMPLT_V-COL_NAME = '旧物料号'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 5.
XMPLT_V-COL_NAME = '物料描述'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 6.
XMPLT_V-COL_NAME = '计量单位'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 7.
XMPLT_V-COL_NAME = '非限制库存'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 8.
XMPLT_V-COL_NAME = '质检库存'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 9.
XMPLT_V-COL_NAME = '冻结库存'.
APPEND XMPLT_V.
XMPLT_V-COL_NO = 10.
XMPLT_V-COL_NAME = '保管员'.
APPEND XMPLT_V.
*$------------------------------set field for report end!---------------
CALL FUNCTION 'XXL_SIMPLE_API'
EXPORTING
N_KEY_COLS = 1
FILENAME = 'bgcheck'
HEADER = XMPL_HEADER
TABLES
DATA = LI_ITAB
ONLINE_TEXT = XMPLT_O
PRINT_TEXT = XMPLT_P
COL_TEXT = XMPLT_V
EXCEPTIONS
DIM_MISMATCH_DATA = 71
FILE_OPEN_ERROR = 72
FILE_WRITE_ERROR = 73
INV_WINSYS = 74
INV_XXL = 75.
CASE SY-SUBRC.
WHEN 0.
MESSAGE S692.
WHEN 71.
RAISE DIM_MISMATCH_DATA.
WHEN 72.
RAISE FILE_OPEN_ERROR.
WHEN 73.
RAISE FILE_WRITE_ERROR.
WHEN 74.
RAISE INV_WINSYS.
WHEN 75.
RAISE INV_XXL.
ENDCASE.
ENDFORM. " TOEXCEL
(完)