BADI 构建方法(NEW BADI 实施)
介绍
SAP Business Planning and Consolidation(SAP BPC)提供SAP Netweaver版本和Microsoft平台版本。SAP BPC Netweaver的优势在于可以使用ABAP(高级业务应用程序编程),即SAP编程语言。
可以使用SAP BAdI(Business Add Ins)功能将SAP BPC脚本逻辑转换为ABAP。BAdI是对SAP代码的标准版本的增强。BAdI的性能明显优于SAP BPC脚本。
本文档结合了一些提示和技巧,可帮助您为SAP BPC创建BAdI实现。
选择合适的BAdI
通过事务SE18打开BAdi Builder以显示所有可用的增强点条目。可以使用与SAP BPC相关的几个BAdI(例如UJR_WRITE_BACK,UJ_CUSTOM_LOGIC),并且可以通过搜索(按F4)找到字符串UJ *来找到。选择最适合您需求的那个。
图1:BAdI Builder
显示所选增强点后,右键单击“实施”并选择“创建BAdI实施”或选择现有实施。
图2:创建BAdI实现
需要创建几个对象:
- 类(例如ZCLASS_BADI_JOURNAL); 根据BAdI实现创建一个新类,
- 增强实施(例如ZBPC_ELEMENTARYPACK); 一个增强实现可以包含多个BAdI实现,
- BAdI实现(例如ZBPC_BADI_JOURNAL_C_IFRS_DEV)。一个BAdI实现可以链接到一个或多个应用程序。
访问现有BAdI编码的另一种方法是通过事务SE80 Object Navigator。输入所需的类并打开方法以直接更改它。
图3:对象导航器
过滤BAdI
一旦增强实施可用,您需要过滤BAdI。这保证了代码仅针对所需的应用程序集和应用程序执行(分别对应于InfoArea和InfoCube)。通过多次单击“创建过滤器组合”,可以添加多个过滤器组合。
过滤器特定于每个增强点。下面是UJR_WRITE_BACK增强点的示例。
图4:过滤BAdI
Module_ID可以有多个值:
COMM | 评论条目 |
DM | 数据管理器 |
DOCS | 文件修改 |
JRN | 期刊录入 |
人 | 手动输入 |
声明数据
在方法的开头,声明了几个常量,字段符号等。常量是固定值,例如值AST(帐户类型资产)。如果必须更改此值,则只需执行一次更改。
CONSTANTS: c_acctype_act TYPE c LENGTH 3 VALUE 'AST', "asset
字段符号和数据引用允许动态访问数据对象。无需像使用静态访问一样指定对象的名称,字段符号和数据引用允许您访问和传递在运行时之前您不知道其名称和属性的数据对象。
FIELD-SYMBOLS:
TYPE table, "result itab
本文档中使用的每个自定义对象的声明在附件中列出。
访问传入数据
便于访问任何维度需要大量编码,这是由于BAdI实现的抽象性。
以下代码允许访问维度帐户,并且应该针对需要查阅或更新的每个维度重复这些代码。
"Find the account dimension by its type
LOOP AT it_dim_obj ASSIGNING
WHERE dim_type = uj00_cs_dim_type-account.
lo_account ?=
-dim_obj.
ls_account =
.
ENDLOOP.
"preparation: create data structure and assign fields
CREATE DATA lr_data LIKE LINE OF ct_array.
ASSIGN lr_data->* TO
.
ASSIGN COMPONENT ls_account-dimension OF
STRUCTURE
TO
. "account
对象it_dim_obj包含维度的元数据。您可以找到每个维度及其所有属性的InfoObject名称。
图5:IT_DIM_OBJ的内容
图6:IT_DIM_OBJ(1)-T_ATTR的内容
图7:LS_ACCOUNT的内容
对象uj00_cs_dim_type在全局类型池UJ00中定义。因此,对于其他维度,uj00_cs_dim_type-account可以由uj00_cs_dim_type-entity等替换。
begin of uj00_cs_dim_type,
account type uj_dim_type value 'A',
entity type uj_dim_type value 'E',
time type uj_dim_type value 'T',
currency type uj_dim_type value 'R',
category type uj_dim_type value 'C',
datasrc type uj_dim_type value 'D',
intco type uj_dim_type value 'I',
subtables type uj_dim_type value 'S',
user type uj_dim_type value 'U',
group type uj_dim_type value 'G',
end of uj00_cs_dim_type.
假设需要属性帐户类型和帐户组。使用函数get_attr_list获取维度的属性列表。实际成员通过函数read_mbr_data获取。
"Get attribute AccountType / Account Group
lo_account->get_attr_list( IMPORTING et_attr_list = lt_attr_list ).
LOOP AT lt_attr_list INTO ls_attr_list
WHERE attribute_name = ujr0_c_attr_acctype OR
attribute_name = c_attr_group.
APPEND ls_attr_list-attribute_name TO lt_attr_name.
ENDLOOP.
"Get Members of account
CALL METHOD lo_account->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name "columns:attributes name list
* it_hier_list = lt_hier_name "columns:hieracies name list
IMPORTING
er_data = lr_data.
ASSIGN lr_data->* TO
。
图8:LT_ACCOUNT_MBR的内容
内部表ct_array是一个生成的对象,它包含来自BPC应用程序的所有记录。循环使用此表ct_array可以访问每条记录。
LOOP AT ct_array INTO .
在第一个循环期间,会创建几个对象来捕获新的计算记录。对象lt_tab
是在运行时创建的临时对象,其结构与ct_array相同。然后将lt_tab的结构分配给字段符号所以后者有一个结构,它是一个表。为了能够使用表的一行,字符符号是类似的创建。可以使用ASSIGN
COMPONENT
语句将字段符号分配给一行的单个字段。例如,然后可以通过访问列帐户。
IF
IS NOT ASSIGNED.
CREATE DATA lt_tab LIKE ct_array.
ASSIGN lt_tab->* TO
.
CREATE DATA lr_data_r LIKE LINE OF ct_array.
ASSIGN lr_data_r->* TO
.
ASSIGN COMPONENT ls_account-dimension OF
STRUCTURE
TO
. "account
ENDIF.
接下来,我们搜索包含当前帐户及其属性的帐户成员数据的内部表。这些属性保存在字段符号中 和
。
"get account members
READ TABLE
WITH TABLE KEY (ujr0_c_member_id) =
ASSIGNING
.
IF sy-subrc = 0.
ASSIGN COMPONENT c_attr_acctype OF
STRUCTURE
TO
.
ASSIGN COMPONENT c_attr_group OF
STRUCTURE
TO
.
现在可以通过相应的字段符号访问所有字段。可以使用这些字段符号执行各种计算和操作。
访问现有数据
当新数据从BPC发送到后端的BW InfoCube时,有时我们需要访问BW InfoCube中已存在的数据。数据分解就是一个很好的例子。在BPC中,可以在父级别输入数据,然后可以按比例将这些数据分配给现有数据。这对于实体和时间等维度最有意义。
以下代码检索实体的层次结构信息,并且还为时间组件重复。
lo_entity->get_hier_list( IMPORTING et_hier_info = lt_hier_info ).
LOOP AT lt_hier_info INTO ls_hier_info.
APPEND ls_hier_info-hier_name TO lt_hier_name.
ENDLOOP.
数据按比例分解为现有数据。因此,我们需要查找与来自BPC应用程序的数据相对应的现有数据。这是通过启动RSDRI查询来实现的,该查询需要返回要返回的维度列表以及要应用的过滤器列表。第一步是检索多维数据集元数据。
CLEAR ls_application.
lo_appl_mgr->get(
EXPORTING
if_with_measures = abap_false
if_summary = abap_false
IMPORTING
es_application = ls_application ).
如果处理的行是父级,我们需要让其子级能够在子级之后分发数据。必须针对时间维度重复此代码。
CALL METHOD lo_entity->get_children_mbr
EXPORTING
i_parent_mbr =
i_level = -1
if_only_base_mbr = abap_true
IMPORTING
et_member = lt_ent_children.
DESCRIBE TABLE lt_ent_children LINES nr_ent_chil.
我们准备一个范围来过滤实体基础成员。必须针对时间维度扩展相同的范围。
LOOP AT lt_ent_children INTO ls_base_en.
ls_range-dimension = 'COMPANY'.
ls_range-low = ls_base_en.
APPEND ls_range TO lt_range.
ENDLOOP.
我们将多维数据集维度保存在列表中并扩展范围以使用与BPC中相同的限制。
REFRESH lt_dim_list.
LOOP AT ls_application-dimensions INTO ls_dimensions.
APPEND ls_dimensions-dimension TO lt_dim_list.
ls_range-dimension = ls_dimensions-dimension.
ASSIGN COMPONENT ls_dimensions-dimension
OF STRUCTURE
TO
.
ls_range-low =
.
APPEND ls_range TO lt_range.
ENDLOOP.
我们构建一个结构来捕获RSDRI查询的结果
lo_appl_mgr->create_data_ref(
EXPORTING
i_data_type = 'T'
it_dim_name = lt_dim_list
if_tech_name = abap_false
if_signeddata = abap_true
IMPORTING
er_data = lr_data ).
ASSIGN lr_data->* TO
.
现在我们可以执行RSDRI查询,该查询从SAP BW InfoCube检索所需日期并将其存储在字段符号中
TRY.
lo_query = cl_ujo_query_factory=>get_query_adapter(
i_appset_id = lv_environment_id
i_appl_id = lv_application_id ).
lo_query->run_rsdri_query(
EXPORTING
it_dim_name = lt_dim_list
it_range = lt_range
if_check_security = abap_false
IMPORTING
et_data =
et_message = lt_message
).
CATCH cx_ujo_read.
ENDTRY.
测试你的申请
为了调试ABAP编码,设置外部断点并(un)发布测试日志。选择要开始调试的代码行,然后单击工具栏中的红色按钮设置/删除外部断点(Ctrl + Shift + F9)。请注意,所选行前面会出现一个图标。现在,您可以使用相同的SAP用户(联合国)发布测试日志,然后您应该输入调试器。现在,您逐步执行代码并检查所有字段的内容。
图9:在类构建器中进行调试
结论
SAP BPC Netweaver可以使用SAP编程语言ABAP。BAdI是对SAP代码的标准版本的增强。BAdI的性能明显优于SAP BPC脚本。这些功能实现了无限的可能性。
附件
本附件包含此见解中包含的所有字段的ABAP声明。
DATA:
ls_record_r TYPE REF TO data,
lt_attr_list TYPE uja_t_attr, "Attributes info
ls_attr_list TYPE uja_s_attr,
lt_attr_name TYPE uja_t_attr_name, "Attribute names
lr_data TYPE REF TO data,
lt_tab TYPE REF TO data,
ls_account TYPE ujr_s_dim_handler, "account
lo_account TYPE REF TO if_uja_dim_data.
FIELD-SYMBOLS:
TYPE ujr_s_dim_handler,
TYPE HASHED TABLE, "All account members
TYPE any,
TYPE uj_dim_member, "account member of current rec
TYPE any, "account group
TYPE any, "account type
TYPE table, "result itab
TYPE any, "result record
TYPE uj_dim_member,"account member of result rec
TYPE any, "attr GROUP of result record
BADI 构建方法(NEW BADI 实施)
介绍
SAP Business Planning and Consolidation(SAP BPC)提供SAP Netweaver版本和Microsoft平台版本。SAP BPC Netweaver的优势在于可以使用ABAP(高级业务应用程序编程),即SAP编程语言。
可以使用SAP BAdI(Business Add Ins)功能将SAP BPC脚本逻辑转换为ABAP。BAdI是对SAP代码的标准版本的增强。BAdI的性能明显优于SAP BPC脚本。
本文档结合了一些提示和技巧,可帮助您为SAP BPC创建BAdI实现。
选择合适的BAdI
通过事务SE18打开BAdi Builder以显示所有可用的增强点条目。可以使用与SAP BPC相关的几个BAdI(例如UJR_WRITE_BACK,UJ_CUSTOM_LOGIC),并且可以通过搜索(按F4)找到字符串UJ *来找到。选择最适合您需求的那个。
图1:BAdI Builder
显示所选增强点后,右键单击“实施”并选择“创建BAdI实施”或选择现有实施。
图2:创建BAdI实现
需要创建几个对象:
- 类(例如ZCLASS_BADI_JOURNAL); 根据BAdI实现创建一个新类,
- 增强实施(例如ZBPC_ELEMENTARYPACK); 一个增强实现可以包含多个BAdI实现,
- BAdI实现(例如ZBPC_BADI_JOURNAL_C_IFRS_DEV)。一个BAdI实现可以链接到一个或多个应用程序。
访问现有BAdI编码的另一种方法是通过事务SE80 Object Navigator。输入所需的类并打开方法以直接更改它。
图3:对象导航器
过滤BAdI
一旦增强实施可用,您需要过滤BAdI。这保证了代码仅针对所需的应用程序集和应用程序执行(分别对应于InfoArea和InfoCube)。通过多次单击“创建过滤器组合”,可以添加多个过滤器组合。
过滤器特定于每个增强点。下面是UJR_WRITE_BACK增强点的示例。
图4:过滤BAdI
Module_ID可以有多个值:
COMM | 评论条目 |
DM | 数据管理器 |
DOCS | 文件修改 |
JRN | 期刊录入 |
人 | 手动输入 |
声明数据
在方法的开头,声明了几个常量,字段符号等。常量是固定值,例如值AST(帐户类型资产)。如果必须更改此值,则只需执行一次更改。
CONSTANTS: c_acctype_act TYPE c LENGTH 3 VALUE 'AST', "asset
字段符号和数据引用允许动态访问数据对象。无需像使用静态访问一样指定对象的名称,字段符号和数据引用允许您访问和传递在运行时之前您不知道其名称和属性的数据对象。
FIELD-SYMBOLS:
TYPE table, "result itab
本文档中使用的每个自定义对象的声明在附件中列出。
访问传入数据
便于访问任何维度需要大量编码,这是由于BAdI实现的抽象性。
以下代码允许访问维度帐户,并且应该针对需要查阅或更新的每个维度重复这些代码。
"Find the account dimension by its type
LOOP AT it_dim_obj ASSIGNING
WHERE dim_type = uj00_cs_dim_type-account.
lo_account ?=
-dim_obj.
ls_account =
.
ENDLOOP.
"preparation: create data structure and assign fields
CREATE DATA lr_data LIKE LINE OF ct_array.
ASSIGN lr_data->* TO
.
ASSIGN COMPONENT ls_account-dimension OF
STRUCTURE
TO
. "account
对象it_dim_obj包含维度的元数据。您可以找到每个维度及其所有属性的InfoObject名称。
图5:IT_DIM_OBJ的内容
图6:IT_DIM_OBJ(1)-T_ATTR的内容
图7:LS_ACCOUNT的内容
对象uj00_cs_dim_type在全局类型池UJ00中定义。因此,对于其他维度,uj00_cs_dim_type-account可以由uj00_cs_dim_type-entity等替换。
begin of uj00_cs_dim_type,
account type uj_dim_type value 'A',
entity type uj_dim_type value 'E',
time type uj_dim_type value 'T',
currency type uj_dim_type value 'R',
category type uj_dim_type value 'C',
datasrc type uj_dim_type value 'D',
intco type uj_dim_type value 'I',
subtables type uj_dim_type value 'S',
user type uj_dim_type value 'U',
group type uj_dim_type value 'G',
end of uj00_cs_dim_type.
假设需要属性帐户类型和帐户组。使用函数get_attr_list获取维度的属性列表。实际成员通过函数read_mbr_data获取。
"Get attribute AccountType / Account Group
lo_account->get_attr_list( IMPORTING et_attr_list = lt_attr_list ).
LOOP AT lt_attr_list INTO ls_attr_list
WHERE attribute_name = ujr0_c_attr_acctype OR
attribute_name = c_attr_group.
APPEND ls_attr_list-attribute_name TO lt_attr_name.
ENDLOOP.
"Get Members of account
CALL METHOD lo_account->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name "columns:attributes name list
* it_hier_list = lt_hier_name "columns:hieracies name list
IMPORTING
er_data = lr_data.
ASSIGN lr_data->* TO
。
图8:LT_ACCOUNT_MBR的内容
内部表ct_array是一个生成的对象,它包含来自BPC应用程序的所有记录。循环使用此表ct_array可以访问每条记录。
LOOP AT ct_array INTO .
在第一个循环期间,会创建几个对象来捕获新的计算记录。对象lt_tab
是在运行时创建的临时对象,其结构与ct_array相同。然后将lt_tab的结构分配给字段符号所以后者有一个结构,它是一个表。为了能够使用表的一行,字符符号是类似的创建。可以使用ASSIGN
COMPONENT
语句将字段符号分配给一行的单个字段。例如,然后可以通过访问列帐户。
IF
IS NOT ASSIGNED.
CREATE DATA lt_tab LIKE ct_array.
ASSIGN lt_tab->* TO
.
CREATE DATA lr_data_r LIKE LINE OF ct_array.
ASSIGN lr_data_r->* TO
.
ASSIGN COMPONENT ls_account-dimension OF
STRUCTURE
TO
. "account
ENDIF.
接下来,我们搜索包含当前帐户及其属性的帐户成员数据的内部表。这些属性保存在字段符号中 和
。
"get account members
READ TABLE
WITH TABLE KEY (ujr0_c_member_id) =
ASSIGNING
.
IF sy-subrc = 0.
ASSIGN COMPONENT c_attr_acctype OF
STRUCTURE
TO
.
ASSIGN COMPONENT c_attr_group OF
STRUCTURE
TO
.
现在可以通过相应的字段符号访问所有字段。可以使用这些字段符号执行各种计算和操作。
访问现有数据
当新数据从BPC发送到后端的BW InfoCube时,有时我们需要访问BW InfoCube中已存在的数据。数据分解就是一个很好的例子。在BPC中,可以在父级别输入数据,然后可以按比例将这些数据分配给现有数据。这对于实体和时间等维度最有意义。
以下代码检索实体的层次结构信息,并且还为时间组件重复。
lo_entity->get_hier_list( IMPORTING et_hier_info = lt_hier_info ).
LOOP AT lt_hier_info INTO ls_hier_info.
APPEND ls_hier_info-hier_name TO lt_hier_name.
ENDLOOP.
数据按比例分解为现有数据。因此,我们需要查找与来自BPC应用程序的数据相对应的现有数据。这是通过启动RSDRI查询来实现的,该查询需要返回要返回的维度列表以及要应用的过滤器列表。第一步是检索多维数据集元数据。
CLEAR ls_application.
lo_appl_mgr->get(
EXPORTING
if_with_measures = abap_false
if_summary = abap_false
IMPORTING
es_application = ls_application ).
如果处理的行是父级,我们需要让其子级能够在子级之后分发数据。必须针对时间维度重复此代码。
CALL METHOD lo_entity->get_children_mbr
EXPORTING
i_parent_mbr =
i_level = -1
if_only_base_mbr = abap_true
IMPORTING
et_member = lt_ent_children.
DESCRIBE TABLE lt_ent_children LINES nr_ent_chil.
我们准备一个范围来过滤实体基础成员。必须针对时间维度扩展相同的范围。
LOOP AT lt_ent_children INTO ls_base_en.
ls_range-dimension = 'COMPANY'.
ls_range-low = ls_base_en.
APPEND ls_range TO lt_range.
ENDLOOP.
我们将多维数据集维度保存在列表中并扩展范围以使用与BPC中相同的限制。
REFRESH lt_dim_list.
LOOP AT ls_application-dimensions INTO ls_dimensions.
APPEND ls_dimensions-dimension TO lt_dim_list.
ls_range-dimension = ls_dimensions-dimension.
ASSIGN COMPONENT ls_dimensions-dimension
OF STRUCTURE
TO
.
ls_range-low =
.
APPEND ls_range TO lt_range.
ENDLOOP.
我们构建一个结构来捕获RSDRI查询的结果
lo_appl_mgr->create_data_ref(
EXPORTING
i_data_type = 'T'
it_dim_name = lt_dim_list
if_tech_name = abap_false
if_signeddata = abap_true
IMPORTING
er_data = lr_data ).
ASSIGN lr_data->* TO
.
现在我们可以执行RSDRI查询,该查询从SAP BW InfoCube检索所需日期并将其存储在字段符号中
TRY.
lo_query = cl_ujo_query_factory=>get_query_adapter(
i_appset_id = lv_environment_id
i_appl_id = lv_application_id ).
lo_query->run_rsdri_query(
EXPORTING
it_dim_name = lt_dim_list
it_range = lt_range
if_check_security = abap_false
IMPORTING
et_data =
et_message = lt_message
).
CATCH cx_ujo_read.
ENDTRY.
测试你的申请
为了调试ABAP编码,设置外部断点并(un)发布测试日志。选择要开始调试的代码行,然后单击工具栏中的红色按钮设置/删除外部断点(Ctrl + Shift + F9)。请注意,所选行前面会出现一个图标。现在,您可以使用相同的SAP用户(联合国)发布测试日志,然后您应该输入调试器。现在,您逐步执行代码并检查所有字段的内容。
图9:在类构建器中进行调试
结论
SAP BPC Netweaver可以使用SAP编程语言ABAP。BAdI是对SAP代码的标准版本的增强。BAdI的性能明显优于SAP BPC脚本。这些功能实现了无限的可能性。
附件
本附件包含此见解中包含的所有字段的ABAP声明。
DATA:
ls_record_r TYPE REF TO data,
lt_attr_list TYPE uja_t_attr, "Attributes info
ls_attr_list TYPE uja_s_attr,
lt_attr_name TYPE uja_t_attr_name, "Attribute names
lr_data TYPE REF TO data,
lt_tab TYPE REF TO data,
ls_account TYPE ujr_s_dim_handler, "account
lo_account TYPE REF TO if_uja_dim_data.
FIELD-SYMBOLS:
TYPE ujr_s_dim_handler,
TYPE HASHED TABLE, "All account members
TYPE any,
TYPE uj_dim_member, "account member of current rec
TYPE any, "account group
TYPE any, "account type
TYPE table, "result itab
TYPE any, "result record
TYPE uj_dim_member,"account member of result rec
TYPE any, "attr GROUP of result record