【ABAP SAP】开发-BUG修补记录_采购申请打印时品名规格品牌为空

项目场景:

TCODE:自开发程序ZMMF004

采购申请打印


问题描述

ZMMF004打印的时候,有的采购申请的品名、规格、品牌为空


原因分析:

1、首先我通过写SQL语句查底表来看这几条采购申请本身有无品名、规格、品牌

SQL语句如下,只需修改where条件即可测试各条数据

eban底表:采购申请

测试1:采购申请号:2500000122

SELECT ZPM,ZGGXH,ZPP
FROM EBAN
WHERE BANFN = '2500000122';

执行结果:

可看出该条采购申请是本身就没有品名、规格、品牌的值的

测试2:采购申请号:2500000134

SELECT ZPM,ZGGXH,ZPP
FROM EBAN
WHERE BANFN = '2500000134';

执行结果:

可看出该条采购申请是本身就有品名的值,但没有规格、品牌的值

测试3:采购申请号:2500000136

SELECT ZPM,ZGGXH,ZPP
FROM EBAN
WHERE BANFN = '2500000136';

执行结果:

可看出该条采购申请对应两个物料号,其中一个物料有品名值,无规格、品牌的值;另一个物料这三个字段都没有值

从上面的测试结果我可以得出,并不是由于程序取数逻辑错误而导致带不出品名、规格、品牌等字段值,而是因为一些采购申请本身就没有填相应的字段值

2、我的首先的思路是,loop循环ALV最终要显现出来的取到数据的内表,一条一条查哪些采购申请的品名、规格、品牌为空,若为空,则再从物料主数据中取然后放到内表中,但这样loop会非常耗费时间,代码实现也要相对注意,所以这个思路out

3、与其loop已取出来数的内表,不如直接从源头select改变取值方式,直接去物料主数据里取


解决方案:

通过上面的原因分析,可采用如下解决方案:也就是原因分析中的第三条

直接取物料对应的物料主数据上的需要的字段信息,并使其显示出来,若采购申请有这三个字段的值也没关系,从物料主数据中取出来的三字段的值会直接覆盖(因为采购申请中的三字段值和物料主数据中的应该是一致的)

所以解决办法也很简单,直接在原先select语句基础上,连一个表mara物料主数据,让直接从mara表中取品名,规格,品牌(前提是mara表中得有这些字段)

mara表:

修改的语句如下:

SELECT a~banfn,
         a~bnfpo,
         a~badat,
         a~bsart,
         a~matkl,
         a~ernam,
         a~knttp,
         a~werks,
         d~name1,
         a~ekgrp,
         b~eknam,
         a~matnr,
         a~txz01,
         i~zpm,
         i~zggxh,
         i~zpp,
         a~menge,
         a~meins,
         a~lfdat,
         a~lgort,
         c~lgobe,
         a~afnam,
         a~zjjcd,
         a~zjhjh,
         f~maktx,
         g~wgbez,
         h~knttx
   INTO CORRESPONDING FIELDS OF TABLE @gt_alv
    FROM eban AS a
    LEFT  OUTER JOIN t024    AS b ON a~ekgrp = b~ekgrp
    LEFT  OUTER JOIN t023T   AS g ON a~matkl = g~matkl
    LEFT  OUTER JOIN t001L   AS c ON a~werks = c~werks AND a~lgort = c~lgort
    LEFT  OUTER JOIN t001w   AS d ON a~werks = d~werks
    LEFT  OUTER JOIN makt    AS f ON a~matnr = f~matnr
    LEFT  OUTER JOIN zmmt021 AS e ON a~banfn = e~banfn
    LEFT  OUTER JOIN t163i   AS h ON a~knttp = h~knttp AND h~spras = @sy-langu
    LEFT  OUTER JOIN MARA    AS i on i~matnr = a~matnr
   WHERE a~bsart IN @s_bsart
     AND a~werks IN @s_werks
     AND a~banfn IN @s_banfn
     AND a~badat IN @s_badat
     AND a~ernam IN @s_ernam
     AND a~loekz NE 'X'
     AND (lv_str)
     AND (lv_str2).

红框中为修改并添加的语句

再执行 ZMMF004,效果如下:


2024/12/12 13:57

承接上文,需要做个纠正,由于采购申请中的那三个字段的值可能和物料主数据中的不一样,所以其实并不能简单的让直接取物料主数据里的值,而忽略过采购申请,所以,还是需要判断:若采购申请中的三个字段的值不为空,则就取采购申请里的,若采购申请里的为空或为初始值,则取物料主数据里的

代码如下:

  SELECT a~banfn,
         a~bnfpo,
         a~badat,
         a~bsart,
         a~matkl,
         a~ernam,
         a~knttp,
         a~werks,
         d~name1,
         a~ekgrp,
         b~eknam,
         a~matnr,
         a~txz01,
