Skip to content
关注公众号,可咨询工作中遇到的问题、获取学习资料、掌握行业资讯

ABAP 事件

一、介绍

  事件(Event)在前面已经提及,但在这章会通过实际程序详细介绍。在ABAP对象中 在没有继承关系的类之间,从一个类的方法中调用另一个类的方法时需要使用事件来控制。 在类中定义事件时类的方法可以触发事件,这与 Event Handler 交替启动。[图 14-18]很好地体 现了类C1与C2中的 Event Trigger 与Event Handler 的关系。当用户进行单击鼠标或按(F1) 键等操作时,在ABAP程序画面上可以通过事件进行处理。 alt text   在[图14-19]中创建了类C1和C2两个实例。SET HANDLER语句为实例创建透明的处 理器表(E1)。处理器表包含了处理器方法名和已注册的(registered)实例的Reference。表 内的记录根据 SETHANDLER 语句动态管理。即使初始化对象 H1和 H2,只要实例 C2<1>、 C2<2>还存在于处理器表中,就不会被 Garbage Collection删掉。Garbage Collection 收集记忆 装置的无用信息,以便以后程序中重新利用,此外因程序积累太多垃圾数据,导致记忆装置 没有多余空间时会自动执行。 alt text   当触发事件时(R1方法在M1中发生事件E1时)系统会从事件表中执行相应实例的方 法。 ① 必须有注册事件的类(C1)。 ② 必须有定义处理器方法的 M2的类(C2)。 ③ 在主程序中有注册处理器方法M2的内容。

二. 触发事件

  为了触发事件(EventTrgger),类必须在类声明部分定义事件,使其在方法中触发事件

1.声明事件

  在类或接口的声明部分首先声明事件。用以下语句声明实例事件。静态事件使用 CLASS-EVENT 语句。

  1. 实例事件   用EVENSTS语句可以声明实例事件。只有实例方法才能调用实例Event。
abap
EVENTS evt EXPORTING.. VALUE(el e2 .)
TYPE type [OPTIONAL]...
  1. 静态事件   可利用CLASS-EVENTS语声明静态事件。所有方法都能调用静态事件。静态事件是 在静态方法中可以调用的唯一事件类型。
abap
CLASS-EVENTS evt...

2.Triggering Event

  类内部的实例事件在类的所有实例中都可以触发。静态事件在所有方法中都可以触发 但是只有静态方法才能触发静态事件。

abap
RAISE EVENT evt EXPORTING el = fl e2 = f2 ..

二、 Handling Event

  触发事件的前提是方法必须声明为Handler 方法,且执行前要注册事件。

1.声明事件处理器方法(Event Handler Method)

  所有类都拥有其他类触发自身类时可以调用的事件处理器方法。当然,可以在同一个类 中用事件和事件处理器定义方法。

abap
METHODS meth FOR EVENT evt OF cifIMPORTING el e2 ...

  Static 方法可以用 CLASS-METHODS 语句定义。

2.注册事件处理器方法

  若要使事件处理器方法启用事件,执行时需要注册处理器。

abap
SET HANDLER hl h2 . FOR...

  指定要注册的实例事件处理器的对象领域时使用FOR语。用FORALLINSTANCES 语句可以一次性注册可触发事件的所有实例处理器。

abap
SET HANDLER hl h2 ... FOR ref.
SET HANDLER h1 h2 ... FOR ALLINSTANCES.MOVE f1+2(3)TO f2.

  在静态事件中无法使用FOR语句。

abap
SET HANDLER hl h2 ...

3. Raise Event

  调用RAISEEVENT语开始执行下一个阶段之前,执行所有被注册的处理器方法 (Synchronous Eventhandling)。若处理器方法触发的是自身事件,则执行原有的处理器方法 之前,执行自身处理器方法。为了防止发生无限循环,将其控制为只执行64次循环。处理器 方法按照注册的顺序执行。若动态地执行事件处理器,则无法预测其执行顺序。此时只能理 解为同时执行所有事件处理器来进行编码。

4.EVENT 例题

  面向对象程序是通过交换对象之间的信息处理数据。继承树中存在的类之间(承关系) 可以调用对方的方法自由的交换信息,但相互独立的类之间需通过事件才能交换信息。此时, 事件的主人(Owner)是注册该事件的类对象,此外所有的类都会注册事件。只有事件的实例 对象才有权限触发事件,其他类只是处于触发事件等待状态(SETHANDLER)。通过[例14-18] 也许容易理解类、方法、事件及事件处理器。为了触发保龄球馆的会员(对象)去打保龄的 事件,需要经过的过程用代码怎么实现呢?请参照[例14-18]。
alt text [结果14-18]

abap
WAIT A MINUATE ~
OK, LETS GO !!!

  邻居(类)之间无法直接控制对方的行为,因此通过“去打一场保龄吧”事件可以 影响邻居的行为(Method)。其中,会长职位对应的是类C1,会员是类C2,且会长姓 金,会员姓李。

  1. EVENTS: BOWL.
      会长(小金)为了想让会员打保龄球(BOWL)时打电话而给了他手机号,当会员(小 李)来电话时记录了BOWL名作为联系人名(注册事件)。
  2. METHODS LETSGO FOR EVENT BOWL OF c1.
      会员(小李)的手机里在会长(小金)的手机号上记录了LETSGO名字(注册处理器方 法)
  3. SET HANDLER LEE->LETSGO FOR KIM.
      代表会长的类C1才有去打保龄球的事件最终决定权。会员C2为了打保龄球,打会长给 的手机号(SETHANDLER)。这就像小李对小金说:“我已经准备好去打球,你准备好了 再联系我”
  4. RAISE EVENT BWL.
      正在睡觉的会长小金收到要去打自己喜欢的保龄球事件后,兴奋的他醒来回复: “首先要准备一下打保龄球的装备,准备完后联系你,稍等一下!”(触发事件)。
  5. KIM->GO BOWL()或者 CALLMETHOD KIM->GO BOWL( )的缩写
      准备完后,会长小金对会员小李说:“准备好了,走吧!” 首先,小金的GOBWL方法触发BOWL事件,然后此事件调用连接在一起的小李的 LETSGO方法。这个过程叫触发(Trigger)。这样,两个人就高兴地去打球了。 为了有助于理解下面按顺序排列了执行事件的过程,在实际程序中按照(例14-19]的顺序 执行。下面练习使用内表。
abap
  REPORT z14_19.
  TABLES:sflight.
  SELECT-OPTIONS: s carrid FOR sflight-carrid.
CLASS CI DEFINITION.
  PUBLIC SECTION.
    TYPES:BEGIN OF t_sflight,
    carrid TYPE sflight-carrid,
    connid TYPE sflight-connid,
    fldate TYPE sflight-fldate,
    END OF t_sflight.
    DATA :gt_itab TYPE STANDARD TABLE OF t_sflight,
    gs_str TYPE t_sflight.
    EVENTS: el .
    METHODS : get_data ,display_data ,no_data
    FOR EVENT el OF cl.
    "C1 DEFINITION
ENDCLASS.

CLASS c1 IMPLEMENTATION.
  METHOD: get_data .
    SELECT carrid connid fldate FROM sflight
    INTO TABLE gt_itab
    WHERE carrid IN s_carrid.
    IF sy-subrc < O.
      RAISE EVENT e1.
    ELSE .
      CALL METHOD display data .
    ENDIF.
  ENDMETHOD.
  "get_data
  METHOD:display_data .
    LOOP AT gt_itab INTO gs_str.
      WRITE:/10 gs_str-carrid.
      WRITE:40 gs_str-connid.
      WRITE:60 gs_str-fldate.
    ENDLOOP.
    "DISPLAY DATA
  ENDMETHOD.
  METHOD no_data .
    WRITE:/10 'There is no data'.
  ENDMETHOD.
ENDCLASS.

"no data
"C1 IMPLEMENTATION
DATA : go_obj TYPE REF TO c1.

START-OF-SELECTION.
  CREATE OBJECT: obi.
  SET HANDLER go obj->no_ data FOR: objl
  CALL METHOD go obj->get_data .

[结果 14-19]

abap
AA      0017    2013-12-15
AA      0017    2014-01-12
AA      0017    2014-02-09
AA      0017    2013-03-09
AA      0017    2015-04-06

5.参数说明[例 14-19]

1) 注册处理器方法
SETHANDLER go obj->no data FOR: obj1。obj1 在自己的方法 no data 中注册了处理器 方法。 2) 调用处理器方法
CALL METHOD go obj->get data.
getdata方法是事件e1的处理器方法。
3) 执行方法
执行 get data方法。执行 SQL语句,若没有査询到数据,则触发 RAISE EVENT,若有 数据则调用 display data 方法。
4) 调用事件
若没有查询到数据,则触发事件返回[结果 14-19]。
5) 触发事件
类c1中注册了事件e1,然后声明了自己事件对应的处理器方法。

abap
EVENTS: el .
METHODS:get_data ,display_data ,no_data
FOR EVENT el OF cl.

虽然有三个处理器方法,但只会调用其中的SETHANDLER go_obj->no data FOR: objl 语句中注册的处理器方法nodata。