BOL其实是一系列接口和函数的总称。目的是为了更新crm的一些bapi的使用,实现crm的所有功能。

有一些比较常见或者重要的class

CL_CRM_BOL_QUERY_SERVICE

查询用到的。

CL_CRM_BOL_ENTITY

存放数据实体,增删改查需要用到。

IF_BOL_TRANSACTION_CONTEXT

You use thisinterface to control transaction behavior.

IF_BOL_BO_COL

可以类比为内表,查询出来的数据都是一个collection,需要进一步读成entity。

如果你开始使用hard code形式做bol编程,一开始的几行是这样写的。

DATA: lv_bol_coreTYPE REF TO cl_crm_bol_core.
lv_bol_core =cl_crm_bol_core=>get_instance( ).
lv_bol_core->start_up(‘MY_COMPONENT_SET’ ).

cl_crm_bol_core你可以理解为就是crm的bol服务。你要使用bol,就要调用这个服务。

而cl_crm_bol_core=>get_instance( )就是将这个服务实例化。

最后这个start_up里面填的是组件集。我们调用的bol都是一个组件集的形式被调用的,

目的是为了减少调用的组件数量,毕竟,这还是比较耗资源的;为啥不设计为直接调用组件,因为一般来说,我们都不会只调用一个组件,如果调用多个组件那么就要起多个服务实例,也很耗资源;当然你也可以填ALL,就是把所有组件都调用出来,不过还是耗资源。正因为如此,我们有一些系统归好类的组件集,比如ONEORDER,不多也不少,刚好足够你完成交易相关的事务。具体有哪些定义好的组件集,用事务代码GENIL_MODEL_BROWSER查看。

那么的确还是会出现一个组件集不够用的情况,可以再加载其他组件的。

不过是一个组件一个组件的加载。

DATA:lv_component_name type crmt_component_name.
lv_component_name ='ANOTHER_COMPONENT'.
lv_bol_core->load_component(lv_component_name ).

想知道目前一共加载了哪些组件,可以用下面的代码。

DATA: lv_obj_modeltype ref to if_genil_obj_model,
lv_obj_model_ typeref to cl_crm_genil_obj_model,
lt_components_loadedtype genil_component_tab.
lv_obj_model =  cl_crm_genil_model_service=>get_runtime_model( ).
lv_obj_model_ ?=lv_obj_model.
lt_components_loaded= lv_obj_model_->get_components_loaded( ).

谈到BOL,就不得不谈到Generic Interaction Layer (GenIL)一般交互层。

先说配置的地方:SPRO》客户关系管理》crm跨应用组件》一般交互层。

BOL实际上是个很虚的东西,可以理解为它只是定义了数据结构和相互关系。

而实际的数据怎么来的,它是没有的。一般交互层就是干这个的。

实际数据来源于GenIL,它是一个class,有构造函数和很多数据拉取的方法。

它可以获取到数据,比如通过调bapi的方式;它可以做增强,这样可以实现不改bol的情况对标准的bol进行数据控制,这个控制可是底层数据上的,不需要一个一个报表慢慢改了。

在基本设置里面,我们可以做两件事情;定义组件集和定义组件。

组件集就是一个包含多个组件的集合,仅此而已。

组件是关键,这里的每个组件,就是狭义上一个bol。

一个组件,描述是不可少的。更重要的是其他3个指标,实施类,对象表,模型表。

实施类里面放的就是具体数据操作的代码。

对象表放的是组件的对象,这个和后面写代码的时候用到的实体是对应的。

模型表放的是对象间的关系。

这个实施类不是随便建的,需要继承

CL_CRM_GENIL_ABSTR_COMPONENT2

或者CL_CRM_GENIL_ABSTR_COMPONENT。

创建完毕后要增强两个方法,为了实现3个指标的关联。

METHODif_genil_appl_model~get_object_props.CLEAR rt_obj_props.SELECT * FROM 对象表INTO CORRESPONDING FIELDS OF TABLErt_obj_props.ENDMETHOD.
METHODif_genil_appl_model~get_model.CLEAR rt_relation_det.SELECT * FROM 模型表INTO CORRESPONDING FIELDS OF TABLErt_relation_det.ENDMETHOD.

