本地化全局变量

Localizing global variables

使用扩展程序检查时,我收到以下警告:

Do not declare fields and field symbols (variable name) globally.

这是在选择屏幕之前声明全局数据。显而易见的解决方案是它们应该在子例程中本地声明。

如果我决定这样做,数据现在将超出其他子程序的范围,所以我最终会创建一些东西来达到 C 或 [=32= 中的 main() 函数的效果].这听起来是个好主意 - 然而,诸如 INITIALIZATION 之类的事件不允许出现在子例程内,这意味着它会强制中断范围。

观察下面的示例程序:

REPORT Z_EXAMPLE.
SELECTION-SCREEN BEGIN OF BLOCK upload WITH FRAME TITLE text-H01.
  PARAMETERS: p_infile TYPE rlgrap-filename LOWER CASE OBLIGATORY.
SELECTION-SCREEN END OF BLOCK upload.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_infile.
  PERFORM main1 CHANGING p_infile.
INITIALIZATION.
  PERFORM main2.
TOP-OF-PAGE.
  PERFORM main3.
...
据我所知,

main1main2main3 不能在没有全局声明的情况下相互传递任何数据。如果数据是从main1中上传的文件p_infile解析出来的,那么在main2main3中是访问不到的。除了一起省略事件之外,有什么方法可以遵守警告但让数据通过事件传递?

有多种技术 - 除了基本的选择屏幕处理之外,我更喜欢在单独的控制器中编写几乎所有代码 class。该报告只是遵从 class 并调用其方法。除此之外 - 如果您知道自己在做什么,这只是一个警告,您可以忽略它。编写完全没有任何全局变量的程序肯定是不切实际的 - 但是,在方法参数更合适的地方使用全局变量或属性之前,您应该至少三思。

正如@vwegert 所说的那样,编写一个没有至少几个全局变量的 ABAP 程序几乎是不可能的(不幸的是,选择屏幕和事件强制执行了这一点)。

一种方法是使用控制器class,另一种方法是有一个主子例程并让它根据需要调用其他子例程,根据需要传递值。在很多情况下,我倾向于支持后一种方法,只是因为它更容易将子例程拆分为单独包含的逻辑分组(使用 classes 这样做有时会有点难看)。虽然这确实是一个方法问题,但关键是将全局变量减少到最低限度——不幸的是,我遇到的 ABAP 开发人员很少关心这些问题。

更新

@Christian 提醒我,从 ABAP AS 7.02 开始,子例程是 considered obsolete:

Subroutines should no longer be created in new programs for the following reasons:

  • The parameter interface has clear weaknesses when compared with the parameter interface of methods, such as:

    • positional parameters instead of keyword parameters
    • no genuine input parameters in pass by reference
    • typing is optional
    • no optional parameters
  • Every subroutine implicitly belongs to the public interface of its program. Generally this is not desirable.

  • Calling subroutines externally is critical with regard to the assignment of the container program to a program group in the internal session. This assignment cannot generally be defined as static.

这些都是有效的观点,我认为,使用 classes 进行模块化绝对是首选方法(并且从纯粹的美学角度来看,它们也更“适合” 7.02 及更高版本中的语法增强)。