SAP CRM BOL编程基础,代码+详细注释

网络上可以找到一些使用BOL查询、维护数据的DEMO,但几乎都是单纯的代码,缺乏说明,难以理解。本文除了代码外,还给出了详细的注释,有助于理解BOL编程中的一些基本概念。

这是一篇翻译的文章,你可能会发现部分内容不是很好理解,这时可以直接阅读原文。

原文所在的sapcrmwebui.com是一个不错的博客,然而网站不是很稳定,偶尔会连接不上,建议使用Internet Archive访问。

如果你访问不了Internet Archive,说明你需要一点过墙的手段。

本文链接:http://www.cnblogs.com/hhelibeb/p/5985110.html

原文链接:BASICS OF BOL PROGRAMMING

如果觉得本文有用,请记得在页面底部点个赞~

搜索操作

**********************************************
*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

  "在我们的场景中,我们有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 we can save , then save the transaction and commit the changes.

        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.

创建操作

***************创建操作*****************************

*让我们创建一个服务合同,并且填充一些它的属性
*"第一步,我们需要创建根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.

    "we use set_* methods to change the properties of BOL objects.

    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.
 
时间: 2024-10-14 16:01:13

SAP CRM BOL编程基础,代码+详细注释的相关文章

ABP+Zero+Metronic+Redis的完美结合快速启动模板(超级代码详细注释版本)

微信扫一扫并支付成功,联系QQ:770628656获取所有源码(超级代码详细注释版本) 原文地址:https://www.cnblogs.com/abpbasic/p/8124792.html

POJ 1035 代码+详细注释

Spell checker Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19319 Accepted: 7060 Description You, as a member of a development team for a new spell checking program, are to write a module that will check the correctness of given words us

转载:LBP代码详细注释

%LBP returns the local binary pattern image or LBP histogram of an image.% J = LBP(I,R,N,MAPPING,MODE) returns either a local binary pattern% coded image or the local binary pattern histogram of an intensity% image I. The LBP codes are computed using

linux 守护进程(daemon process)代码-详细注释

1.进程组 组长不能创建新的 会话 2.会话首领可以重新打开控制终端 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <sys/param.h> 5 #include <sys/stat.h> 6 #include <sys/types.h> 7 #include <fcntl.h> 8 #include <sig

Linux 网络编程基础(4) -- Ping 的C代码实现

1.背景 在进行网络编程的时候,通常使用的协议有TCP协议,UDP协议.这些协议在简历套接字之初需要制定套接字的类型,比如TCP应当设置为 SOCK_STREAM, UDP对应的套接字应当设置为SOCK_DGRAM.但是这些套接字并非能够提供网络所需的全部功能,我们还需要其他的套接字,比如原始套接字OCK_RAW.原始 套接字可以提供SOCK_STREAM和SOCK_DGRAM所不及的能力.比如: (1)有了原始套接字,进程可以读取ICMPV4.ICMPV6.IGMP等的分组.正如ping所使用

BST基础教学(详细注释)

1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #define re return 7 #define rep(i,a,n) for(int i = a;i <= n;i++) 8 #define per(i,n,a) for(int i = n;i >= a;i--) 9 typ

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握

Linux中的shell脚本编程——基础篇

概述: shell脚本在Linux系统管理员的运维工作中非常重要.shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求.本篇将从编程基础.脚本基本格式.变量.运算.条件测试这几个方面详细介绍shell脚本编程的基础内容,也是我们必须要掌握熟练的内容. 一.编程环境 1.程序:指令+数据 程序编程的风格有两种: 过程式:以指令为中心,数据服务与指令 对象式:以数据为中心,指令服务于数据 2.程序的执行方式: □计算机:只能识别二进制文件

SAP CRM 树状视图(TREE VIEW)

树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view)那种专门的树视图类型.我们可以认为树视图是表视图的一种特例.没有可以用于创建树视图的向导.需要按以下特定的步骤手动改造已存在的视图. 首先,这个看起来挺难的,但是你做的次数越多,就会越容易理解它.在本文,我将创建一个如下模样的树视图. 如你所见,它有两级结构.第一级展示LEAD ID,下一级展示客户