К основному контенту

События для ведения таблиц

Как и всегда, в пылу проекта внезапно родилась Z табличка. Главный нюанс был в том, что она должна была хранить пароли для авторизации на стороннем сервере. Естественно, никто не хотел хранить пароли в открытом виде, а двустороннее шифрование SAP не умеет без сторонних пакетов и надстроек. Далее, все как обычно - придумали алгоритм, сделали табличку. Дело осталось за малым - нужно шифровать пароли, которые вводит пользователь.
Делать отдельную программу нет смысла, поскольку ее функционал мало чем будет отличаться от сгенерированного. Вот здесь на помощь приходят события! С их помощью можно, наверное, все. По крайней мере, я не нашел чего-либо, что нельзя сделать с данными через события.

Step-by-step


В качестве алгоритма шифрования для примера укажу MD5.
Итак, по порядку:

Шаг 1. Создаем табличку



Немного пояснений: все поля я описывать не буду, остановлюсь только на последних двух - PASSWORD и HASHPASS. Поле PASSWORD с целом фиктивное, оно сделано только для того, что бы пользователи вводили туда пароль. Сам пароль будет храниться в поле HASHPASS в зашифрованном виде.

Шаг 2. Генерируем ракурс ведения

Тут ничего сложного нет - все по отлаженной схеме

Шаг 3. Создаем события

Для создания событий переходим по меню прямо из окна генератора ракурса ведения
После этого откроется табличка, в которой можно настроить функцию (FORM) на определенное событие. Все возможные события перечислены в Search-Help для поля МВр
На скриншоте много событий, но я остановлюсь только на двух: 01 - событие перед сохранением и 05 - событие перед добавлением новой записи.

Шаг 3. Событие перед добавлением новой записи (05)

В момент добавления новой записи мне нужно зашифровать пароль. После того, как я привязал к событию имя формы, ее нужно создать. Ниже представлен код, который работает при добавлении новой записи в таблицу

FORM before_add_record.
  DATA: lv_value TYPE string.
  MOVE: ziki_t_auth-password TO lv_value.
  CALL FUNCTION 'Z_IKI_HASH_PASSWORD'
    EXPORTING
      lv_password      = lv_value
    IMPORTING
      ev_hash          = ziki_t_auth-hashpass
    EXCEPTIONS
      ex_iternal_error = 1
      OTHERS           = 2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.
 
ENDFORM.                    "BEFORE_ADD_RECORD

Здесь вызывается ФМ, который шифрует пароль - все просто. Результат шифрования возвращается в поле HASHPASS.

Шаг 4. Событие перед сохранением (01)

Именно это событие вызывает интерес. Оно не реагирует на сохранение отдельной записи, оно происходит один раз и сразу для всех записей. Беда в том, что отдельных записей, которые были модифицированы, я не нашел.
Ниже представлен код, который обрабатывает измененные записи.

FORM before_save.
  DATA: lt_auth TYPE TABLE OF ziki_t_auth.
  DATA: ls_tab TYPE ziki_t_auth.
  DATA: lv_value TYPE string.
  DATA: lv_hash TYPE ziki_t_auth-hashpass.
 
  FIELD-SYMBOLS: <fs_field> TYPE any .
  FIELD-SYMBOLS: <lt_auth> LIKE LINE OF lt_auth.
 
  SELECT *
    FROM ziki_t_auth
    INTO TABLE lt_auth.
 
 
  LOOP AT total.
    CLEAR: ls_tab.
 
    ASSIGN COMPONENT 'BUKRS' OF STRUCTURE <vim_total_struc> TO <fs_field>.
    IF sy-subrc EQ 0 .
      ls_tab-bukrs = <fs_field>.
    ENDIF.
 
    ASSIGN COMPONENT 'STEP' OF STRUCTURE <vim_total_struc> TO <fs_field>.
    IF sy-subrc EQ 0 .
      ls_tab-step = <fs_field>.
    ENDIF.
 
    ASSIGN COMPONENT 'USERID' OF STRUCTURE <vim_total_struc> TO <fs_field>.
    IF sy-subrc EQ 0 .
      ls_tab-userid = <fs_field>.
    ENDIF.
 
    ASSIGN COMPONENT 'PASSWORD' OF STRUCTURE <vim_total_struc> TO <fs_field>.
    IF sy-subrc EQ 0 .
      ls_tab-password = <fs_field>.
    ENDIF.
 
    READ TABLE lt_auth
      ASSIGNING <lt_auth>
      WITH KEY
      bukrs = ls_tab-bukrs
      step = ls_tab-step
      userid = ls_tab-userid.
    IF sy-subrc NE 0.
      CONTINUE.
    ENDIF.
 
    MOVE: ls_tab-password TO lv_value.
 
    CALL FUNCTION 'Z_IKI_HASH_PASSWORD'
      EXPORTING
        lv_password      = lv_value
      IMPORTING
        ev_hash          = lv_hash
      EXCEPTIONS
        ex_iternal_error = 1
        OTHERS           = 2.
    IF sy-subrc <> 0.
      CONTINUE.
    ENDIF.
 
    IF <lt_auth>-hashpass NE lv_hash.
      ASSIGN COMPONENT 'HASHPASS' OF STRUCTURE <vim_total_struc> TO <fs_field>.
      IF sy-subrc EQ 0 .
        <fs_field> = lv_hash.
      ENDIF.
 
      READ TABLE extract WITH KEY <vim_xtotal_key>.
      IF sy-subrc = 0.
        extract = total .
        MODIFY extract INDEX sy-tabix.
      ENDIF.
      MODIFY total.
 
    ENDIF.
 
  ENDLOOP.
 
ENDFORM.                    "BEFORE_SAVE

Кратко по алгоритму - в основе всего лежит цикл по итоговой внутренней табличке total. Это глобальная переменная и доступна везде. Для проверки, изменился ли пароль, т.е. ввел ли пользователь новый пароль, мы сравним хешированную часть, которая была изначально и хеш нового пароля. Если они изменились, тогда изменим хеш на новый. Результат сохраним в total и в переменной extract.

Заключение

Скорее всего, это не последняя статья по генератору ведения таблиц в SAP, да и алгоритм, представленный выше не совершенен. Но, я считаю, это отличный пример для демонстрации возможностей событий для таблиц SAP.

Комментарии

Популярные сообщения из этого блога

Прямые ссылки на файлы Google диска

В предыдущей статье я рассказал, как подключить свой JavaScript файл к блогу BLOGSPOT . Но для того, что бы их подключить нужны прямые ссылки на файл, а Google диск при предоставлении общего доступа к файлу выдает ссылку на предварительный просмотр, которая никак напрямую не ссылается на файл. Для Google диска прямая ссылка на файл - это ссылка на скачивание. Ниже описаны два способа создания ссылки на скачивание на примере файла prism.js.

OOP ALV GRID с HTML шапкой

В этой статье хочу постараться подробно описать и привести пример, как можно создать ALV отчет с таблицей на весь экран и с HTML шапкой вверху. Я не буду описывать начальный этап, где пишется селекционный экран или делается выборка данных. Будем считать, что основа у нас есть и нам нужно просто вывести данные. Главной изюминкой является то, что нужно вывести ALV GRID на экран без использования каких-либо дополнительных элементов на экране. Step-By-Step Шаг 1. Создание окна Создаем самое простое окно с номером 100. На него не нужно кидать никаких контейнеров. Оно нам нужно только для модулей PAI и PBO и вывода на него ALV GRID.