这个实施类下面还有很多的方法,看方法名顾名思义就能知道意思,对于特定的业务场景增强这些方法很有用。

对象表和模型表的结构是什么?这个你可以参考其他crm标准组件的设定。他们在设定的时候不是每个属性都做为结构的一部分,所有的属性有哪些可以参考上面增强代码对应的那两个表结构。至于具体每个字段代表什么意思,用查看bol的事务代码GENIL_MODEL_BROWSER看标准的组件是怎么搞的就明白了。其实理解起来不难,每个字段名的意思相当于就是字面意思。

我们先说说bol的查。可以运行下下面这个代码,对bol的查询有个感性认识。

DATA: lv_obj_modelTYPE REF TO if_genil_obj_model.
lv_obj_model =cl_crm_genil_model_service=>get_runtime_model( ).
DATA lt_query_namesTYPE crmt_ext_obj_name_tab.
CALL METHODlv_obj_model->get_object_listEXPORTING
*   iv_object_kind =if_genil_obj_model=>query_object   "搜索对象iv_object_kind =if_genil_obj_model=>dquery_object "动态搜索对象IMPORTINGet_object_list = lt_query_names.

这个lt_query_names显示的就是当前运行时你可以使用的搜索对象的名称。

这个方法还有很多用处,具体可以看看传入参数就明白了。

真正使用一个bol查询,可以参考下面的代码。

DATA: lv_query TYPEREF TO cl_crm_bol_query_service.
lv_query =cl_crm_bol_query_service=>get_instance( 搜索对象 ).
lv_query->set_property( iv_attr_name =  '查询条件名'iv_value = '值' ).
DATA: 变量 TYPE string.
变量 = lv_query->get_property_as_string( '字段名' )."查询结果是有且唯一的实体
DATA: lv_result TYPEREF TO if_bol_entity_col.
lv_result = lv_query->get_query_result( )."查询结果是数量不确定的实体集DATA:lv_advanced_query TYPE REF TO cl_crm_bol_dquery_service.
lv_advanced_query =cl_crm_bol_dquery_service=>get_instance( 动态搜索对象 ).
DATA: lt_params TYPEcrmt_name_value_pair_tab,
ls_params TYPEcrmt_name_value_pair.
ls_params-name ='MAX_HITS' . ls_params-value = '最大结果数'.
APPEND ls_params TOlt_params.
lv_advanced_query->set_query_parameters(it_parameters = lt_params ).
lv_advanced_query->add_selection_param( iv_attr_name = '查询条件名'iv_sign= 'I'iv_option = 'GT'iv_low= '5'iv_high= '' ).
DATA: lv_result TYPEREF TO if_bol_entity_col.
lv_result =lv_advanced_query->get_query_result( ).

一个小彩蛋,我们可以存储查询条件为一个类似于变式的查询模板,

这样下次只要记住模板名,就可以直接使用了。

lv_advanced_query->save_query_as_template( iv_query_id = 模板名iv_overwrite= abap_true ).
lv_advanced_query->load_query_template(iv_query_id = 模板名’).

bol的查询是围绕着接口cl_crm_bol_dquery_service展开的。这个接口还有其他很多

有用的方法,可以点进去好好研究。

下面说说数据的读取。通过查询或者其他方式得来的数据,都是实体。

将他们转变为变量,结构,内表可以参考下面的代码。

DATA:lv_iteratorTYPE REF TO if_bol_entity_col_iterator."实体集迭代器
lv_iterator =lv_result->get_iterator.
DATA: lv_entity TYPEREF TO cl_crm_bol_entity.
lv_entity= lv_iterator->get_first( )."指向实体集第一行
WHILE lv_entity IS BOUND."判断实体是否存在DATA: lv_firstname TYPE string,lv_lastname TYPE string.lv_firstname =lv_entity->get_property_as_string( ‘firstname’ )."实体字段到变量lv_lastname =lv_entity->get_property_as_string( ‘lastname’ ).DATA: lv_default_address TYPE REF TOcl_crm_bol_entity.lv_default_address =lv_entity->get_related_entity(‘defaultaddress’)."获取此实体关联的实体DATA: lv_addresses TYPE REF TOif_bol_entity_col.lv_addresses =lv_entity->get_related_entities( ‘addresses’ )."获取此实体关联的实体集lv_entity = lv_iterator->get_next( ).”指向下一行
ENDWHILE.

