从另一个程序中读取变量

Ped*_*rsi 1 sap abap

当我处于堆栈的11级时,我想从5级访问一个变量。

两个级别的程序都不相同:

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>.
...
Run Code Online (Sandbox Code Playgroud)

这是我目前正在做的事情:

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>.
Run Code Online (Sandbox Code Playgroud)

现在,我可以在另一个程序中使用<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.
Run Code Online (Sandbox Code Playgroud)
  1. 就是那个犯规,index_all
  DATA: index_all TYPE t_t_pernr.
Run Code Online (Sandbox Code Playgroud)

这意味着此过程(program)variable仅适用于common part由ldb 声明为“ ”的变量?

换句话说,index_all当我在程序中时,不可能从LDB程序中获取的内容,因为它不是“ common part”?

->给出一个上下文,index_all具有我需要的所有条目,而index只是的一个分区index_all。ldb进行迭代index,完成后,它将使用的下一个索引对其进行更新index_all

San*_*ssi 6

我认为文档说明了一切:

仅供内部使用,名称中的名称也可以采用“(PROG)DOBJ”格式,其中“ PROG”是ABAP程序的名称,“ DOBJ” 是该程序的全局数据对象的名称(这些名称是不区分大小写)。如果在执行ASSIGN语句时将程序“ PROG”加载到与当前程序相同的内部会话中,则在该程序中将找到数据对象“ DOBJ”,并且如果分配成功,则字段符号将指向该数据对象。

注意“仅供内部使用”,即ASSIGN的这种特殊形式可以在将来的ABAP版本中删除(但我怀疑)。

因此,可能您想访问的变量不是global,即local,instance属性或private / protected静态属性。

ASSIGN ('PROG(DOBJ)')common part之所以与之合作,是因为它具有全球范围。注意,通过声明“公共部分”的相同名称,公共部分也可以在没有ASSIGN的情况下被属于同一“组”(1)的其他程序使用。

如果您可以修改程序(因为它是自定义的),则最好对其进行一点重构,以便可以从外部访问数据,而不是使用以下技巧。

如果您不能适应该程序(因为它是标准程序),则可以通过以下变通方法来访问本地数据对象

假设该程序是“ PROG”,它包含过程“ X”,该过程包含要读取的本地数据对象“ LOCVAR”。您可以使用增强框架来做到这一点。因此,要使其可从外部程序访问:

  • 在PROG中,声明一个全局数据引用变量(2),例如DATA ZZ_REF_LOCVAR TYPE REF TO DATA(建议:将其前缀为“ ZZ”以限制与程序的将来补丁的冲突)
  • 在过程“ X”的开头,通过代码ASSIGN ('LOCVAR') TO FIELD-SYMBOL(<zz_locvar>). zz_ref = ref #( <zz_locvar> ).(3)初始化ZZ_REF_LOCVAR
  • 在您自己的程序中,如果过程“ 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)注意:一 “程序”由通过PERFORM IN PROGRAM或PROG的CALL SUBSCREEN调用的程序组成,它们具有称为“ 接口工作区 ” 的公共存储区。

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

(3)注意:过程“ X”开头的隐式增强不能通过命名它们直接访问局部变量,因为它们DATA在增强之后;解决方法是在运行时使用字段符号访问局部变量。

  • 如果其他程序是自定义程序,则只需要求您的开发人员对其进行调整,以使数据可以在外部使用。上面提出的解决方案是最糟糕的! (2认同)