SAPBW例程(Routine)【开始例程、关键值或特性的例程、结
束例程】
定义
可以使⽤例程定义关键值或特性的复杂的转换规则.
例程是本地 ABAP 类,它们包括预定义的定义和实施范围.进站和出站参数的 TYPES及⽅法签名都存储在定义范围中.实际例程创建于实施范围中.使⽤该⽅法,可以分配 ABAP 对象.在⽣成期间,把此⽅法嵌⼊到转换程序中.
转换包括以下类型的例程:
启动例程
关键值或特性的例程
结束例程
专家例程:此类型的例程仅⽤于特殊情况.如果提供的转换功能不⾜以满⾜您的要求,那么可以使⽤专家
程序.在标准系统中所要求的功能可⽤前,可以使⽤它作为临时解决⽅案.在不使⽤可⽤规则类型的情况下,可以⾃⼰使⽤此⽅法对整个转换进⾏编程.如果要进⾏此操作,还必须亲⾃对监控器实施消息的转换.
Invertierungsroutine
步骤
输⼊以下信息,以创建例程:
1. 在*$*$ 全局开始 ... 和 *$*$ 全局结束 ...期间,可⽤定义全局数据声明 'CLASS-DATA',随后,它们将在所有的例程中可⽤.在当前包中,在当前包中,可以使⽤'DATA'存取数据声明.
例如,这意味着可以在其他例程中使⽤中间结果,或者,如果再次调⽤相同的例程,那么可⽤重新使⽤第⼀次调⽤的结果.
注意:
只要为此请求专门保留的处理实例继续存在,那么,在序列装载期间,保持以 'CLASS-DATA '声明的数据.由于性能原因,在并⾏装载期间,已实例化的处理也不⽌使⽤⼀次.这意味着,保持处理实例中以'CLASS-DATA'声明的数据.
因此,根据该⽅案,使⽤全局数据的'CLASS-DATA' 或 'DATA'.
2. 在*$*$例程开始... 和 *$*$例程结束...之间,插⼊该例程的程序代码.
在编码中不要使⽤ SAP COMMIT (ABAP 声明:COMMIT WORK).当执⾏声明时,⽤于从源中读取的使⽤指针丢失.作为替代,使⽤ DB COMMIT(调⽤功能模块DB_COMMIT)或避免这些 COMMIT 在⼀起。
3. 请检查该例程的语法.
4. 保存该例程.
退出该编辑器以结束此例程的维护.
相关
根据批管理器中的设置,以序列的或并⾏的⽅式更新数据.
(⼀)开始例程
使⽤
在开始转换时为每个数据包执⾏开始例程.开始例程不包含任何返回值.其⽤于执⾏基本计算并将结果保存在全局数据结构或表中.系统可在其他例程中访问该结构或表.其可更改或删除数据.
开始例程参数
导⼊
REQEUST: 请求标识
DATAPAKID: 当前数据包数
导出
MONITOR: ⽤户定义监控表.使⽤ MONITOR_REC ⾏结构填充该表 (框架⾃动添加待处理的记录数).
更改
SOURCE_PACKAGE: 包含例程的输⼊字段的结构
抬⾼
CX_RSROUT_ABORT: 若在例程内触发类型为 cx rsrout_abort 的异常,整个装载处理将终⽌.在提起监控中将请求标记为已终⽌.当前数据包的处理已终⽌.在严重错误的情况下,这可能有效.
范例
使⽤ ERP 系统中总帐: 业务额数据源 (FI_GL_1) 将数据装载到FIGL: 业务额数据存储对象 (0FIGL_O06).
需要创建开始例程,该例程删除数据包中的所有记录,这些记录的借⽅和贷⽅过帐为零.
1. 创建转换.转换的源包含字段总计借⽅过帐 (UMSOL) 和总计贷⽅过帐 (UMHAB),这些字段分配到信息对象总计借⽅过帐(0DEBIT) 和总计贷⽅过帐(0CREDIT).
2. 选择创建开始例程.打开例程编辑器.
3. 转到例程的本地备件,并插⼊以下编码⾏:
*$*$ 例程开始 - 仅在该⾏下插⼊代码 *-*
... "在此插⼊代码
DELETE SOURCE_PACKAGE 在此 UMHAB = 0 和 UMSOL = 0
*$*$ 例程结束 - 仅在此⾏前插⼊代码 *-*
删除语句是唯⼀需要过滤借⽅和贷⽅过帐的⾏,这些过帐不包含来⾃数据包的值.
4. 退出例程编辑器.
5. 保存转换.开始例程前的铅笔图标指⽰退出开出例程.
(⼆)关键值或特性的例程
使⽤
关键值或特性的例程可⽤作规则类型.也就是说,可⽤把例程定义为关键值或特性的转换规则.
在信息块案例中,也可以选择带有单位的例程.这将使例程也含有返回参数'UNIT',它使您可以存储需要的关键值单位,如, 'PC'.例如,可以使⽤该选项把源中可⽤的单位千克转换成⽬标中的吨.
关键值或特性例程中的参数
导⼊
REQEUST: 请求标识
DATAPAKID:当前包的编号
SOURCE_FIELDS:在例程的⽤户界⾯上定义的含输⼊字段的结构
导出
MONITOR:⽤户特定监控表.⽤ MONITOR_REC ⾏结构填充此表(框架结构⾃动添加已处理记录的编号).
RESULT:必须把计算的关键值或特性的结果分配到可⽤的 RESULT.
CURRENCY (可选的): 在有关货币的例程中,必须在此分配货币.
UNIT(可选的): 在有关单位的例程中,必须在此分配单位.
抬⾼
为了控制写⼊到⽬标中的内容,系统使⽤含例外类的例外处理:
CX_RSROUT_SKIP_RECORD:如果在例程中,随时可以触发抬⾼例外类型 cx_rsrout_skip_recor ,那么系统终⽌当前⾏的处理继⽽开始下⼀数据记录的处理.
CX_RSROUT_ABORT:如果在例程中,随时可以触发抬⾼例外类型 cx_rsrout_abort ,那么终⽌整个装载过程.在监视器中,把此请求标记为已终⽌.终⽌当前包的处理.在出现严重错误的情况下,这是有帮助的.
范例
特性例程的⽰例:
使⽤ ERP 系统中的总分类帐:交易额 (FI_GL_1)数据源把数据装载到FIGL:交易额(0FIGL_O06)数据源对象.
需要在⽬标系统中创建借⽅/贷⽅标识特性(0FI_DBCRIND)的例程,它分配借⽅的过帐的值 D 和贷⽅过帐的值 C.
1. 现在处于转换维护事务中,要显⽰规则明细,请在规则组中双击借⽅/贷⽅标识(0FI_DBCRIND).
2. 选择添加源字段来添加字段总计借⽅过帐(UMSOL)和总计贷⽅过帐(UMHAB),这样它们在您的例程中就是可⽤的.
3. 选择例程作为规则类型.该例程编辑器打开.
4. 插⼊以下代码⾏,它们返回 D 或 C 作为结果值:
*$*$ 开始例程 - 仅在该⾏以下插⼊代码 *-*
... "在此插⼊您的代码
* 例程的结果值
if SOURCE_FIELDS-umhab ne 0 and SOURCE_FIELDS-umsol eq 0.
RESULT = 'D'.
elif SOURCE_FIELDS-umhab eq 0 and SOURCE_FIELDS-umsol ne 0.
RESULT = 'C'.
el.
monitor_rec-msgid = 'ZMESSAGE'.
monitor_rec-msgty = 'E'.
monitor_rec-msgno = '001'.
monitor_rec-msgv1 = 'ERROR, D/C Indicator'.
monitor_rec-msgv2 = SOURCE_FIELDS-umhab.
monitor_rec-msgv3 = SOURCE_FIELDS-umsol.
RAISE EXCEPTION TYPE CX_RSROUT_ABORT.
endif.
*$*$ 结束例程 - 仅在该⾏以前插⼊您的代码 *-*
系统检查借⽅和贷⽅过帐是否包含以下值:
如果借⽅过帐包含不等于零的值并且贷⽅过帐包含等于零的值,那么系统分配值 D.
如果贷⽅过帐包含不等于零的值并且借⽅过帐包含等于零的值,那么系统分配值 C.
如果借⽅过帐和贷⽅过帐都包含值,那么监视器上输出错误,装载程序将终⽌.
5. 退出例程编辑器.
6. 在规则明细对话框中,选择应⽤值.
7. 保存转换.
(三)结束例程
使⽤
结束例程是包含表的例程,该表以⽬标结构的格式作为输⼊和输出参数.可在转换后使⽤该例程按包逐个后处理数据.例如,可删除不需要更新的记录或执⾏数据检查.
注意,仅复制转换中有规则的结束例程的字段。
结束例程中的参数
导⼊
REQEUST: 请求标识
DATAPAKID: 当前数据包数
导出
MONITOR: ⽤户特定监控的表.使⽤ MONITOR_REC ⾏结构填充该表 (框架⾃动添加处理的记录数).
更改
RESULT_PACKAGE: 包含所有经过转换的数据
抬⾼
CX_RSROUT_ABORT: 若在例程的任何点上触发类型为 cx rsrout_abort 的异常,整个装载处理将终⽌.在提取监控中将请求标记为已终⽌.当前包的处理终⽌.在这种严重错误的情况下,其可能有效.
范例
使⽤ ERP 系统中总帐: 业务额 (FI_GL_1)数据源将数据装载到FIGL: 业务额 (0FIGL_O06) 数据存储对象.
需要创建结束例程,该例程填充附加计划/实际标识 (ZPLACTUAL) 信息对象.要执⾏该操作,由例程
读取值类型字段.若值为 10(实际),系统将值
A 写⼊到计划/实际标识 (ZPLACTUAL) 信息对象;若值为 20 (计划),系统将值 P 写⼊到计划/实际标识(ZPLACTUAL) 信息对象.
1. 在转换维护事务中.选择创建结束例程.例程编辑器打开.
2. 插⼊以下编码⾏:
*$*$ begin of routine - inrt your code only below this line
... "inrt your code here
loop at RESULT_PACKAGE assigning <RESULT_FIELDS>
where vtype eq '010' or vtype eq '020'.
ca <RESULT_FIELDS>-vtype.
when '010'.
<RESULT_FIELDS>-/bic/zplactual = 'A'. "Actual
when '010'.
<RESULT_FIELDS>-/bic/zplactual = 'P'. "Plan endca.
endloop.
*$*$ end of routine - inrt your code only before this line
*-*
result_package 上的编码循环,并搜索含值类型 10 或 20 的值.系统然后将相应的值传递到这些值的计划/实际变式(ZPLACTUAL) 信息对象中.
3. 退出例程编辑器.
4. 保存转换.结束例程前的铅笔图标标识退出结束例程.
(四) 专家例程
此类型的例程仅⽤于特殊情况.如果提供的转换功能不⾜以满⾜您的要求,那么可以使⽤专家程序.在标准系统中所要求的功能可⽤前,可以使⽤它作为临时解决⽅案.在不使⽤可⽤规则类型的情况下,可
以⾃⼰使⽤此⽅法对整个转换进⾏编程.如果要进⾏此操作,还必须亲⾃对监控器实施消息的转换.
(五)反冲例程(Invertierungsroutine)
反冲例程
使⽤
在例程编辑器中,为之前定义的例程创建反向例程。例如,当在虚拟提供者中执⾏查询时,需要此例程。在这种情况下,需要⽅向例程传输导航步骤的选择标准⾄提取器的选择标准。当您使⽤报表-报表界⾯转到另⼀个 SAP 系统时,同样应⽤它。如果您不创建反向例程,系统将选择所有值。
可为所有类型的例程创建反向例程。以下例程适⽤:
使⽤专家例程,没有分段到条件。
使⽤开始例程,系统执⾏分段到条件。系统应⽤此例程完成源结构。源结构是开始和结束点。
使⽤结束例程,⽬标结构时开始和结束点。
反向例程有⽅法反转。
范例
在这个例⼦中,⽬标特征中的德语代码 'HERR' 和 'FRAU' 被映射到源字段 PASSFORM(地址格式)的英⽂代码 'MR' 和 'MRS'。源字段中的所有其它值都映射到初始值。
编码例程如下:
*$*$ 例程开始 - 在此⾏下插⼊您的代码 *-*
CASE SOURCE_FIELDS-passform.
WHEN 'HERR'. RESULT = 'MR'.
WHEN 'FRAU'. RESULT = 'MRS'.
WHEN OTHERS. RESULT = space.
ENDCASE.
*$*$ 例程结束 - 在此⾏前插⼊您的代码 *-*
ENDMETHOD. "compute_0PASSFORM
相应的反向例程如下:
*$*$ 反向例程开始 - 在此⾏下插⼊您的代码 *-*
DATA l_r_t TYPE REF TO cl_rsmds_t.
IF i_r_lt_outbound->is_universal( ) EQ rsmds_c_boolean-true.
* If query requests all values for characteristic 0PASSNAME
* request also all values from source field PASSNAME
c_r_lt_inbound = cl_rsmds_t=>get_universal_t( ).
c_exact = rs_c_true. "Inversion is exact
ELSE.
TRY.
IF me->p_r_t_mrs IS INITIAL.
* Create t for condition PASSFORM = 'FRAU'
me->p_r_t_mrs =i_r_univer_inbound->create_t_from_string( 'PASSFORM = ''FRAU''' ).
ENDIF.
IF me->p_r_t_mr IS INITIAL.
* Create t for condition PASSFORM = 'HERR'
me->p_r_t_mr =i_r_univer_inbound->create_t_from_string( 'PASSFORM = ''HERR''' ).
ENDIF.
IF me->p_r_t_space IS INITIAL.
* Create t for condition NOT ( PASSFORM = 'FRAU' OR PASSFORM= 'HERR' )
l_r_t = me->p_r_t_mr->unite( me- >p_r_t_mrs).
me->p_r_t_space = l_r_t->complement( ).
ENDIF.
* 组成内向选择
c_r_lt_inbound = cl_rsmds_t=>get_empty_t( ).
* 检查外向选择是否包含值 'MR'
IF i_r_lt_outbound->contains( 'MR' ) EQrsmds_c_boolean-true.
c_r_lt_inbound = c_r_lt_inbound->unite(me>p_r_t_mr ).
ENDIF.
* 检查外向选择是否包含值 'MRS'
IF i_r_lt_outbound->contains( 'MRS' ) EQrsmds_c_boolean-true.
c_r_lt_inbound = c_r_lt_inbound->unite(me>p_r_t_mrs ).
ENDIF.
* 检查外向选择是否包含初始值
IF i_r_lt_outbound->contains( space ) EQrsmds_c_boolean-true.
c_r_lt_inbound = c_r_lt_inbound->unite(me>p_r_t_space ).
ENDIF.
c_exact = rs_c_true. "Inversion is exact
CATCH cx_rsmds_dimension_unknown