实现事件检测机制

在确定了要支持的业务流程(例如,销售报价或销售订单)并确定了首选事件检测机制之后,为您的业务流程实现该机制。

注:
当实现事件检测机制时,最好是在一个机制中支持业务流程的所有功能。这限制了对 SAP 应用程序的影响,并使事件检测更容易管理。

下列各节描述由连接器实现的四种事件检测机制的实现过程。在适用的任何时候,均将提供示例以及样本代码。

代码增强

代码增强要求将一部分 ABAP 代码包括在定制功能模块中。事件检测代码将作为功能模块编写,以确保处理与事务保持分离。从事务中使用的任何表或变量都需要按值而不是按引用传递至功能模块。

要在检索事件时使锁定业务对象的影响最小,功能模块通常以更新任务方式执行。要避免不一致,当在处于更新任务方式下的进程内已调用功能模块时,不要使用更新任务。

要使事务中的影响最小,将功能模块放置在另一个包含程序内。使用包含程序将允许您对定制代码而不是 SAP 代码进行更改。

事件检测代码包含标识事件对象的逻辑。例如,销售订单事务处理许多类型的订单,但只有一种订单类型是必需的。此逻辑在事件检测代码中。放置此事件检测代码的一般策略是恰好在将数据提交至数据库之前插入它。包含事件检测代码的功能模块通常将作为业务对象功能组的一部分创建。

要实现代码增强以进行事件检测:

下列步骤描述使用代码增强事件检测机制来创建示例 SAP 销售报价的过程。步骤后面的代码是此过程的结果。

  1. 在调查 SAP 销售报价事务时,找到事务 VA21 以支持期望的销售报价创建业务流程。
  2. 销售报价号被确定为唯一键。销售报价号存储在表/字段 VBAK-VBELN 中。
    注:
    因为此事件使用单个唯一键,所以代码示例使用 OBJKEY 参数来传递该键的值。有关编写使用组合键的事件的示例,请参阅编写组合键作为名称-值对
  3. 事务 VA21 在事务流中使用用户出口作为文档保存过程的一部分(Form Userexit_save_document)。在事务的此时刻,当执行用户出口时可获得报价号。
  4. 用户出口属于其它业务流程,因此需要进行额外的编码才能将销售报价与其它类别的文档区分开来。VBAK-VBTYP 可用来确定文档类别。销售报价将以文档类别 B 保存在 SAP 数据库中。
  5. 将包含语句添加至指向包含程序的用户出口。
  6. 此时,需要创建包含程序和功能模块。

/CWLD/ADD_TO_QUEUE:单个键值示例

以下代码片段举例说明对 /CWLD/ADD_TO_QUEUE 事件触发器(使用单个键值)的函数调用。

If VBAK-VBTYP = 'B'.
       C_OBJ_ORDER = 'SAP4_SalesQuote'.
          TMP_OBJKEY = XVBAK-VBELN.
     TMP_EVENT = 'Create'.
  
       CALL FUNCTION '/CWLD/ADD_TO_QUEUE'
        EXPORTING
                   OBJ_NAME                = C_OBJ_ORDER
 OBJKEY = TMP_OBJKEY
 EVENT = TMP_EVENT
 GENERIC_RECTYPE = ''
 IMPORTING
 RECTYPE = TMP_RECTYPE
 TABLES
                   EVENT_CONTAINER = TMP_EVENT_CONTAINER
              EXCEPTIONS
                   OTHERS          = 1.
  
 Endif.
 

/CWLD/ADD_TO_QUEUE_IN_FUTURE:单个键值示例

以下代码片段举例说明对 /CWLD/ADD_TO_QUEUE_IN_FUTURE 事件触发器(单个键值)的函数调用。

DATA: DATE_IN_FUTURE LIKE SY_DATUM.
  
 DATE_IN_FUTURE = VBAK-VDATU.
  
 If VBAK-VBTYP = 'B'.
       C_OBJ_ORDER = 'SAP4_SalesQuote'.
         TMP_OBJKEY = XVBAK-VBELN.
  TMP_EVENT = 'Create'.
  
       CALL FUNCTION '/CWLD/ADD_TO_QUEUE_IN_FUTURE'
        EXPORTING
                   OBJ_NAME               = C_OBJ_ORDER
 OBJKEY = TMP_OBJKEY
 EVENT = TMP_EVENT
                   VALID_DATE             = DATE_IN_FUTURE
 IMPORTING
 RECTYPE = TMP_RECTYPE
 TABLES
                   EVENT_CONTAINER = TMP_EVENT_CONTAINER
              EXCEPTIONS
                   OTHERS          = 1.
  
 Endif.
 

编写组合键作为名称-值对

如果事件的键由多个字段而不是单个键字段组成,则可以指定每个键属性的名称及其相应的值。因为您指定了属性的名称,所以,不需要将属性标记为 IsKey 以便连接器填充它和用于检索。

