员工
0HR_PA_0
业务数据源中有一个CALMONTH日历年/月的字段,只要员工还在职,每个员工每个月都会产生一条数据
:
人事事件
0HR_PA_1
业务数据源中有一个CALDAY日历天的字段,只要员工发生人事事件(如入职、晋升、调离、离职等),该数据源中就会产生一条数据
:
需求:将
0HR_PA_0
、
0HR_PA_1 两个数据源中的数据抽到DSO后,需要在原有的数据字段上附加上
人事子范围 、
公司代码、
员工组 、
员工子组、
人事范围、
雇佣状态 、组织单位、
业务范围
这些数据字段(从上面图中可以看到这两个业务数据源中原本没有这些字段),即需要将主数据属性直接存入到交易数据中(而非导航属性那样,主数据属性是通过导航的方式关联起来,而这里是要求将这些主数据属性直接存储到Fact表的维度表中,即要求以场景A来建模,
场景A具体应用及实现请参照另一篇文章
),如何用场景A来实现?
分析:现需要将业务数据源中原本没有的这些字段附加到业务数据上,除了通过直接对业务数据源进行增强外,针对这两个业务数据源(
0HR_PA_0
、
0HR_PA_1
),有更简便的方法就是在DSO层,通过
Read Master Data 读取主数据转换规则 将这些附加字段数据从相应主数据中读取出来(前提是附加的这些字段是交易数据能关联到的主数据属性字段,
如这里附加的这些字段,都是可以通过
0HR_PA_0
、
0HR_PA_1业务数据源与员工0EMPLOYEE、组织
0ORGUNIT
关联得到的,
但增强方式没有这个要求)。由于
人事子范围 、
公司代码、
员工组 、
员工子组、
人事范围、
雇佣状态 、组织单位
这些字段是InfoObect员工OEMPLOYEE的属性(且这些属性与时间相关):
而
业务范围
又是
组织单位
0ORGUNIT信息对象 的属性(且也与时间相关):
现在要附加上的这些字段分别属于 OEMPLOYEE(
人事子范围 、
公司代码、
员工组 、
员工子组、
人事范围、
雇佣状态 、
组织单位
) 、
0ORGUNIT(
业务范围
)这两个信息对象中,并且
业务范围
这个字段需要在
组织单位
属性抓出来后,才能根据
组织单位
到
0ORGUNIT信息对象 中将
业务范围
属性抓出来。下面
屡一下这些附加字段的抓取顺序:先将业务数据源
0HR_PA_0
、
0HR_PA_1的数据抽取到第一层DSO中(明细层,原样存储数据源的数据,在这一层不会增加数据源抽取结构以外的字段);再将第一层DSO数据转换存储到第二层DSO中,第二层DSO需在第一层DSO的基本上,附加上
人事子范围 、
公司代码、
员工组 、
员工子组、
人事范围、
雇佣状态 、
组织单位
这些字段,这些字段通过
Read Master Data
转换规则从主数据
OEMPLOYEE中抓取出来,但要注意的是这些属性是与时间相关的,读取时需要加上业务时间这一条件(即从0EMPLOYEE底表里抓取这些属性字段时,除了员工编号外,还需要加上 业务时间0CALMONTH 条件);最后第三层DSO在第二层的基本上再附加上
业务范围
这一字段,此时需从
0ORGUNIT信息对象 底表抓取,条件是 组织单位 + 业务时间0CALDAY
。下面以 员工
0HR_PA_0 数据源为例,采用三层DSO建模:
具体转换规则如下:
上面在通过
Read Master Data
读取主数据 转换规则读取主属性时,由于主属性是时间相关的,则读取主数据的时间条件取值可以是以下三种:
当前日期
:
读取
主属性时,会以当前时间点(YYYYMMDD)为时间限制条件值,抓取当前时间点所对应有效属性,即抓取满足
DateFrom <= 当前时间 <=DateTo
时间条件的主数据(
DateFrom
、
DateTo为主数据底表两个字段,用它们来表示数据的有效期
)
常数日期
:以某个常数日期(也是
YYYYMMDD,到天)为时间条件,
读取相应时间点的有效主属性
Form(从)
:以DSO源中的某个日期字段(上面选择的为0CALMONTH,该字段为源DSO中的某个时间字段,只到月)为时间条件,读取相应时间点的主属性
。由于这里选择的日期字段
0CALMONTH只到月,以此为时间限制条件(
DateFrom <= 0CALMONTH <=DateTo
)
去主数据底表里查询时,可能会有多条数据对应,这时是取最早的,还是最晚的数据(但不能取到中间某个时间段主数据),就要看选择的是“开始”还是“结束”了,选择的不同,抓取到的主属性也是不一样的,具体请看下面的测试:
员工 0HR_PA_0 业务数据源 中的
日历年月CALMONTH只到月,以此字段作为业务产生的时间来读取时间相关的主数据属性时,”开始“、”结束“测试结果如下:
所以从上面两组(
0HR_PA_0、
0HR_PA_1
)测试结果来看,”开始“、”结束“只对
到月(或季度、年)
业务时间起作用
,如员工
0HR_PA_0数据源的0CALMOTH业务时间字段
;对已精确到天
的业务时间不起作用
,如人事事件
0HR_PA_1数据源的0CALDAY业务时间字段
,到天时不管选择的是“开始”还是“结束”读取到的主数据属性都是一样的,因为已精确到某一天,所以读取到的主数据有且仅有一条;
根据不到天(如只到月、季度、年)的业务时间来抓取时间相关主数据时,
Read Master Data 中
选择“开始”时,如果有多条符合(原因就是业务时间没有精确到天,而主数据的DATEFrom与DAETo是到天的,在以业务时间为条件从主数据底表读取主属性时,会忽略掉主数据有效时间字段
DATEFrom与DAETo中的天,这样就会匹配到多条主数据
),就取有效时间段最早的那条;如果选择“结束”时,有多条符合就取最晚(最新的)的那一
条,注:不可能只取中间某个时间的主数据
上面实例是以员工
0HR_PA_0数据源为例,演示了如何通过
Read Master Data 转换规则 读取
时间相关的主数据,并且是通过三层DSO建模来实现的,实质上也可以只通过两层DSO就可以实现
OEMPLOYEE与
0ORGUNIT主数据的读取。具体实现方式:需要在第一层DSO的End Routine中,先根据数据源中的员工编号从
OEMPLOYEE信息对象底表中
将
组织单位
抓取出来(注:通过End Routine程序抓取主数据时,也需要考虑时间相关,
End Routine程序
代码中需加上时间限制条件)
,然后在第二层DSO的转换规则中,通过
Read Master Data 方式将将所有的附加字段一次性全读取出来,而不需要分两层DSO分两次读取
OEMPLOYEE与
0ORGUNIT主数据
。注:上面
员工
0HR_PA_0数据源不能采用这种 End Routine +
Read Master Data 的两层DSO方式,因为业务时间只到月
,虽然程序可以读取时间相关的主数据,但程序无法灵活实现“开始”与“结束”
,只有人事事件
0HR_PA_1数据可以使用
End Routine +
Read Master Data 的两层DSO方式建模,因为相应业务时间到天了,可通过End Routine精确读取到一条时间相关的主数据,与“开始”“结束”无关。下面采用这种
End Routine +
Read Master Data只有两层DSO方式来建模:
0ORGUNIT抓取是通过End Routine实现的,但要注意的是,
0ORGUNIT的抓取虽然是放在End Routine代码里实现的,不需要划线,但规则类型也不能选择“无转换”,否则DSO 激活时,New表里抓取到的 组织单位 在激活后Active表里的组织单位就会丢失,所以最好选择规则类型为常数转换规则,值为空,这样在激活后就不会消失
),具体代码如下:
METHOD
end_routine
.
*=== Segments ===
FIELD-SYMBOLS
:
<RESULT_FIELDS>
TYPE
_ty_s_TG_1
.
DATA
:
MONITOR_REC
TYPE
rstmonitor
.
*$*$ begin of routine - insert your code only below this line *-*
.
.
.
"insert your code here
*-- fill table "MONITOR" with values of structure "MONITOR_REC"
*- to make monitor entries
.
.
.
"to cancel the update process
* raise exception type CX_RSROUT_ABORT.
DATA
:
t_docinfo
TYPE
TABLE
OF
_ty_s_TG_1
.
DATA
:
wa_docinfo
TYPE
_ty_s_TG_1
.
**=======调试使用
Data
:
t_zjzjtest
TYPE
TABLE
OF
zjzjtest
.
DATA
wa_zjzjtest
type
zjzjtest
.
**=======end
SELECT
ORGUNIT EMPLOYEE
INTO
CORRESPONDING
FIELDS
OF
TABLE
t_docinfo
FROM
/BI0/MEMPLOYEE
FOR
ALL
ENTRIES
IN
RESULT_PACKAGE
WHERE
EMPLOYEE
=
RESULT_PACKAGE
-
EMPLOYEE
"员工主数据表为 /BI0/MEMPLOYEE,其属性是与时间相关的,所以查询时需加上时间条件,
"读取业务数据产生时所对应的主数据. RESULT_PACKAGE-CALDAY 为业务发生的时间,
"dateto与datefrom为主数据的有效期
and
datefrom <= RESULT_PACKAGE
-
CALDAY
and
dateto >=
RESULT_PACKAGE
-
CALDAY
.
sort
t_docinfo
by
EMPLOYEE
ASCENDING
.
LOOP
AT
RESULT_PACKAGE
ASSIGNING
<RESULT_FIELDS>
.
READ
TABLE
t_docinfo
WITH
key
EMPLOYEE
=
<RESULT_FIELDS>
-
EMPLOYEE
BINARY
SEARCH
INTO
wa_docinfo
.
<RESULT_FIELDS>
-
ORGUNIT
=
wa_docinfo
-
ORGUNIT
.
**=======调试使用
APPEND
wa_docinfo
-
ORGUNIT
to
t_zjzjtest
.
**=======end
ENDLOOP
.
**=======调试使用
DELETE
FROM
zjzjtest
.
MODIFY
zjzjtest
from
TABLE
t_zjzjtest
.
**=======end
*$*$ end of routine - insert your code only before this line *-*
ENDMETHOD
.
"end_routine
在第二层DSO中将
OEMPLOYEE与
0ORGUNIT两个主数据一次全部读取出来: