完整源代码见文末。

如今像 Visual Studio Code,Eclipse,Sublime Text,甚至 Chrome 这些编程 IDE,代码编辑器和开发辅助工具,通过 Extension & Plugin 的方式,来对其增添额外功能,仿佛已经成为编程工具圈里的标配了。

和这些后辈们相比,SAPGUI 算是爷爷级的存在了。

其实 SAPGUI 里的 ABAP 代码编辑器,比如 SE24,SE37,SE38 和 SE80,UI 和逻辑均由 ABAP 编写。因此理论上来说,一个 ABAP 开发者,如果觉得这些事务码某些方面的功能有所欠缺,大不了自己动手创建增强就行了。

只不过 SE80 等事务码的内部设计和逻辑,无论国内还是国外的技术博客,讲这一块的资料都很稀缺,所以很多想自己动手的朋友,也不知道从哪里入手。

本文就从 SE80 等 ABAP 代码编辑器的语法检查功能,如何去定制化作为例子,介绍 SAPGUI 环境下开发工具增强的实现步骤。

在 SAP 社区上已经有一些博客,介绍了如何在 ABAP Code Inspector 或 ATC Check 中,实现自定义的语法检查:

https://blogs.sap.com/2006/11/02/code-inspector-how-to-create...

在 SAPGUI 代码编辑器里,需要点击多次鼠标才能触发这些自定义实现的检查逻辑。

我这个人比较懒,能点一次鼠标或键盘就能完成的操作,我绝不想点两次。本文介绍的自定义语法检查逻辑,通过 SAPGUI 快捷键 Ctrl+F2 就能直接触发。

比如打开一个 ABAP 类的某个方法,点击语法检查图标,或按快捷键 Ctrl+F2:

这会触发我实现的自定义语法检查,具体逻辑是:

如果当前方法的总行数超过了硬编码的阈值,比如说 100,自定义语法检查的实现,就会在 Class Builder 中显示 Warning 消息,如下图所示:

对于仅仅使用 SAPGUI 来完成业务操作的用户来说,可能会认为在 SAPGUI 中的操作,比如在 Class Builder 类中双击一个方法,看到自己想要查看的内容,是一件顺理成章的事情。然而这些工具本身,底层的处理逻辑的实现复杂度,远远超出普通人的想象。

比如我在 SE80 里打开一个 ABAP 报表,双击某个 subroutine,在右边看到其源代码:

这个操作背后的处理流程如下图所示:

ABAP Workbench 中由用户发起的每一个操作,都被类 CL_WB_REQUEST 的一个实例封装,这个实例中包含了有关给定操作的所有详细信息,例如被点击对象的对象名称和对象类型(类方法,透明表或任何其他 ABAP 仓库对象),以及操作类型(增删改,查看等等)。

不同的请求操作类型由不同的 Handler Classes 来服求,这些类在配置表 WBREGISTRY 中统一维护。这个配置表的内容由类 CL_WB_REGISTRY 暴露。

类 CL_WB_MANAGER 作为一个中介,通过 CL_WB_REQUEST 的实例,以统一的方式与这些工具进行通信。

在有的 ABAP 代码编辑器的操作场景下,用户进行某种操作后,出于操作复杂性的因素,无法仅仅通过查看配置表 WBREGISTRY 来简单地确定对应的处理器类。在这种情况下,可以通过实现接口 IF_WB_DECISION_CLASS,来编写如何动态决定出需要指派哪一个 Handler Class 去响应用户发起的请求。

下面是对 ABAP 类方法的代码行数这一自定义语法检查的详细实现步骤。

  1. 通过继承标准类 CL_WB_CLEDITOR 的方式来创建一个新类 ZCL_WB_CLEDITOR. 这个新类的完整的源代码,可以通过阅读原文获得。

主要逻辑在方法 CHECK_METHOD_SOURCE 的重定义中实现。首先完成超类中的标准检查逻辑,如果发现语法错误,将它们显示给最终用户;否则在第 14 行执行自定义语法检查,也就是进入我编写的 custom_syntax_check 方法里。