如果您指定了多个名称-值对,则连接器在它创建的业务对象中设置多个属性的值来从应用程序中检索整个对象。如果您指定单个名称-值对,则连接器设置除了标记为 IsKey 的第一个属性之外的指定属性的值。

因为 IDoc 处理程序不使用名称-值对,所以,在使用 /CWLD/IDOC_HANDLER 时不要指定名称-值对是很重要的。有关更多信息,请参阅IDoc 处理程序和检索查询描述

下列步骤描述创建示例 SAP 销售报价的过程,该示例 SAP 销售报价在它的组合键中使用三个字段。步骤后面的代码是此过程的结果。

  1. 根据本章提供的结构(/CWLD/NAME_VALUE_PAIRS)来创建本地 name_value_pairs 内部表。此结构具有两列:ATTR_NAMEATTR_VALUE
  2. 在调用功能模块 /CWLD/ADD_TO_QUEUE 或 /CWLD/ADD_TO_QUEUE_IN_FUTURE 之前,编写代码来将键属性的名称以及它们的值添加至内部表。
  3. 更改功能模块 /CWLD/ADD_TO_QUEUE 或 /CWLD/ADD_TO_QUEUE_IN_FUTURE
  4. 触发功能会自动格式化每个事件键。格式化使用以下语法:
    attribute1=value1|Cx|attribute2=value2|Cx|[attributeN=valueN|Cx|]
     

    其中:

    attribute
    键属性的名称(不区分大小写)

    value
    键属性的值(区分大小写)

    |Cx|
    每个名称-值对的终止符(即使只指定了一个名称-值对也要使用终止符)

您在代码中指定名称-值对的顺序不需要与业务对象中属性的顺序相匹配。但是,如果您指定业务对象中不存在的属性,则事件将失败。

以下代码段在触发时将 KNVV 表中的客户号、销售组织和分销渠道指定为名称-值对。在功能模块 /CWLD/ADD_TO_QUEUE 的代码中突出显示了下面两行:

DATA:  name_value_pairs LIKE /cwld/name_value_pairs OCCURS 5 with header line.
  
 MOVE   'CustomerId' TO name_value_pairs-attr_name.
 MOVE   knvv-kunnr TO name_value_pairs-attr_value.
 APPEND name_value_pairs.
  
 MOVE   'SalesOrg' TO name_value_pairs-attr_name.
 MOVE   knvv-vkorg TO name_value_pairs-attr_value.
 APPEND name_value_pairs.
  
 MOVE   'DistributionChannel' TO name_value_pairs-attr_name.
 MOVE   knvv-vtweg TO name_value_pairs-attr_value.
 APPEND name_value_pairs.
 If VBAK-VBTYP = 'B'.
       C_OBJ_ORDER = 'SAP4_SalesQuote'.
          TMP_OBJKEY = XVBAK-VBELN.
     TMP_EVENT = 'Create'.
  
       CALL FUNCTION '/CWLD/ADD_TO_QUEUE'
             EXPORTING
                   OBJ_NAME               = C_OBJ_ORDER
 *                 OBJKEY                 = TMP_OBJKEY
 EVENT = TMP_EVENT
 GENERIC_RECTYPE = ''
 IMPORTING
 RECTYPE = TMP_RECTYPE
 TABLES
                   NAME_VALUE_PAIRS = name_value_pairs
                   EVENT_CONTAINER = TMP_EVENT_CONTAINER
             EXCEPTIONS
                   OTHERS                  = 1.
  
 Endif.
 

批处理程序

要实现批处理程序作为事件检测机制,您必须编写评估数据库信息的 ABAP 程序。如果当 ABAP 程序执行时达到该程序中的条件,则将触发一个事件。

要实现批处理程序以进行事件检测:

以下步骤描述创建批处理程序的过程,该批处理程序检测当天创建的所有销售报价的事件。步骤后面的代码是此过程的结果。

  1. “创建”被确定为受支持的查询描述。
  2. 报价号被确定为用来检索事件的唯一键。
  3. 需要检查创建日期(VBAK-ERDAT)和文档类别(VBAK-VBTYP)。

以下样本代码支持 SAP 销售报价作为批处理程序:

REPORT ZSALESORDERBATCH.
  
 tables: vbak.
  
 parameter: d_date like sy-datum default sy-datum.
  
 data: tmp_key like /CWLD/LOG_HEADER-OBJ_KEY,
       tmp_event_container like swcont occurs 0.
  
 " retrieve all sales quotes for today's date
 " sales quotes have vbtyp = B
 select * from vbak where erdat = d_date
                      and vbtyp = 'B'.
  
 tmp_key = vbak-vbeln.
  
   CALL FUNCTION '/CWLD/ADD_TO_QUEUE'
        EXPORTING
             OBJ_NAME        = 'SAP4_SalesQuote'
 OBJKEY = tmp_key
 EVENT = 'Create'
 GENERIC_RECTYPE = ''
 IMPORTING
 RECTYPE = r_rectype
 TABLES
             EVENT_CONTAINER = tmp_event_container.
  
   write: / vbak-vbeln.
 endselect.
 

