SAP CRM BOL编程基础,代码+详细注释
网络上可以找到一些使用BOL查询、维护数据的DEMO,但几乎都是单纯的代码,缺乏说明,难以理解。本文除了代码外,还给出了详细的注释,有助于理解BOL编程中的一些基本概念。
这是一篇翻译的文章,你可能会发现部分内容不是很明确,这时可以直接阅读原文。
原文所在的sapcrmwebui.com是一个不错的博客,里面有较为完整的Web UI入门教程,然而网站不是很稳定,偶尔会连接不上,建议使用Internet Archive访问。
如果你访问不了Internet Archive,说明你需要一点过墙的手段。
本文链接:http://www.cnblogs.com/hhelibeb/p/5985110.html
原文链接:BASICS OF BOL PROGRAMMING
如果觉得本文有用,请记得在页面底部点个赞~
2016.12.31 更多示例代码请参考:BOL Programming(WebUI), AbapLog
搜索操作
**********************************************
*BOL 编程
*SAP CRM WEBCLIENT
*包含一些基本的操作,比如bol中的查找、创建、更新
*通过编程来介绍业务对象层的主要的类和方法
********************************************** *需要的数据
DATA: lr_core TYPE REF TO cl_crm_bol_core. *为了使用BOL中的服务,我们需要通过CORE类启动模型(组件集) lr_core = cl_crm_bol_core=>get_instance( ). *一旦我们有了实例,之后便可以加载组件集
*这里我们将使用ONEORDER组件集 *在Web UI上面,这个将会由框架操作。这里我们正在report程序中编程,因此需要自己来操作 TRY.
CALL METHOD lr_core->load_component_set
EXPORTING
iv_component_set_name = 'ONEORDER'.
CATCH cx_crm_genil_general_error .
ENDTRY. *组件加载了,因此我们可以使用BOL服务。让我们搜索一个特定的合同。为了实现这个目的,我们需要获取一个dquery服务对象的实例。
DATA: lr_query TYPE REF TO cl_crm_bol_dquery_service,
lr_result TYPE REF TO cl_crm_bol_bo_col. *****搜索操作*********************** "获取动态搜索对象的实例,它会被用于搜索服务合同。
lr_query ?= cl_crm_bol_dquery_service=>get_instance( iv_query_name = 'BTQSrvCon' ). "每一个动态搜索对象将会有他自己的结果类型对象,这里BTQSrvcon的结果对象是BTQRSrvcon
"因此在结果列表里面,所有的对象都是BTQRSrvcon的类型。 "我们得到了实例,之后我们需要设置选择条件值,取得所有描述是‘testing’的合同。
"你可以多次使用这个方法,来添加不同的选择参数。 lr_query->add_selection_param( iv_attr_name = 'DESCRIPTION'
iv_sign = 'I'
iv_option = 'EQ'
iv_low = 'testing' ).
"获取以集合(collection)形式存在的的、匹配选择条件值的合同列表 "集合不过是一个保存记录的容器,我们可以把它和内表相类比 "它保存了记录. lr_result ?= lr_query->get_query_result( ). "让我们输出集合中所有的合同ID和描述 "cl_crm_bol_entity用于表现业务对象层中的记录 DATA: lr_entity TYPE REF TO cl_crm_bol_entity,
lv_objectid TYPE string,
lv_descr TYPE char40. "读取集合中的第一条记录 lr_entity ?= lr_result->if_bol_bo_col~get_first( ). "下面的while循环机制用于访问集合中的每一条数据 WHILE lr_entity IS BOUND. "读取合同ID. "get property as string方法将返回字符串格式的属性,因此我们将lv_object声明为字符串。 lr_entity->get_property_as_string( EXPORTING iv_attr_name = 'OBJECT_ID'
RECEIVING rv_result = lv_objectid ). "get property as value将返回值本身的类型,因此我们使用数据元素来声明DESCRIPTION lr_entity->get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION' IMPORTING ev_result = lv_descr ). WRITE : lv_objectid, lv_descr. WRITE /:. "读取集合中的下一条数据. lr_entity ?= lr_result->if_bol_bo_col~get_next( ). ENDWHILE.
更新操作
**************更新操作***************************
"让我们修改服务合同的描述 "从结果列表获取现在的entity "每个集拥有一个总是指向我们当前访问的记录的指针,通常我们在BOL的语言中称之为焦点
"因此get current返回拥有焦点的对象,所以就是我们在上面的循环中曾经最后访问的对象 将会被下面的语句取得 lr_entity ?= lr_result->if_bol_bo_col~get_current( ). IF lr_entity IS BOUND. "我们从不对initial状态的对象引用进行操作,这个检查在bol中是十分重要的 "我们能直接在这个lr_entity中使用字符串设置属性吗? "答案是不能,这是一个动态查询对象,通常这些类型的对象的所有的属性都是只读的 "DESCRIPTION是BTAdminH对象的属性,我们需要使用relations获取它我们需要从MODEL中观察我们抵达目标对象所需要的关系是什么.事务代码GENIL_MODEL_BROWSER中可以浏览这些bol对象的关系 "在我们的场景中,我们有lr_entity变量中的BTQRSrvcon作为源.这个对象有关系'聚合BTADVSSrvCon子级基数1' "将会给出对象BTOrder. "同样BTOrder有关系'组成 BTOrderHeader子级基数1', 通过它将取得对象BTAdminH,这个对象有一个属性‘DESCRIPTION’ "当寻找关系时,观察关系的子级基数。如果子级基数是0...1,这个关系将会总是能获取到单一的entity。如果是0...n的话,这个关系将可以获取多个entity. " 如果子级基数是0...1,使用 GET RELATED ENTITY. " 如果子级基数是0...n,使用 GET_RELATED_ENTITIES. DATA: lr_order TYPE REF TO cl_crm_bol_entity. "首先读取BTORDER "参数iv_mode将携带一个值'b',代表绕过缓冲区. "这意味着,框架将会忽视bol缓冲区中存在的值,通过触发相关的api从数据库读取目标entity的值。 "这将降低性能,所以只应在需要的情况使用它,比如你在读取一个特别的、第一次读取的enetity。 TRY. CALL METHOD lr_entity->get_related_entity
EXPORTING
iv_relation_name = 'BTADVSSrvCon'
iv_mode = cl_crm_bol_entity=>bypassing_buffer
RECEIVING
rv_result = lr_order. CATCH cx_crm_genil_model_error . ENDTRY. "我们取得了订单,接下来读取BTAdminH. DATA: lr_header TYPE REF TO cl_crm_bol_entity. IF lr_order IS BOUND. TRY. CALL METHOD lr_order->get_related_entity
EXPORTING
iv_relation_name = 'BTOrderHeader'
iv_mode = cl_crm_bol_entity=>bypassing_buffer
RECEIVING
rv_result = lr_header. CATCH cx_crm_genil_model_error . ENDTRY. ENDIF. "获取到了BTadminH,之后修改它的DESCRIPTION属性. IF lr_header IS BOUND. "在修改任何BOL的对象前,我们需要锁定它 "这由lock方法完成 IF lr_header->lock( ) = abap_true. "如果我们获取了锁, 接下来继续 "我们使用set_* 方法来修改BOL对象的属性. lr_header->set_property_as_string( EXPORTING iv_attr_name = 'DESCRIPTION' iv_value = 'changed' ). ENDIF. "一旦修改结束,我们需要通知框架这个改变已经发生 "使用core类实现它 lr_core->modify( ). "接着从entity获取transaction,并且检查它是否可以保存 DATA: lr_transaction TYPE REF TO if_bol_transaction_context. lr_transaction ?= lr_header->get_transaction( ). IF lr_transaction IS BOUND. IF lr_transaction->check_save_possible( ) EQ abap_true. "如果可以保存,接下来保存transaction并且commit修改。 IF lr_transaction->save( ) EQ abap_true. lr_transaction->commit( ). ENDIF. "我们修改了对象的描述,再次读取它,以获取新的值。 lr_header->get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION'
IMPORTING ev_resul t = lv_descr ). ENDIF. ENDIF. ENDIF. ENDIF.
创建操作
***************创建操作***************************** *让我们创建一个服务合同,并且填充一些它的属性
*"第一步,我们需要创建根entity DATA: lr_factory TYPE REF TO cl_crm_bol_entity_factory, lr_order_new TYPE REF TO cl_crm_bol_entity, ls_params TYPE crmt_name_value_pair, lt_params TYPE crmt_name_value_pair_tab. ls_params-name = 'PROCESS_TYPE'. ls_params-value = 'ZSZ'. APPEND ls_params TO lt_params. "使用工厂类以创建根entity。 我们发送根对象给core类的方法get entity factory去获取需要的工厂类 "接下来我们通过发送需要的参数来使用工厂类的CREATE方法 "这里我们创建合同,将PROCESS_TYPE作为参数输入 lr_factory = lr_core->get_entity_factory( 'BTOrder' ). "#EC NOTEXT lr_order_new = lr_factory->create( lt_params ). IF lr_order_new IS BOUND. "BTOrder只含有GUID,我们需要获取BTAdminH entity去填充某些它的属性。 TRY. CALL METHOD lr_order_new->get_related_entity
EXPORTING
iv_relation_name = 'BTOrderHeader'
iv_mode = cl_crm_bol_entity=>bypassing_buffer
RECEIVING
rv_result = lr_header. CATCH cx_crm_genil_model_error . ENDTRY. "使用setter方法填充属性 IF lr_header IS BOUND. "使用set_*方法修改BOL对象的属性. lr_header->set_property_as_string( EXPORTING iv_attr_name = 'DESCRIPTION' iv_value = 'New Contract' ). lr_core->modify( ). lr_transaction ?= lr_header->get_transaction( ). IF lr_transaction IS BOUND. IF lr_transaction->check_save_possible( ) EQ abap_true. "如果我们可以保存,保存事务并且commit修改 IF lr_transaction->save( ) EQ abap_true. lr_transaction->commit( ). ENDIF. "修改对象描述,再次读取以获取新的值 lr_header->get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION'
IMPORTING ev_result = lv_descr ). ENDIF. ENDIF. ENDIF. ENDIF.
补充:创建条目可以使用cl_crm_bol_entity的create_related_entity方法
参考阅读:Business Object Layer (BOL) Application Programming Guide
SAP CRM BOL编程基础,代码+详细注释的更多相关文章
- 阿里天池 NLP 入门赛 TextCNN 方案代码详细注释和流程讲解
thumbnail: https://image.zhangxiann.com/jung-ho-park-HbnqEhMBpPM-unsplash.jpg toc: true date: 2020/8 ...
- python3编程基础之一:注释模块和包
1.注释 python中的注释和其他任何编程语言中的注释都不一样,有的注释有特殊要求,而是还是有用的. 1).单行注释:注释以#开始到语句结尾,#号后一般跟一个空格 2).多行注释:文档注释,以&qu ...
- 转载:LBP代码详细注释
%LBP returns the local binary pattern image or LBP histogram of an image.% J = LBP(I,R,N,MAPPING,MOD ...
- hdu 1013 过山车 匈牙利算法(代码+详细注释)
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- linux 守护进程(daemon process)代码-详细注释
1. 进程组 组长不能创建新的 会话. 其它进程可以创建新的会话,创建后既成为会话首领,同时失去控制终端. 2. 会话首领可以重新打开控制终端 1 #include <stdio.h> 2 ...
- SAP CRM 7.0中的BOL(Business Object Layer)
业务对象层(BOL)和通用交互层(GenIL)属于业务层. 业务对象层: 在CRM WebClient会话运行期间,业务对象层存储业务对象的数据以及它们属性和关系的定义. 通用交互层 通用交互层将 ...
- 使用ABAP代码提交SAP CRM Survey调查问卷
Jerry之前曾经写过两篇关于SAP CRM Survey调查问卷的技术文章: SAP CRM Survey调查问卷的模型设计原理解析 如何使用SAP CRM Marketing Survey创建一个 ...
- C#_GDI+详细教程(图形图像编程基础)
第7章 C#图形图像编程基础 本章主要介绍使用C#进行图形图像编程基础,其中包括GDI+绘图基础.C#图像处理基础以及简单的图像处理技术. 7.1 GDI+绘图基础 编写图形程序时需要使用GDI( ...
- Umi + Dva的数据传递学习Demo(代码有详细注释)
刚学习时写了篇笔记,以免自己忘记,用了一段时间后,觉得不如做个demo,代码写上注释,方便也在学习umi-dva的同学们理解更好,更容易上手. 这可能是网上注释最多,看了最易理解的学习小指南吧,哈哈. ...
随机推荐
- 在centos7(EL7.3 即 kernel-3.10.0-514.X )上安装BCM4312无线网卡驱动要注意的问题
我新装的centos7主机无法使用里面自带的网卡,查询后发现网卡型号为BCM4312.我在看资料安装的过程中遇到了些问题,纠结了好久,现在分享下要注意的点,为后来的遇到同样问题的人提供点帮助.现在开始 ...
- Autofac 的点滴
泛型类型的注册和使用 public interface IRepository<T> where T:class { } public interface ISchoolDetailRep ...
- 跨域问题,前端主动向后台发送cookie
跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同 http://www.baidu.com:80 和 https:/ ...
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建
公司在IDC机房有两台很高配置的服务器,计划在上面部署openstack云平台虚拟化环境,用于承载后期开发测试和其他的一些对内业务.以下对openstack的部署过程及其使用做一详细介绍,仅仅依据本人 ...
- Mono 3.2.3 Socket功能迎来一稳定的版本
由于兴趣自己业余时间一直在搞.net下面的通讯应用,mono的存在得以让.NET程序轻松运行在Linux之下.不过经过多尝试Socket相关功能在Mono下的表现并不理想.不管性能还是吞吐能力方面离我 ...
- Mono产品生命周期
软件生命周期 同任何事物一样,一个软件产品或软件系统也要经历孕育.诞生.成长.成熟.衰亡等阶段,一般称为软件生命周期(软件生存周期) .软件生命周期模型是指人们为开发更好的软件而归纳总结的软件生命周期 ...
- mysql sleep进程过多,应用级配置
<property name="hibernateProperties"> <props> <prop key="hibernate.dia ...
- ABP文档 - Web Api 控制器
文档目录 本节内容: 简介 AbpApiController 基类 本地化 其它 过滤 审计日志 授权 防伪造过滤 工作单元 结果包装和异常处理 结果缓存 验证 模块绑定器 简介 通过Abp.Web. ...
- 简单的ViewPager了解Scroller类
View滑动是自定义ViewGroup中十分常见的一个功能.Android提供了多种View滑动的方法. layout方法 offsetLeftAndRight()与offsetTopAndBotto ...
- wget 显示"英国中部时间",去掉烦人的刷屏显示
wget下载文件显示多行,进度条后面显示英国中部时间,非常让人郁闷. 本来英文是eta(Estimated Time of Arrival 预计到达时间),翻译错了,干脆去掉好了. 先要有两个个工具 ...