接下来谈bol的增和改。首先类似于abap的modify,bol把增和改也是合并起来考虑的,根据关键字,有则改之无则新增。纯新增的代码可以参考下面。

* 1. Build parametersto create an entity:
* here an orderentity with technical name ‘BTOrder’
DATA: lt_params TYPEcrmt_name_value_pair_tab,
ls_params TYPEcrmt_name_value_pair.
ls_params-name =‘process_type’.
ls_params-value =‘ta’.
APPEND ls_params TOlt_params.
* 2. Get factory forbusiness object
DATA:lv_order_factory TYPE REF TO cl_crm_bol_entity_factory.
lv_order_factory =lv_bol_core->get_entity_factory( ‘btorder’ ).
* 3. Create rootentity
DATA: lv_order TYPEREF TO cl_crm_bol_entity.
lv_order =lv_order_factory->create( lt_params ).
* 4. Create childobjects
DATA: lv_order_headerTYPE REF TO cl_crm_bol_entity,
lv_activity_headerTYPE REF TO cl_crm_bol_entity.
lv_order_header =lv_order->create_related_entity(‘btorderheader’).
lv_activity_header =lv_order_header->create_related_entity(‘btheaderactivityext’).
* 5. Submit childobjects created
lv_bol_core->modify().
* 6. Save and commitchanges using global transaction context
DATA: lv_transactionTYPE REF TO if_bol_transaction_context.
lv_transaction =lv_bol_core->get_transaction( ).
lv_transaction->save().
lv_transaction->commit().

每个实体都有关键字段,否则不能创建成功,修改也是通过这些关键字段去操作的。

关键字段怎么看?去看下BOL根对象的关键结构就明白了。需要注意的是,关键字段一个都不能少。

代码的最后,是对bol的事务处理,这里有COMMIT( ),当然也有ROLLBACK( )。

有个注意点,不要在同一段代码里面多次commit,bol事务是带锁的,搞得不好就会看似bol提交成功,但是DB层存储失败。

真的想要在提交前锁数据,可以这样写。

DATA: lv_successTYPE crmt_boolean.
lv_success =lv_entity->lock( ).

修改bol相对比较简单,查询出数据以后这样操作。

* 1. Lock and modifya property
* here order headerentity with technical name ‘BTOrderHeader’
lv_order_header =lv_order->get_related_entity(‘btorderheader’).
IF lv_order_header->lock( ) = if_genil_boolean=>true.lv_order_header->set_property(iv_attr_name = ‘description’iv_value =‘changed description’).
ENDIF.
* 2. send all changesto BO layer
lv_bol_core->modify().
* 3. get theimplicitly created transaction
lv_transaction =lv_bol_core->get_transaction( ).
* 4. save and commityour changes
lv_transaction->save().
lv_transaction->commit().

最后是bol删的写法。

lv_order_header->delete().
lv_bol_core->modify().
DATA: lv_transactionTYPE REF TO if_bol_transaction_context.
lv_transaction =lv_bol_core->get_transaction( ).
lv_transaction->save().
lv_transaction->commit().