*         a~zpm,
*         a~zggxh,
*         a~zpp,
    CASE
    WHEN a~zpm is not null and a~zpm is not initial then a~zpm
    else i~zpm
    end as zpm,

    CASE
    WHEN a~zggxh is not null and a~zggxh is not initial then a~zggxh
    else i~zggxh
    end as zggxh,

      CASE
    WHEN a~zpp is not null and a~zpp is not initial then a~zpp
    else i~zpp
    end as zpp,

         a~menge,
         a~meins,
         a~lfdat,
         a~lgort,
         c~lgobe,
         a~afnam,
         a~zjjcd,
         a~zjhjh,
         f~maktx,
         g~wgbez,
         h~knttx

    FROM eban AS a
    LEFT  OUTER JOIN t024    AS b ON a~ekgrp = b~ekgrp
    LEFT  OUTER JOIN t023T   AS g ON a~matkl = g~matkl
    LEFT  OUTER JOIN t001L   AS c ON a~werks = c~werks AND a~lgort = c~lgort
    LEFT  OUTER JOIN t001w   AS d ON a~werks = d~werks
    LEFT  OUTER JOIN makt    AS f ON a~matnr = f~matnr
    LEFT  OUTER JOIN zmmt021 AS e ON a~banfn = e~banfn
    LEFT  OUTER JOIN t163i   AS h ON a~knttp = h~knttp AND h~spras = @sy-langu
    LEFT  OUTER JOIN MARA    AS i on i~matnr = a~matnr
   WHERE a~bsart IN @s_bsart
     AND a~werks IN @s_werks
     AND a~banfn IN @s_banfn
     AND a~badat IN @s_badat
     AND a~ernam IN @s_ernam
     AND a~loekz NE 'X'
     AND (lv_str)
     AND (lv_str2)
  INTO CORRESPONDING FIELDS OF TABLE @gt_alv.

另外:对null 和initial做个区分

a~zpm is not null检查字段是否有值;a~zpm is not initial检查字段的值是否不是其"初始"状态;

这里的初始状态应该是说数据库表字段在定义时有无指定默认值,如果数据库表字段在定义时指定了默认值,那么在插入数据时如果没有为该字段赋值,数据库会白动使用指定的默认值;如果数据库表字段没有指定默认值,且在插入数据时没有为其赋值,那么该字段的值将取决于数据库系统的默认行为:字符类型字段会被赋值为空字符(")

那只有在从采购申请中得来的字段不为空且不是初始值的情况下,就用采购申请里的;若是空或是初始值,就用物料主数据里的
null 在数据库中表示一个未知或缺失的值。如果一个字段的值为null,这意味着这个字段没有值,或者说它的值是不确定的。
initial用于表示一个字段或变量的初始状态或默认值

注:

在 ABAP 中,往数据库插入数据时,如果字段未被显式赋值,则插入行为取决于以下几个方面:

1、字段的初始值:

对于 ABAP 内部表或者工作区(Work Area)中的字段,如果未赋值,这些字段会有默认的

初始值,具体如下:

字符型(CHAR, STRING):空字符串 ··

数值型(INT, FLOAT, DEC):e。

日期型(DATE):'00000000'。

时间型(TIME):'000000'

布尔型 (X, FLAG):8。

插入数据库时,ABAP 会使用这些默认初始值。

2、数据库字段的默认值

如果数据库表字段在定义时指定了默认值(通过字段的 Defaut 属性设置),即使 ABAP 程序

没有赋值,该默认值也会被插入。

3、数据库字段是否允许空值:

如果字段在数据库中被定义为允许 NULL值,那么 ABAP 中使用 CLEAR 或未赋值的字段可

能会被视为 NULL,具体取决于数据库接口的设置。

如果字段不允许 NULL值,未赋值字段会使用其默认的初始值插入到数据库中,

相关推荐
幽兰的天空1 分钟前
Java 基础之 XQuery:强大的 XML 查询语言
java·运维·数据库
哈茶真的c25 分钟前
【docker】12. Docker Volume(存储卷)
运维·docker·容器
duration~31 分钟前
Docker Compose应用实战
运维·docker·容器
ccubee1 小时前
docker run安装镜像
运维·docker·容器
Little丶Seven1 小时前
[游戏开发] Unity中使用FlatBuffer
数据库·unity
斗-匕1 小时前
MySQL 事务隔离级别详解
数据库·mysql·oracle
柴华松1 小时前
mysql密码配置
数据库·mysql
MClink1 小时前
聊聊系统的弹力设计-服务器性能指标篇(一)
运维·服务器·高可用
Easy_Company2 小时前
关于Redis哨兵机制实验操作步骤
java·大数据·数据库·redis·缓存
YCyjs2 小时前
Jenkins
运维