“要想富,先修路”,这是一条曾经在全国各地农村很容易见到的标语,的确只有在有了便捷的交通后,农村的特产、加工品才能走出去为人所知,而外面的新玩意、游客也才能络绎不绝流进来;现实如此,信息世界也同样如此,数据之间的流通需要有正确的通路才能够最终有机结合生机勃勃;在BW中,信息对象,CUBE及DSO就是这样一个个的乡野村落,真正使他们活起来变得有意义的就是在他们中间建立的传输与转换进程.首先要展示的莫过于BW中整体数据传输的流程图
这幅美轮美奂的图清晰的描述了在BW中数据传递的关系,即数据通过InfoPackage传入PSA,然后在通过DTP由PSA传入CUBE或者DSO,其中PSA到上层的传输过程中,其转换规则从TRANSFORMATION中体现。
其中一般的BW模型设计中,都会将数据由PSA原原本本的抽取到DSO中,基本不加以修饰,因为最原始的数据在数据出现错误时候才容易和数据源做比对。然后再通过DTP由TR的规则传入CUBE,即遵从DataSource-->PSA-->DSO-->CUB这样的原则;那也就是说可以大做文章的数据清洗过程都包含在TRANSFORMATION中。 在PSA和DSO或者CUBE之间新建一个TR如下,
查看任何一个规则,都可以看到如下的界面,其中的规则类型有常数、直接分配、公式、初始的、读主数据以及例程;其中各种意义如下:
常数,表示目标对象中根本就是存一个常数,跟源字段丝毫没有关系,在选择常数后,其后会出现一个空格需要输入常数值;
直接分配,就是将数据源字段值原封不动的直接分配到目标信息对象,无需处理;
公式,SAP提供了一些公式,可以对字段做一些处理,不过一般情况下,这个功能没有例程来的实在
初始的,表示这个信息对象的值就是一个初始值,也搞不清楚这个功能初衷何在...
读主数据,是在某些情况下,可能目标字段没有直接包含需要字段,但是可以通过某个字段来读取信息对象中的属性字段,在选择这个功能后,会出现一个属性的信息对象,选择需要的信息对象即可从主数据信息对象中将数据读取过来赋给目标字段;
例程,就是写一段ABAP程序来把源数据做需要的处理后再分配给目标信息对象,这个是一个非常强大好用的功能;
在TR中,有三种类型的例程,开始例程,转换例程及结束例程,分别有自己的独到之处;
一般来说开始例程是在数据加载之前对源数据进行的一个处理过程,例如对数据进行筛选删除等,而转换例程则是在每笔数据传输过程中,对数据进行的一个转换,例如数据根据条件进行的匹配转换;而结束例程则是对于数据进行符合目标数据结构的转换与调整,例如数据一行结构性调整成多行等。例程的巧妙使用可以使建模精巧细致,甚至减少数据的维护量。
在所有的TR维护界面上方,都有下面的两个按钮
分别给出一个开始例程,传输例程及结束例程的应用场景及代码实现,如下:
开始例程程序范例及场景:
在数据传输伊始就需要删除AAA工厂数据,则可以在传输例程中写入如下程序:
*$*$ begin of routine - insert your code only below this line
"删除AAA工厂
DELETE SOURCE_PACKAGE WHERE /BIC/ZPLANT = 'AAA'
*$*$ end of routine - insert your code only before this line
转换例程应用:
在数据传输过程中需要补充物料前导零,则在信息对象例程中加入以下代码即可。
*$*$ begin of routine - insert your code only below this line
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = SOURCE_FIELDS-MATNR
IMPORTING
OUTPUT = RESULT.
*$*$ end of routine - insert your code only before this line
结束例程应用:
如果数据源的结构是一个扁平化结构,现在需要将其拆分成多行,例如结构是源数据是
办事处 一月份销量 二月份销量 三月份销量...
而目标的结构为 办事处 月份 销量;则就可以在结束例程里做文章了;示例代码如下:
现在开始例程中定义一个与源一模一样的内表,并且将源值赋给这个内表,代码如下:
*$*$ begin of routine - insert your code only below this line *-*
... "insert your code here
ITAB[] = SOURCE_PACKAGE[].
*$*$ end of routine - insert your code only before this line *-*
然后在结束例程中,在写入以下程序:
*$*$ begin of routine - insert your code only below this line *-*
... "insert your code here
REFRESH RESULT_PACKAGE.
DATA: WA_RESULT TYPE _TY_S_TG_1.
LOOP AT ITAB INTO WA_ITAB.
WA_TG-/BIC/ZSM_OFF = WA_ITAB-ORG_ID.
*****1月
WA_TG-CALMONTH2 = '01'.
WA_TG-/BIC/ZSM_BPQTY = WA_ITAB-M1 .
APPEND WA_TG TO ITAB_TG.
****2月
WA_TG-CALMONTH2 = '02'.
WA_TG-/BIC/ZSM_BPQTY = WA_ITAB-M2.
APPEND WA_TG TO ITAB_TG.
****3月
WA_TG-CALMONTH2 = '03'.
WA_TG-/BIC/ZSM_BPQTY = WA_ITAB-M3.
APPEND WA_TG TO ITAB_TG.
ENDLOOP.
LOOP AT ITAB_TG INTO WA_TG.
MOVE-CORRESPONDING WA_TG TO WA_RESULT.
APPEND WA_RESULT TO RESULT_PACKAGE.
ENDLOOP.
*$*$ end of routine - insert your code only before this line *-*