赞
踩
总览
SAP S4采用HANA数据库,本质上是用大内存、列存储实现快速的数据读取,其实存取效率应该还是下降了。
对于MM的库存管理,其实顾问们遇到最多的问题就是进销存/库龄/时点库存盘点之类的。
过去ECC面临海量数据时基本都推给BW了,现在HANA其实给了我们更多的可能。
SAP标准表变化
其实S4的版本中,库存表虽然看起来还跟ECC一致,其实底层已经完全不同了。
以MARD为例,如果你用HANA工具打开数据库链接,你会发现里面的数量字段,全都是0。
那系统时怎么做到SE16N看到库存数量呢?
第一步代理视图:
第二部DDL源视图:
大概套了了好几层,最后一层是 NSDM_DDL_MARD_AGG
第三步:SAP 标准的MARD数据视图
- @AbapCatalog.preserveKey: true
- @AbapCatalog.compiler.compareFilter: true
- @AbapCatalog.sqlViewName: 'NSDM_V_MARD_AGG'
- @EndUserText.label: 'MARD Compatibility View: Aggregation'
- @DataAging.noAgingRestriction: 'false'
-
- @ObjectModel.usageType.sizeCategory: 'L'
- @ObjectModel.usageType.serviceQuality: #C
- @ObjectModel.usageType.dataClass: #TRANSACTIONAL
- @ClientHandling.algorithm: #AUTOMATED
- @AccessControl.authorizationCheck: #NOT_ALLOWED
- @AbapCatalog.viewEnhancementCategory: #PROJECTION_LIST
-
- define view nsdm_e_mard_agg as
- select from matdoc_extract
- {
- key mandt,
- key matbf as matnr,
- key werks,
- key lgort_sid as lgort,
-
- key lbbsa_sid as lbbsa,
- key sobkz,
-
- sum(stock_qty_l2) as stock_qty,
- sum(stock_vkwrt_l2) as stock_vkwrt,
- max(gjper_curr_per) as gjper_max,
- sum(/cwm/stock_qty_l2) as /cwm/stock_qty
- }
- where stock_ind_l2 = ''
- and (((sobkz = '' or sobkz = 'K')
- and (lbbsa_sid = '01' or lbbsa_sid = '02' or lbbsa_sid = '07' or lbbsa_sid = '08'))
- or (sobkz = ''
- and (lbbsa_sid = '03' or lbbsa_sid = '04')))
-
- group by mandt, matbf, werks, lgort_sid, lbbsa_sid, sobkz
-
可以看下SQL逻辑,就是简单的通过matdoc_extract表聚合而成。
而matdoc_extract是一张物料存储表,是MSEG的衍生表。默认行数应该与MATDOC一致。
月底应该有个默认作业,对matdoc_extract做同KEY同该期间的合并压缩。其实很多行业压缩率很低。
可见新版本HANA的SQL,已经可以做到过去通过ORCALE 直接 OPENSQL取数的效率。
那么问题来了,对我们有什么帮助呢?
H表的变化
大家知道基本每个库存表都由有个H表,记录每个期末的库存。其实H表也这么调整了,而且解决了之前的一个难题。
过去如果一个物料/工厂/库位 在该期间没有货物移动,那么该期间的H表就是空。所以取月底的数逻辑十分复杂,效率低下,这个在新架构下基本没问题。
到天的时点库存
有些时候进销存/库龄可能不仅仅是按期间的,可能要到某一天。
其实我遇到这个需求是看看MARD的变化,本来想学MARD的方式也汇总那个表获取到天的库存,后来发现那个表只有期间没有天。其实SAP这么优化架构,大概率也会建立一些视图满足这个功能。找了下真有。
PMATSTOCKTIMESER
SE16N打开这个函数,执行时要输入参数,期间一般用D按天,然后开始/结束日期。
输出格式是按KEY的库存,基本支持各类特殊库存,按库存类型区分非限制、质检等信息。
简单处理下就是完整的库存数量了。效率OK
进一步的理解
我能不能自己汇总MSEG得到库存呢?
其实MSEG有很多问题,例如315只有一行,有一些无库存移动的行要排除。其实用MATDOC更好一些。完全可以实现,新SQL可以通过借贷 CASE WHEN THEN实现 SUM聚合与正负调整。
不过金额的处理还是不够完美。
例如MR21 调差 MIRO采购差异等这里还是缺的。K库存的金额其实不计入库存商品。有些特殊业务金额可能分布在不同的列等等。
这里我有个终极方案:自定义ZMSEG,将一些特殊处理全部放到物料凭证BADI->BEFORE_UPDATE方法里简单处理,同步写入ZMSEG。
简单处理了下业务类型的区分,金额/数量的取值/和正负。
通过作业或增强获取 ACODCA中 存货科目下非物料凭证生成的会计凭证,获取差异金额数据。同样处理好金额正负/取值等。
大概结果如下:
物料凭证数据
其它金额调整:下图应该是发票校验移动金额差。
那么就可以通过一个简单的SQL,获取某时点的库存数量/金额。
通过前面对业务类型的规划,可以实现对应对期间内数据的分列,实现一般进销存的的数据分列,SQL如下。
- SELECT
- * c~partner AS channel,
- * c~name1,
- a~werks AS werks,
- a~satnr AS satnr,
- goods_brand,
- SUM(
- CASE d~jxc_type
- WHEN '1' THEN a~erfmg
- END
- ) AS menge1,
-
- SUM(
- CASE d~jxc_type
- WHEN '1' THEN a~dmbtr
- END
- ) AS netwr1,
-
- SUM(
- CASE d~jxc_type
- WHEN '2' THEN a~erfmg
- END
- ) AS menge2,
-
- SUM(
- CASE d~jxc_type
- WHEN '2' THEN a~dmbtr
- END
- ) AS netwr2,
- SUM(
- CASE d~jxc_type
- WHEN '3' THEN a~erfmg
- END
- ) AS menge3,
-
- SUM(
- CASE d~jxc_type
- WHEN '3' THEN a~dmbtr
- END
- ) AS netwr3,
- SUM(
- CASE d~jxc_type
- WHEN '4' THEN a~erfmg
- END
- ) AS menge4,
-
- SUM(
- CASE d~jxc_type
- WHEN '4' THEN a~dmbtr
- END
- ) AS netwr4,
- * SUM(
- * CASE d~jxc_type
- * WHEN '5' THEN a~erfmg
- * END
- * ) AS menge5,
- *
- * SUM(
- * CASE d~jxc_type
- * WHEN '5' THEN a~dmbtr
- * END
- * ) AS netwr5,
- * SUM(
- * CASE d~jxc_type
- * WHEN '6' THEN a~erfmg
- * END
- * ) AS menge6,
- *
- * SUM(
- * CASE d~jxc_type
- * WHEN '6' THEN a~dmbtr
- * END
- * ) AS netwr6,
- SUM(
- CASE d~jxc_type
- WHEN '7' THEN a~erfmg
- END
- ) AS menge7,
-
- SUM(
- CASE d~jxc_type
- WHEN '7' THEN a~dmbtr
- END
- ) AS netwr7,
- SUM(
- CASE d~jxc_type
- WHEN '8' THEN a~erfmg
- END
- ) AS menge8,
-
- SUM(
- CASE d~jxc_type
- WHEN '8' THEN a~dmbtr
- END
- ) AS netwr8
- * SUM(
- * CASE d~jxc_type
- * WHEN 'T' THEN a~erfmg
- * END
- * ) AS menget,
- *
- * SUM(
- * CASE d~jxc_type
- * WHEN 'T' THEN a~dmbtr
- * END
- * ) AS netwrt
-
- INTO CORRESPONDING FIELDS OF TABLE @gt_alv
- FROM zmseg AS a
-
- LEFT JOIN zvmm_xpwl_info AS b ON a~satnr = b~matnr
-
- * INNER JOIN zscmt0010 AS c ON a~werks = c~werks AND a~lgort = c~lgort
-
- INNER JOIN zscm_jxc AS d ON a~bwart = d~bwart AND a~grund = d~grund AND a~shkzg = d~shkzg
-
- WHERE a~budat_mkpf >= @p_date1
- AND a~budat_mkpf <= @p_date2
- AND a~werks IN @s_werks
-
- * AND partner IN @s_partn
- * AND budat_mkpf < @p_date1
- * AND zxzdq IN @s_zxzdq
- * AND zejqy IN @s_zejqy
- * AND brand_id IN @s_brand
- * AND zsyb IN @s_zsyb
-
- AND a~satnr IN @s_satnr
- AND saisj IN @s_saisj
- AND saiso IN @s_saiso
- AND goods_brand IN @s_brand1
- AND mtart IN @s_mtart
-
- GROUP BY
- * c~partner,
- * c~name1,
- a~werks,
- goods_brand,
- a~satnr .
-
通过以上的方案,就可以实现把进销存或时点库存,甚至库龄的计算绝大部分都放到HANA的DB曾执行,ABAP应用层只做简单的数据拼装就可以,实现比较高的系统效率。
其实除了库存,还有信贷、甚至FI的科目余额、成本金额,都可以用此类方式实现(实际上你取标准表也是视图)。
所以HANA的方案实际上给业务顾问/ABAP顾问更强大的工具去做业务实现。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。