业务工作流

业务工作流是一组或一系列在逻辑上相关的业务操作。工作流内的处理逻辑检测事件。业务工作流事件检测机制依靠 SAP 业务对象资源库(BOR),该资源库包含对象及其相关属性、方法和事件的目录。

要实现业务工作流以进行事件检测:

SAP 销售报价的以下示例可以用来实现使用业务工作流的事件触发器:

  1. 搜索 BOR 以获取适当的销售报价业务对象。可以使用简短描述字段和字符串“*quot*”来执行搜索。BUS2031(客户报价)是返回的一个业务对象。
  2. 进一步研究 BUS2031 之后,确定键字段为 CustomerQuotation.SalesDocument(VBAK-VBELN)。
  3. 将使用以下条目创建 BUS2031 的子类型:

    对象类型 - ZMYQUOTE

    事件 - SAP4_SalesQuote

    名称 -SAP4 销售报价

    描述 - SAP 4 销售报价子类型的示例

    程序 - ZMYSALESQUOTE

    应用程序 - V

  4. 将通过把条目添加至“事件链接”表(事务 SWE3)来激活事件检测机制。将使用以下条目来激活创建事件:

    对象类型 - ZMYQUOTE

    事件 - SAP4_SalesQuote

    接收器 FM - /CWLD/ADD_TO_QUEUE_DUMMY

    接收器类型 FM - /CWLD/ADD_TO_QUEUE_WF

注:
接收器和接收器类型功能模块(FM)都指向 /CWLD/ADD_TO_QUEUE。因为 SAP 应用程序有时要求两个字段都要填充,所以仅使用了 DUMMY 功能模块。WF 功能模块将 SAP 标准接口转换为由 /CWLD/ADD_TO_QUEUE 使用的那个接口。

业务工作流事件检测机制已创建且是活动的。已设置它来检测已创建的所有 SAP 客户报价。

更改指针

更改指针使用更改文档,它是要实现的其中一种更复杂的事件检测机制。SAP 的业务对象资源库(BOR)也使用“应用程序链接启用”(ALE)技术。更改文档始终引用至少为它指定了一个数据库表的业务文档对象。如果表中的数据元素被标记为需要更改文档并且将该表指定给了业务文档对象,则由该数据元素定义的字段的值发生更改时就会生成更改文档。这些更改被捕获在表 CDHDRCDPOS 中并用于事件检测。

要实现更改指针以进行事件检测:

SAP 销售报价的以下示例可以用来实现使用更改指针的事件触发器:

  1. 更新被确定为受支持的查询描述。调查销售报价创建事务显示“创建”查询描述不是通过此机制来检测的。
  2. 当对业务执行检查以获取销售报价时:
  3. 在此示例中没有对数据元素进行求值。
  4. 销售报价号被确定为 CDHDR-OBJECTID 中的唯一键。
  5. CDHDR-OBJECTCLAS 的值为 VERKBELEG,这是主要的区分器。只应该选取销售报价。代码将检查标题表中的 TCODE 字段,但是在 VBAK 表中应该执行正确的查找。

已将以下样本代码添加至 /CWLD/EVENT_FROM_CHANGE_POINTR

when 'VERKBELEG'.
    data: skey    like /cwld/log_header-obj_key,
       s_event like swetypecou-event,
       r_genrectype like swetypecou-rectype,
       r_rectype like swetypecou-rectype,
       t_event_container like  swcont occurs 1 with header line.
  
    " Quick check. Should check document category (VBTYP) in VBAK.
    check header-tcode = 'VA22'.
  
    " Event detection has started
    perform log_create using c_log_normal c_blank
                               c_event_from_change_pointer c_blank.
  
    " Set the primary key 
    skey = header-objectid.
  
    " Set the verb
    s_event = c_update_event.
  
    " Log adding the event to the queue
    perform log_update using c_information_log text-i44
                             'SAP4_SalesQuote' s_event skey.
  
       " Event detection has finished.
       perform log_update using c_finished_log c_blank
                                c_blank c_blank c_blank.
  
    call function '/CWLD/ADD_TO_QUEUE'
       exporting
             obj_name                  = 'SAP4_SalesQuote'
             objkey                    = skey
             event                     = s_event
             generic_rectype           = r_genrectype
       importing
             rectype                   = r_rectype
       tables
             event_container           = t_event_container
       exceptions
             others                     = 1.
 

Copyright IBM Corp. 1997, 2004