Автор Тема: CL_MMIM_USERDEFAULTS - Хранение собственных значений переменных в Z-программах  (Прочитано 7301 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 809
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Управление значениями переменных в собственных Z-программах (Класс CL_MMIM_USERDEFAULTS)


Очень часто в собственных разработках приходится где-то хранить состояние значения каких-то переменных для их восстановления во время работы в следующих сеансах системы, например это могут быть значения чек-боксов селекционного экрана, которые задал пользователь. Можно конечно воспользоваться хранением значений параметров, команды SET / GET PARAMETER ID, но тут есть тонкость, которая заключается в том, что значения переменных хранятся только на время сеанса и, следовательно, при новом входе в систему, предыдущее состояние переменных будет недоступно. Можно, например, еще воспользоваться хранением значений в общей памяти через команды IMPORT / EXPORT TO DATABASE. Однако, как мне кажется, SAP как-то не ровно дышит к этой возможности и не рекомендует оставлять значения в этой памяти на долгосрочное хранение, т.е. после работы программы рекомендуется чистить используемые параметры, а так как хранить получается нужно много, то обычно для этих целей используют таблицы БД. Сам кстати не раз так делал, в разных системах, когда нужно, делаешь это или по-разному, или в лучшем случае, используешь copy-past своих где-то сохраненных программ. Но это не всегда возможно, так как если в компании серьезная служба поддержки и ведения разработок, то легализовать эту разработку сложно, так как делать ее в рамках какой-то одной разработки не выход, использовать хочется в разных программах, а сделать библиотекой, довольно сложно. Случайно тут как-то нашел, что как обычно в SAP, все уже написано до нас, просто, как всегда, никто не сказал где написано и кем написано, поэтому в этом раз сам говорю, что есть класс  CL_MMIM_USERDEFAULTS - который позволяет хранить такие вот переменные данные в зависимости от пользователя и программы. Класс довольно простой, поэтому рассмотрю его работу на примере небольшого отчета.

Примечание: Исследовать версию системы с которой доступен данный класс, мне сейчас сложно, похоже что с версии ECC 6.0 данный класс есть во всех вариантах. У меня дата последнего изменения данного класса отмечена как 06.05.2002. Так что думаю с переносимостью проблем не будет.

Программа простая имеет несколько чек-боксов, при этом начальное состояние данных переключателей должно быть следующим, переключатели P_OPEN и P_CLOSE должны быть установлены, а P_EXIT нет. Что это значит, это значит, что при первом запуске программы, когда никакое состояние переключателей нигде еще не сохранено, должна быть установлена их предопределенная комбинация. Обычно это достигается через указание ключа DEVAULT VALUE <знчение>, но в данном случае, это можно не делать, так как заданием начальных значений у нас будет заниматься наш класс.

Далее идет собственно сам текст программы:
Код: You are not allowed to view links. Register or Login
*&---------------------------------------------------------------------*
*& Report  ZTEST_USERDEFAULTS_CALSS
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ztest_userdefaults_calss.

*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
PARAMETERS: p_open  AS CHECKBOX,
            p_close AS CHECKBOX,
            p_exit  AS CHECKBOX.

*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
DATA: gc_settings TYPE REF TO cl_mmim_userdefaults.

*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
INITIALIZATION.
* Инициализация параметров экрана
  PERFORM settings_init.


*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
AT SELECTION-SCREEN.
* Сохранить введенные пользователем значения параметров
  PERFORM settings_save.


*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
START-OF-SELECTION.
  WRITE: 'Test class CL_MMIM_USERDEFAULTS. Variables are SAVE'.


*----------------------------------------------------------------------*
*------------- Подпрограммы -------------------------------------------*
*----------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*&      Form  SETTINGS_INIT
*&---------------------------------------------------------------------*
*       Считать значения параметров для экрана
*----------------------------------------------------------------------*
FORM settings_init .
  IF gc_settings IS INITIAL.
    CREATE OBJECT gc_settings EXPORTING i_action = 'ZTEST_USERDEFAULTS_CALSS'.
    CALL METHOD gc_settings->preset( i_element = 'P_OPEN' i_active = abap_true ).
    CALL METHOD gc_settings->preset( i_element = 'P_CLOSE' i_active = abap_true ).
  ENDIF.
  p_open  = gc_settings->get( 'P_OPEN' ).
  p_close = gc_settings->get( 'P_CLOSE' ).
  p_exit  = gc_settings->get( 'P_EXIT' ).
ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  SETTINGS_SAVE
*&---------------------------------------------------------------------*
*       Сохранить значения параметров введенные на экране
*----------------------------------------------------------------------*
FORM settings_save.
  CALL METHOD gc_settings->set( i_element = 'P_OPEN' i_active = p_open ).
  CALL METHOD gc_settings->set( i_element = 'P_CLOSE' i_active = p_close ).
  CALL METHOD gc_settings->set( i_element = 'P_EXIT' i_active = p_exit ).

  CALL METHOD gc_settings->flush.
ENDFORM.

Как видим программа не сложная, как и методика работы с классом. Рассмотрим по шагам, что выполняется во время работы программы.

1.1. После запуска программы на выполнение, система выполнит блок кода заданный в секции INITIALIZATION. В данном блоке мы поставили вызов подпрограммы в которой создадим класс для работы с переменными если он не создан и зададим начальные значений переменных, если это первый вызов программы пользователем. Далее считаем заданные значения. Итак, если IF gc_settings IS INITIAL, класс не создан то выполнить создание экземпляра объекта. При создании мы указываем переменную i_action = 'ZTEST_USERDEFAULTS_CALSS', фактически это ключ доступа к нашим переменным, которые мы дальше будем сохранять и читать. Имя может быть любым, обычно тут пишут имя программы, можно просто написать SY-PROG. Так же у конструктора есть необязательный параметр I_UNAME, который по умолчанию будет равен имени пользователя, от которого запущена программа. Это позволяет с одной стороны хранить уникальные значения запуска программы для каждого пользователя, а с другой стороны позволяет сделать так, чтобы например, все пользователи работали с одним набором параметров и следующий пользователь получал значения, установленные в предыдущем сеансе.

1.2. Далее мы задаем значения по умолчанию для выбранных нами флажков, если это выполняется первый вход в систему, т.е. мы говорим что флажки P_OPEN и P_CLOSE будут установлены в значение = "Х". Обратите внимание, что если это уже не первый запуск программы, и предыдущее значение флажка, например, было задано как равное " ", то эта команда не перезапишет уже сохраненное значение, т.е. метод gc_settings->preset( i_element = 'P_OPEN' i_active = abap_true ), это именно инициализация начального значения, если в БД нет никакой информации по состоянию флажков.

2.1. Вызываем получение последнего значения переменных для программы. Для этого используем метод  p_open  = gc_settings->get( 'P_OPEN' ), который возвращает нам значение запрошенной переменной. При этом значение будет считано, так как оно было сохранено при последнем запуске программы, или, если это первый запуск, то будет считано значение, заданное в методе PRESET, на шаге 1.2

3.1 Сохранение текущих значений переменных в БД. В данном примере это выполняется в событии AT SELECTION-SCREEN, и тем самым достигается такой результат, что если отчет был выполнен с заданными параметрами, то значения переменных будут сохранены иначе если мы зашли на селекционный экран и вышли, не запустив отчет, то значения переменных сохранятся не будут. Сохранение выполняется методом gc_settings->set( i_element = 'P_OPEN' i_active = p_open ), в который передаем имя переменной программы и саму переменную, чтобы метод мог сохранить ее текущее значение. Далее для записи данных вызываем метод gc_settings->flush, который физически сохранит все в БД.


Как видим все работает очень просто. Теперь несколько замечаний по внутреннему механизму кухни данного класса.

1. Физическое сохранение данных происходит при вызове COMMIT WORK, в самом классе нет метода обновления данных. Вы или должны вызвать фиксацию изменений сами или это сделает неявный COMMIT, например, в данном случае, такая фиксация происходит при переходе между экранами с селекционного на экран вывода информационного сообщения.

2. Внутри класса выполняется оптимизация того что нужно писать в БД, т.е. если пользователь не изменил значение переменной, то и запись значения такой переменной выполнятся не будет, как говорится незачем грузить лишним БД.

3. Значения сохраняются в таблицу базы данных ESDUS - "MM - динамические параметры настройки пользователя". Ну что это только ММ, это дело такое, никто не запрещает там хранить что-то свое, что мы и делаем. А второе ограничение, заключается в том, что ACTIVE - поле в котором выполняется сохранение значения переменной, имеет значение CHAR(50), т.е. если переменная имеет длину более 50 символов, то ее длина будет обрезана. Из приятного, хранить можно не только строки, но и числа и вообще все, что может быть преобразовано в строку.

PS: Как обычно все в одном файле: CL_MMIM_USERDEFAULTS - Хранение собственных параметров.pdf

Sapforum.Biz