читать переменную из другой программы в abap - PullRequest
1 голос
/ 17 апреля 2019

Я бы хотел получить доступ к переменной с уровня 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.
тот, который не делает, 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.

1 Ответ

6 голосов
/ 18 апреля 2019

Я думаю, что документация говорит само за себя:

Только для внутреннего использования, имя в имени также может иметь форму "(PROG) DOBJ", где "PROG""- это имя ABAP-программы , а" DOBJ "- имя global объекта данных этой программы (эти имена не чувствительны к регистру).Если программа "PROG" загружена в тот же внутренний сеанс , что и текущая программа, когда выполняется оператор ASSIGN, объект данных "DOBJ" найден в этой программе, и символ поля указывает на этот объект данныхесли назначение было успешным.

Обратите внимание на «только для внутреннего использования», то есть эта специальная форма ASSIGN может быть удалена в любой будущей версии ABAP (но я сомневаюсь).

Итак, вероятно, вы хотитеполучить доступ к переменной, которая не global , то есть либо локальная, атрибут экземпляра, либо закрытый / защищенный статический атрибут ...

ASSIGN ('PROG(DOBJ)') работает с common part, поскольку имеет global scope.Обратите внимание, что общая часть может также использоваться без ASSIGN другими программами, которые принадлежат к той же «группе» (1), объявив то же имя «общей частью».

Если вы можете адаптировать программу (потому что это пользовательский режим), предпочтите немного рефакторинг, чтобы к данным можно было получить доступ извне, а не с помощью описанного ниже трюка.

Если вы не можете адаптировать программу (потому что она стандартная), естьследующий обходной путь к доступ к локальному объекту данных .

Допустим, эта программа является «PROG» и содержит процедуру «X», которая содержит локальный объект данных «LOCVAR», который вы хотитечитать.Для этого вы можете использовать Enhancement Framework .Итак, чтобы сделать его доступным из внешних программ:

  • В 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) Примечание: " группа " программ сформирована из программ, вызываемых через PERFORM IN PROGRAM или CALL SUBSCREENPROG, и у них есть общая область памяти, называемая « рабочая область интерфейса ».

(2) Примечание: я предлагаю глобальную переменную ссылки на данные, а не глобальный символ поля, потому что символы поляне может быть объявлено глобально в таких программах, как пулы классов.

(3) Примечание: неявное улучшение в начале процедуры «X» не может получить доступ к локальным переменным напрямую, назвав их, потому что их DATA послеулучшение;Обходной путь должен использовать символ поля для доступа к локальной переменной во время выполнения.

...