BOL简单分析(一)相关推荐

  1. BOL简单分析(二)

    关于Display Mode 从CRM5.0开始,BOL带有了一个Display Mode.目的就是防止误操作BOL数据. 最终是改变了core的一个参数 IV_DISPLAY_MODE_SUPPOR ...

  2. R语言splines包构建基于logistic回归的自然样条分析:南非心脏病数据集、非线性:基函数展开和样条分析、你简单分析的不重要特征,可能只是线性不显著、而非线性是显著的

    R语言splines包构建基于logistic回归的自然样条分析:南非心脏病数据集.非线性:基函数展开和样条分析.你简单分析的不重要特征,可能只是线性不显著.而非线性是显著的 目录

  3. [EntLib]微软企业库5.0 学习之路——第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—上篇...

    在完成了后,今天开始介绍企业库中的新模块:Cryptographer(加密模块),这个模块在日常的大多数项目的作用非常重要,例如:网站会员密码.身份证号.网站配置等,通过对信息进行加密可以保证项目数据 ...

  4. FFmpeg资料来源简单分析:libswscale的sws_getContext()

    ===================================================== FFmpeg库函数的源代码的分析文章: [骨架] FFmpeg源码结构图 - 解码 FFmp ...

  5. howdoi 简单分析

    对howdoi的一个简单分析. 曾经看到过下面的这样一段js代码: try{doSth(); } catch (e){ask_url = "https://stackoverflow.com ...

  6. Mac与Phy组成原理的简单分析

    Mac与Phy组成原理的简单分析 2011-12-28 15:30:43 //http://blog.chinaunix.net/uid-20528014-id-3050217.html 本文乃fir ...

  7. python做数据可视化的代码_Python数据可视化正态分布简单分析及实现代码

    Python说来简单也简单,但是也不简单,尤其是再跟高数结合起来的时候... 正态分布(Normaldistribution),也称"常态分布",又名高斯分布(Gaussiandi ...

  8. ASIHTTPRequest源码简单分析

    2019独角兽企业重金招聘Python工程师标准>>> 1.前言 ASIHttprequest 是基于CFNetwork的,由于CFNetwork是比较底层的http库,功能比较少, ...

  9. Hessian 源码简单分析

    Hessian 源码简单分析 Hessian 是一个rpc框架, 我们需要先写一个服务端, 然后在客户端远程的调用它即可. 服务端: 服务端通常和spring 做集成. 首先写一个接口: public ...

最新文章

  1. 无法创建Web Application项目的问题
  2. Java Thread源码分析
  3. 如何解决多线程并发问题
  4. 如何在Python3.x上安装Sentry,实时监控业务错误
  5. 【HDU - 5963】朋友(博弈,思维,必胜态必败态,找规律)
  6. 【MPI学习3】MPI并行程序设计模式:不同通信模式MPI并行程序的设计
  7. 【Andorid X 项目笔记】禁用ListView的Fling功能(1)
  8. 如何让nodejs同步操作
  9. 2017.9.19 禁忌 失败总结
  10. c语言栈的实现以及操作_python模拟栈的操作实现非递归方式的快速排序算法
  11. Python+django网页设计入门(15):公用模板设计与使用
  12. lan8720a自协商启动_惠及18个小区17851户!今年海曙老旧小区改造启动,重点内容包括…...
  13. 在苹果mac中使用excel时,如何快速求和多行数值?
  14. java 中文数字排序_java 中文数字排序方法
  15. html文件超链接打不开,Excel中出现超链接打不开的解决方法
  16. xwork配置文件: 新配置文件覆盖旧文件中的同名Action
  17. 个税汇算清缴是怎么算的,为何有人补税几百,有人退税几千?
  18. 陀螺仪的进动及其数学描述
  19. 整理了60个Python小例子,拿来即用!
  20. 查询跟踪多家快递单号,筛选某一时间发货的单号

热门文章

  1. 【已解决】树莓派新系统连接vcn后无任务栏如何解决?
  2. 西门子1200PLC和Modbus485从站设备通讯
  3. C#使用S7.net连接西门子S1200PLC,C#直接连接西门子PLC
  4. 六西格玛奠基人之张驰染阳杂记
  5. vue表格某一列的显示与隐藏
  6. java我的世界114_我的世界114更新了什么_我的世界114更新内容_快吧单机游戏
  7. android+蓝牙遥控器,一种通过蓝牙遥控安卓设备的方法与流程
  8. win10触摸键盘TabTip软件特性
  9. 告别传统机房:3D 机房数据可视化实现智能化与VR技术的新碰撞
  10. AI+教育 I 69天流利说APP学习浅谈自适应学习