custom_syntax_check 方法的实现逻辑很简单,读取当前被检查的 ABAP 方法的源代码到内表变量中,计算该内表的行数,如果大于 100,就抛出语法警告消息。

详细代码,大家请点击文末的阅读原文获得。

大家可能会问,我咋知道为什么要继承 CL_WB_CLEDITOR 这个类?好吧,我只是从单步调试中知道,当点击语法检查的图标,或使用快捷键 Ctrl+F2 时,会调用这个类:

  1. 在标准 ABAP 类 CL_OO_METHOD_REQ_DISPATCHER 的方法 GET_TOOL_FOR_REQUEST上创建一个新的 Post-Exit:

这个 Post-Exit 的实现很简单,返回我们在第一步扩展自标准类,并实现了自己自定义语法检查的子类 ZCL_WB_CLEDITOR.

在 Post-Exit 实现里,返回我们自定义的 ZCL_WB_CLEDITOR.

这样每当 Ctrl+F2 触发 ABAP 类的语法检查之后,我们自己编写的 ZCL_WB_CLEDITOR, 就会被 ABAP Editor 的处理框架调度并执行。

至此这个简单的 SAPGUI 环境下的 ABAP 语法检查的自定义增强需求就实现了。本文给出了扩展 SAPGUI 里标准功能的一些思路,大家在实际工作中可以灵活运用,来调整 SAPGUI 里一些标准事务码的行为,使其符合自己定制化的需求。

完整源代码

class ZCL_WB_CLEDITOR definition
  public
  inheriting from CL_WB_CLEDITOR
  final
  create public .

public section.

  methods CHECK_METHOD_SOURCE
    redefinition .
protected section.
private section.

  methods CUSTOM_SYNTAX_CHECK
    changing
      !CHECK_LIST_OBJECT type ref to CL_WB_CHECKLIST .
ENDCLASS.



CLASS ZCL_WB_CLEDITOR IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_WB_CLEDITOR->CHECK_METHOD_SOURCE
* +-------------------------------------------------------------------------------------------------+
* | [--->] ALL_ERRORS                     TYPE        CHAR1 (default =SPACE)
* | [<---] CHECK_LIST_OBJECT              TYPE REF TO CL_WB_CHECKLIST
* | [<---] NAVIGATION_REQUEST             TYPE REF TO CL_WB_REQUEST
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD check_method_source.

    CALL METHOD super->check_method_source
      EXPORTING
        all_errors         = all_errors
      IMPORTING
        check_list_object  = check_list_object
        navigation_request = navigation_request.

    CHECK sy-uname = 'WANGJER'.

    CHECK check_list_object IS INITIAL.

    custom_syntax_check( CHANGING check_list_object = check_list_object ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_WB_CLEDITOR->CUSTOM_SYNTAX_CHECK
* +-------------------------------------------------------------------------------------------------+
* | [<-->] CHECK_LIST_OBJECT              TYPE REF TO CL_WB_CHECKLIST
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD custom_syntax_check.
    CONSTANTS: cv_threshold TYPE int4 VALUE 100.
    DATA: lt_source TYPE seop_source,
          lt_text   TYPE rsfb_source.

    CALL FUNCTION 'SEO_METHOD_GET_SOURCE'
      EXPORTING
        mtdkey = mtdkey
        state  = 'A'
      IMPORTING
        source = lt_source.

    IF lines( lt_source ) > cv_threshold.
      check_list_object = NEW #( ).
      APPEND `This warning message is raised by Jerry's custom syntax check`  TO lt_text.
      APPEND | method: { mtdkey-cpdname } has totally { lines( lt_source ) } lines of source code, please refact it to ensure   | TO lt_text.
      APPEND | no more than { cv_threshold } lines in a single method. | TO lt_text.

      check_list_object->add_error_message( p_message_text = lt_text p_message_type = 'W' ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

注销
1k 声望1.6k 粉丝

invalid