Включение истории изменений в собственных документах

Есть два основных направления отслеживания истории изменения какого-либо объекта.

1. Историчность данных

В этом случае мы принимаем за основу, что нам интересно знать состояние объекта на любую дату: год назад, месяц назад, вчера, сегодня. И знание такой информации важно для осуществления бизнес-операций.

Реализуется в БД посредством включения даты в ключ таблицы (BEGDA/ENDDA) и написания многих строк на ABAP, разруливания этого добра на экранах.

При этом предполагается, что пользователь может управлять диапазонами актуальности данных.

Управление кадрами практически полностью использует этот подход, там всё зависит от даты (имя, должность, организационное присвоение, документы).

2. Журналирование изменений

В этом случае мы принимаем за основу, что нас интересует только текущее состояние объекта, но мы хотим “на всякий случай” иметь историю изменения.

История такая нужна в первую очередь для контроля за действиями пользователя. Как правило, её используют только в качестве улик, при разборе проблем. Информация о предыдущем состоянии объекта не может использоваться в бизнес-операциях.

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

Самый базовый подход предполагает использование четырёх дополнительных полей: (ERNAM, ERDAT, AENAM, AEDAT). Дело совсем нехитрое. Однако нас может заинтересовать и характер вносимых изменений (список всех изменений, включая предыдущие значение полей.

Именно такой подход используется практически во всех основных данных ERP (ОС, Счёт, Дебитор, Кредитор), поэтому есть какой-то стандартный механизм в SAP, который используется везде, где это необходимо.

И именно о нём пойдёт речь под катом.

Основные таблицы с документами изменений

Есть две основных таблицы, в которых откладывается история изменений для всех объектов:

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

 

Исходная таблица с основными данными

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

И всё что вы хотите – это быстро и просто прикрутить отслеживание изменений.

В моём случае таблица называется ZPM_OPER – регистрация операций. Добавлять колонки нам дополнительно не надо, но надо убедиться в том, чтобы у нас элементы данных ко всем колонкам были правильными.

Документ изменений в домене

Для полей, которые мы хотим отслеживать, этот флаг должен быть включён, а для остальных – выключен.

Создание объекта документа изменений

Заходим в транзакцию SCDO, и создаём там объект. В качестве имени вполне подойдёт имя таблицы:

Объект документа изменений

Если включить флаг “Перенос как внутренней таблицы”, то в сгенерированном ФМ в качестве основного параметра будет таблица, а иначе – просто структура.

Особой разницы может быть и нет, но если вы сохраняете много позиционный документ, то разумнее сразу все позиции, чем дёргать этот ФМ в цикле. И наоборот, если у вас обрабатывается однострочная карточка какого-то объекта, то таблица вам не нужна и структуры вам достаточно.

Но вот галочку эту легко поставить и сгенерировать ФМ заново, а вот переписать его вызов – будет задачкой посложнее, так что будьте предусмотрительны.

К этому объекту надо сгенерировать программы:

Генерация программы

Если вы вдруг выберете флаг “Особая обработка текстов”, то в интерфейс ФМ будут добавлены дополнительные параметры по текстам, зависимым от языка. Но на практике основные данные не имеют текстов, зависимых от языка (а именно для них создаются документы изменений). Как правило, зависимостью от языка обладают только справочники (а для них изменения отслеживаются другими механизмами).

Чтоб не путаться, я предварительно создал отдельную группу функций по имени таблицы с префиксом ZCD (Change Document).

Самое главное что нам тут потом понадобится: сгенерированная функция ZPM_OPER_WRITE_DOCUMENT.

Включение записи изменений

Находим место в тексте программы, когда запись в БД наших данных уже гарантированно проходит и включаем туда вызов сгенерированной функции:

data: lv_objectid type cdhdr-objectid.
lv_objectid = ls_zpm_oper-eqopr.
call function ‘ZPM_OPER_WRITE_DOCUMENT’
exporting
        objectid     = lv_objectid
        tcode        = sy-tcode
        utime        = sy-uzeit
        udate        = sy-datum
        username     = sy-uname
        n_zpm_oper   = ls_zpm_oper      "New record
        o_zpm_oper   = ls_zpm_oper_bak  "Old record
        upd_zpm_oper = ‘U’.

 

ID объекта – это наш ключ к объекту (ключ таблицы). Если у вас в таблице несколько ключевых полей, то придётся их склеить в одно поле.

Во входных параметрах две строки-структуры: до изменений и после них. По-хорошему, у вас они и так должны быть, хотя бы в целях проверки необходимости сохранения. Значения и колонки анализируются внутри ФМ: сравниваются поля и проверяется признак в ЭД.

Пока это всё. Можно подёргать изменения и убедиться, что записи в таблице CDPOS появляются.

Написание программы для просмотра

Здесь можно пойти тремя разными путями:

А я расскажу о третьем пункте.

Набрасываем программку вокруг стандартных функциональных модулей. Вот первая версия такой программки (подсмотрено на основных средствах):

Пробуем и смотрим на результат:

Просмотр истории изменений

В целом, годная программа… Да вот как-то некрасиво показывается номер объекта, хочется перенести его из второй колонки в первую и обработать.

Сложилось ощущение, что в глубинах дёргаемых ФМ есть специальная обработка для некоторых объектов, в том числе и ANLA.

А вот как это действительно красиво подать?  Уж сильно не хочется делать параллельную реализацию со всеми красотульками…

Реализация API для красотулек

В нашей программе есть два основных недостатка:

Есть несколько настроечных таблиц, в которых мы можем сделать тюнинг:

Технология условно примитивная: по определённому интерфейсу реализуете ФМ и прописываете его в эти таблицы. В нужный момент произойдёт CALL FUNCTION этих модулей. Образцы интерфейсов можно подсмотреть на тех же основных средствах (ANLA).

И после этого действа всё выглядит поглаже:

Просмотр истории изменения 2

Включение программы в основную транзакцию

Рисуем кнопку на экране (а можно и в меню):

Кнопка истории на экране

Обрабатываем нажатие:

case sy-ucomm.
  when ‘ZCD’.
    submit ZPM_EQT_POST_CD
      with p_eqopr = zpm_oper_scr-eqopr
    and return.
endcase.

Вот и всё.

Остаётся только протестировать работу кнопки и допиливать напильником получившийся общий результат.

Опубликовано 15.05.2013 в 13:43 · Автор ivan · Ссылка
Рубрики: ABAP

2 комментария

Подписаться на комментарии по RSS

  1. Написал(-а) Аноним
    27.01.2014 в 18:09
    Ссылка

    Здравствуйте! Это только для типа изменения update или возможно следить за типом изменения insert, delete?

  2. Написал(-а) ivan
    28.01.2014 в 08:52
    Ссылка

    Как вы могли догадаться — всё приходится делать самому, то есть системный перехват команд UPDATE/DELETE/INSERT не производится.
    Если вы сгенерируете функциональный модуль и посмотрите на его интерфейс, то увидите там параметр OBJECT_CHANGE_INDICATOR, который можно установить в одно из значений (U, I, E, D).
    U — UPDATE (значение по умолчанию)
    I — вставка
    E, D — удаление поля или записи

Подписаться на комментарии по RSS

Написать комментарий