在线ABAP代码生成器

通常使用ABAP编码会出现一个典型的任务-通过内部表的某些字段的值初始化其他字段(从数据库表中选择,通过调用FM子例程)。 在这种情况下,代码在算法方面非常简单,但是很多。 我一直想减少花在此类常规操作上的时间。 他甚至编写了一种基于程序动态创建的方法,以通过数据库表中的键选择参考值

在评论中指出

代码的可读性 ”是您需要学习的微语言。
动态调用 ”-不欢迎使用动态调用 ,包括在这种情况下使用情况日志未找到使用相应表/字段的位置。

作为替代方案,我仍在建议使用自动代码生成选项,但是直到现在,我才将此东西带到成品工具中 。 谁在乎,请在猫下。

这个想法很简单:有一组参数,根据给定模板,可以通过这些参数生成ABAP代码。

让我们举一个简单的例子:在内部表中,将字段名称乘以字段的值。 用开发人员的技术语言来说: 在内部表中,根据BUKRS字段的值, 根据数据库表T001放入BUTXT字段的值

简单的陈述只有一句话。 但是要实现这一点,您必须在内部表上执行LOOP并在循环中执行SELECT SINGLE(这很快速,但是从速度的角度来看,这不是很受欢迎,尤其是在内部表中有很多行的情况下),或者选择唯一的BUKRS值,对数据库表T001的查询,然后通过READ TABLE记录BUTXT字段的相应值。 在这种情况下,代码将是最优的,但是编写起来并不那么快,因为该代码已经很多了。 而且,它没有什么复杂的-几乎是简单的“猴子”打字工作。

自动生成器可以解决这个问题,因为这样的代码具有样板形式,这意味着其编写可以自动化。

指定以下参数:

DB表: T001
交流领域: BUKRS
初始化的字段: BUTXT

并获取以下生成的代码
*--      T001 FORM values_from_tab_T001 USING "-- ()  uv_in_BUKRS TYPE any "--   uv_out_BUTXT TYPE any CHANGING "--    ct_table TYPE ANY TABLE . "--    ? CHECK NOT ( ct_table[] IS INITIAL ). "--     TYPES: BEGIN OF lty_item, BUKRS TYPE T001-BUKRS, BUTXT TYPE T001-BUTXT, END OF lty_item. DATA ls_item TYPE lty_item. DATA lt_item LIKE TABLE OF ls_item. FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_item. FIELD-SYMBOLS <ls_table> TYPE any. FIELD-SYMBOLS <lv_BUKRS> TYPE any. FIELD-SYMBOLS <lv_BUTXT> TYPE any. "--    LOOP AT ct_table ASSIGNING <ls_table>. CLEAR ls_item. ASSIGN COMPONENT uv_in_BUKRS OF STRUCTURE <ls_table> TO <lv_BUKRS>. ls_item-BUKRS = <lv_BUKRS>. APPEND ls_item TO lt_item. ENDLOOP. "--     SORT lt_item BY BUKRS. DELETE ADJACENT DUPLICATES FROM lt_item COMPARING BUKRS. "--     SELECT BUKRS BUTXT FROM T001 INTO TABLE lt_item FOR ALL ENTRIES IN lt_item WHERE BUKRS = lt_item-BUKRS . "--     SORT lt_item BY BUKRS. "--     LOOP AT ct_table ASSIGNING <ls_table>. "--    ASSIGN COMPONENT uv_in_BUKRS OF STRUCTURE <ls_table> TO <lv_BUKRS>. ls_item-BUKRS = <lv_BUKRS>. "--    ASSIGN COMPONENT uv_out_BUTXT OF STRUCTURE <ls_table> TO <lv_BUTXT>. "--      READ TABLE lt_item ASSIGNING <ls_item> WITH KEY BUKRS = ls_item-BUKRS BINARY SEARCH. IF sy-subrc = 0. IF <lv_BUTXT> IS ASSIGNED. <lv_BUTXT> = <ls_item>-BUTXT. ENDIF. ELSE. IF <lv_BUTXT> IS ASSIGNED. CLEAR <lv_BUTXT>. ENDIF. ENDIF. ENDLOOP. ENDFORM. 

现在,足以在程序中调用生成的子例程

 PERFORM values_from_tab_T001 USING 'BUKRS' 'BUTXT' CHANGING lt_TABLE. 

ABAP生成器网站上查看代码
内部表中的字段名称和内部表本身作为参数传递给子例程。 通话后,BUTXT字段将具有所需的值。

内部表中字段的名称以参数的形式制成,因此可以为不同的字段调用相同的子例程。 即 如果内部表中有两个BE字段(例如BUKRS1和BUKRS2),则只需要生成一个子例程并调用两次即可

 PERFORM values_from_tab_T001 USING 'BUKRS1' 'BUTXT1' CHANGING lt_TABLE. PERFORM values_from_tab_T001 USING 'BUKRS2' 'BUTXT1' CHANGING lt_TABLE. 

在这种情况下,由于数据库表T001中会有两个SELECT,因此出现“非最佳性”,尽管在理想情况下,您可以一次完成所有操作。 但这是自动化的成本。 这不太可能会大大减慢程序的执行速度,但是如果有必要,您可以始终根据自己的私人需要“完成”子程序。

您可以一次初始化几个字段,并在条件中指定常量(例如sy-langu,这在选择文本时经常使用)。 在标准示例中,根据表T006A选择UE的名称

生成代码时,还会创建一个链接,通过该链接可以在浏览器中打开创建的示例。

当前,生成器中有几个模板:

  1. 定义结构[+表类型] -定义结构+表类型+此类型的表+表工作空间+表的字段符号。 这并非总是必要的,但是与手动输入相比,删除生成的内容要容易得多
  2. 通过字段从内部表中删除重复的记录是一个非常简单的生成器,通常,此类代码可以手动编写,但是在我看来,如果有很多字段,则最好使用此模板
  3. 从数据库表中选择参考值 -上述模板
  4. 选择参考值 -该模板允许您通过调用FM子程序来设置字段值。 在这种情况下,将缓存呼叫。
  5. 从域中选择参考值 -此模板没有参数,并且已添加,仅能将此代码复制到您的程序中

我认为对每个模板的操作进行详细描述是没有意义的,因为在站点上更容易看到其工作结果。 每个模板都有其参数的默认值,如果您是abap开发人员,则可以快速理解代码。

Source: https://habr.com/ru/post/zh-CN426967/


All Articles