本地化全局变量
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.
...
据我所知,main1
、main2
和 main3
不能在没有全局声明的情况下相互传递任何数据。如果数据是从main1
中上传的文件p_infile
解析出来的,那么在main2
或main3
中是访问不到的。除了一起省略事件之外,有什么方法可以遵守警告但让数据通过事件传递?
有多种技术 - 除了基本的选择屏幕处理之外,我更喜欢在单独的控制器中编写几乎所有代码 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 及更高版本中的语法增强)。
使用扩展程序检查时,我收到以下警告:
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.
...
据我所知,main1
、main2
和 main3
不能在没有全局声明的情况下相互传递任何数据。如果数据是从main1
中上传的文件p_infile
解析出来的,那么在main2
或main3
中是访问不到的。除了一起省略事件之外,有什么方法可以遵守警告但让数据通过事件传递?
有多种技术 - 除了基本的选择屏幕处理之外,我更喜欢在单独的控制器中编写几乎所有代码 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 及更高版本中的语法增强)。