在运行时从另一个程序中读取非全局变量。

问题描述 投票:2回答:1

我想从第5层访问一个变量,当我在栈的第11层时。

两个级别都是不同的程序。

lvl    type       event              program                 include 
11     METHOD     SET_PERNRS_TAB     <my_program>            <my_include>.
...
05     FORM       PUT_PERNR          <ldb_program>          <ldb_include>.
04     FORM       %_ROOT             <ldb_program>          <ldb_include>.
...

这是我目前的做法。

constants lc_ldb_pernr_tab   type string value `(LDB_PROGRAM)INDEX[]`.
field-symbols <lt_pernr_tab> type any table.

assign (lc_ldb_pernr_tab) to <lt_pernr_tab>.

现在我可以用 <lt_pernr_tab>的 "副本",它是变量 index[] 在另一个程序中,来自LDB的变量。

这里的问题是,它只对一些变量有效,而对其他变量无效......请在下面找到两个变量的声明,在ldb程序中。

我试图从我的程序中获取它们的值,但只有一个能用。

  1. 工作的那个。index:
DATA: BEGIN OF COMMON PART $pnp-index$.
  DATA: BEGIN OF index OCCURS 1000,
          pernr LIKE pernr-pernr,
        END OF index.
DATA: END   OF COMMON PART.
  1. 那一个没有。index_all:
  DATA: index_all TYPE t_t_pernr.

这意味着,这一进程 (program)variable 只适用于声明为"common part"由ldb?

换句话说,不可能由? index_all 当我在我的程序中时,从LDB程序中取出,因为它不属于"common part"?

->来说明一下背景。index_all 有我需要的所有条目,而 index 只是一个隔断 index_all. 迭代的ldb通过 index 当它完成后,它用下一个索引更新它的 index_all.

dynamic sap abap
1个回答
8
投票

我认为 文件 说的就是这个。

仅供内部使用,名称中的名称也可以采用"(PROG)DOBJ "的形式,其中 "PROG "是一个项目的名称。ABAP程序 和 "DOBJ "的名称。全球性 这个程序的数据对象(这些名称不区分大小写)。如果程序 "PROG "被加载到相同的 内部会议 作为当前程序,当语句ASSIGN被执行时,数据对象 "DOBJ "在这个程序中被找到,如果赋值成功,字段符号指向这个数据对象。

请注意 "仅供内部使用",即这种特殊形式的ASSIGN可能会在未来的任何ABAP版本中被删除(但我怀疑)。

所以,可能你想访问的变量不是 全球性即本地、实例属性或私有保护的静态属性...。

ASSIGN ('PROG(DOBJ)')common part 因为它有一个 全球性 范围。需要注意的是,一个公共部分也可以不通过ASSIGN被属于同一个 "组"(1)的其他程序使用,只要声明相同的 "公共部分 "名称即可。

如果你能改编程序(因为它是自定义的),宁愿重构一下,使数据可以从外部访问,而不是使用下面的技巧。

如果你不能改编程序(因为它是标准的),有下面的变通方法可以解决 访问本地数据对象.

假设这个程序是 "PROG",它包含了存储过程 "X",其中包含了要读取的本地数据对象 "LOCVAR"。你可以使用 加强框架 来做到这一点。所以,为了使外部程序能够访问它。

  • 在PROG中,声明一个全局数据参考变量(2),例如: DATA ZZ_REF_LOCVAR TYPE REF TO DATA (建议:前缀为 "ZZ",以限制与未来程序补丁的冲突)
  • 在存储过程 "X "的开始,通过代码初始化ZZ_REF_LOCVAR。ASSIGN ('LOCVAR') TO FIELD-SYMBOL(<zz_locvar>). zz_ref = ref #( <zz_locvar> ). (3)
  • 在你自己的程序中,如果过程 "X "当前在调用栈中,那你可以用类来检查 CL_ABAP_GET_CALL_STACK现在,你可以使用这段代码访问指向本地变量的全局数据引用。FIELD-SYMBOLS <ref_locvar> TYPE REF TO DATA. FIELD-SYMBOLS <locvar>. ASSIGN ('(PROG)ZZ_REF_LOCVAR') TO <ref_locvar>. ASSIGN <ref_locvar>->* TO <locvar>.
  • 这个解决方案的一个小变种是声明 ZZ_REF_LOCVAR 作为自定义类池中的一个静态公共属性,并从标准程序PROG和你自己的代码中访问它。

请注意如果未来的补丁删除了局部变量,那么它可能就不能工作了。无论如何,这句话对全局变量也是有效的。


(1) 注意:一个"群体"的程序是由通过PROG调用PERFORM IN PROGRAM或CALL SUBSCREEN的程序组成的,它们有一个共同的内存区域,称为"界面工作区".

(2)注意:我建议采用全局数据引用变量,而不是全局字段符号,因为字段符号在程序中不能像类池那样全局声明。

(3)注意:程序 "X "开头的一个隐性增强,不能直接通过命名访问局部变量,因为它们的 DATA 是增强后的,变通的办法是在运行时使用字段符号来访问本地变量。

© www.soinside.com 2019 - 2024. All rights reserved.