在SAP中,未结PO(未完全收货/未完全开票)的状态是动态计算的,没有单独的“未结PO表”。不过,可以通过几个核心表关联查询。我先梳理流程和表关系,再给出查询未结PO的常用方法。
一、PO相关主要后台表
| 表名 | 描述 | 关键字段 |
|---|---|---|
| EKKO | PO抬头数据 | EBELN(PO号)、BSART(凭证类型)、LIFNR(供应商) |
| EKPO | PO行项目数据 | EBELN、EBELP(行号)、MATNR(物料)、MENGE(数量)、NETWR(金额) |
| EKET | PO计划行数据 | EBELN、EBELP、ETENR(计划行号)、MENGE(计划数量) |
| EKES | PO确认(供应商确认) | EBELN、EBELP、ETENR |
| RESB | 预留/相关需求 | RSNUM(预留号)、BDMNG(需求数量) |
二、收货(Goods Receipt)相关表
| 表名 | 描述 | 关键字段 |
|---|---|---|
| EKBE | PO历史(收货/发票凭证) | EBELN、EBELP、VGABE(交易类型)、BELNR(物料凭证/发票凭证)、SHKZG(借贷标识)、MENGE(数量)、DMBTR(金额) |
| MSEG | 物料凭证项目 | MBLNR(物料凭证)、ZEILE(行号)、EBELN、EBELP、MENGE |
| MKPF | 物料凭证抬头 | MBLNR、MJAHR(年度)、BLART(凭证类型) |
关键点:EKBE是最重要的表,它记录了每一笔与PO相关的收货和发票凭证。
VGABE = '1'表示收货VGABE = '2'表示发票收据SHKZG = 'S'表示借方(增加库存/应付)SHKZG = 'H'表示贷方(退货/冲销)
三、发票校验(Invoice Verification)相关表
| 表名 | 描述 | 关键字段 |
|---|---|---|
| RBKP | 发票抬头 | RBNUM(发票凭证)、LIFNR、BUDAT |
| RSEG | 发票行项目 | RBNUM、RBZEILE(行号)、EBELN、EBELP、MENGE(数量)、DMBTR(金额) |
四、业务流程及数据更新
1. PO创建
更新表:
EKKO(抬头)、EKPO(行项目)、EKET(计划行)状态:PO行项目的
ELIKZ(交货完成标识)和REPOS(发票完成标识)均为空
2. 收货(MIGO)
更新
MSEG/MKPF(物料凭证)同时更新
EKBE:增加一条VGABE='1'的记录,SHKZG='S'(收货)PO行项目
EKPO-MENGE不变,但已收货数量可通过EKBE累计计算
3. 退货(退货交货)
更新
MSEG/MKPF同时更新
EKBE:增加一条VGABE='1'的记录,SHKZG='H'(退货)
4. 发票校验(MIRO)
更新
RBKP/RSEG(发票凭证)同时更新
EKBE:增加一条VGABE='2'的记录,SHKZG='S'(发票)如果发票数量小于收货数量,则未完全开票
5. 完成标识更新
当收货数量 ≥ PO数量时,系统自动勾选EKPO-ELIKZ = 'X'(交货完成)
当发票数量 ≥ PO数量时,系统自动勾选EKPO-REPOS = 'X'(发票完成)
五、如何查询“未结PO”
方法1:直接通过EKPO状态字段查询(简单但不精确)
sql
SELECT ebeln, ebelp, menge, elikz, repos FROM ekpo WHERE elikz <> 'X' OR repos <> 'X';
缺点:只反映最终完成状态,不反映部分收货/开票的中间状态。
方法2:通过EKBE累计计算(推荐)
sql
SELECT e.ebeln, e.ebelp, e.menge AS po_quantity, SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'H' THEN be.menge ELSE 0 END) AS gr_quantity, SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'H' THEN be.menge ELSE 0 END) AS iv_quantity, e.menge - (SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'H' THEN be.menge ELSE 0 END)) AS open_gr, e.menge - (SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'H' THEN be.menge ELSE 0 END)) AS open_iv FROM ekpo e LEFT JOIN ekbe be ON e.ebeln = be.ebeln AND e.ebelp = be.ebelp AND be.vgabe IN ('1', '2') WHERE e.loekz <> 'L' -- 未删除 GROUP BY e.ebeln, e.ebelp, e.menge HAVING e.menge > (SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '1' AND be.shkzg = 'H' THEN be.menge ELSE 0 END)) OR e.menge > (SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'S' THEN be.menge ELSE 0 END) - SUM(CASE WHEN be.vgabe = '2' AND be.shkzg = 'H' THEN be.menge ELSE 0 END));方法3:使用标准视图或事务代码
事务代码:
ME2L、ME2M、ME2N等,可以选择“未完全交货”或“未完全开票”的PO视图:
V_EKPO_EBAN、V_EKBE等组合查询
六、关键总结
没有独立的“未结PO表”,状态是通过
EKPO的完成标识和EKBE的累计数量动态判断的。核心表关系:
EKKO/EKPO→EKBE←MSEG/RBKP判断逻辑:
未完全收货:
PO数量 - 累计收货数量 > 0未完全开票:
PO数量 - 累计开票数量 > 0完全完成:
EKPO-ELIKZ = 'X'且EKPO-REPOS = 'X'
如果你需要具体报表或更复杂的查询逻辑(如按供应商、物料、工厂等),我可以提供更详细的SQL示例。