Как построить отчет по истории изменений записей в регистре сведений 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов в 1С нередко возникает задача показать динамику изменения показателей: вывести список записей периодического регистра сведений и наглядно отобразить, какие именно значения ресурсов изменились по сравнению с предыдущей записью. Разберем особенности устройства регистров сведений, проанализируем типовые ограничения и рассмотрим практические способы решения этой задачи с помощью запросов, СКД и платформенных механизмов версионирования.

Особенности структуры регистра сведений

Перед тем как строить алгоритм сравнения, важно учитывать технические особенности хранения данных в 1С:

  1. Ключ записи: в периодическом регистре сведений уникальность строки определяется совокупностью всех измерений и поля Период. Две записи с абсолютно одинаковым набором измерений могут существовать в базе только тогда, когда у них различаются даты.
  2. Хронология срезов vs Аудит изменений: периодический регистр хранит историю состояний на временной шкале. Если пользователь вносит запись новой датой, мы видим срез. Но если пользователь перезаписывает или удаляет уже существующую запись на ту же дату, старое значение в регистре безвозвратно заменяется. Для отслеживания таких действий требуются отдельные механизмы аудита.
  3. Сравнение данных: чтобы выявить факт изменения, необходимо сопоставить текущую запись с непосредственно предшествующей записью по тому же набору измерений. Простое соединение таблицы самой с собой по условию «не равно» приведет к декартову произведению строк.

Способ 1. Реализация через запрос: определение предыдущей даты

Рассмотрим классический и надежный алгоритм на языке запросов 1С. Чтобы избежать избыточного размножения записей, разобьем задачу на последовательные шаги:

  1. Получаем срез данных с необходимыми отборами во временную таблицу.
  2. Соединяем таблицу саму с собой левым соединением по ключевым измерениям и условию Период1 > Период2, вычисляя функцию МАКСИМУМ(Период2). Это позволяет найти дату строго предыдущей записи для каждого набора измерений.
  3. Повторно соединяем полученный результат с регистром для выборки старых значений ресурсов.
  4. Сравниваем ресурсы и отсекаем строки, где значения не изменились.

Посмотрим на пример текста запроса для периодического регистра сведений:


ВЫБРАТЬ
    Регистр.Период КАК Период,
    Регистр.Номенклатура КАК Номенклатура,
    Регистр.Цена КАК Цена
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Регистр
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТекДанные.Период КАК Период,
    ТекДанные.Номенклатура КАК Номенклатура,
    ТекДанные.Цена КАК Цена,
    МАКСИМУМ(ПредДанные.Период) КАК ПредыдущийПериод
ПОМЕСТИТЬ ВТ_СвязиПериодов
ИЗ
    ВТ_ИсходныеДанные КАК ТекДанные
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК ПредДанные
        ПО ТекДанные.Номенклатура = ПредДанные.Номенклатура
        И ТекДанные.Период > ПредДанные.Период
СГРУППИРОВАТЬ ПО
    ТекДанные.Период,
    ТекДанные.Номенклатура,
    ТекДанные.Цена
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Связи.Номенклатура КАК Номенклатура,
    Связи.Период КАК ДатаИзменения,
    Связи.Цена КАК НоваяЦена,
    ЕСТЬNULL(ПредРегистр.Цена, 0) КАК СтараяЦена
ИЗ
    ВТ_СвязиПериодов КАК Связи
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ПредРегистр
        ПО Связи.Номенклатура = ПредРегистр.Номенклатура
        И Связи.ПредыдущийПериод = ПредРегистр.Период
ГДЕ
    НЕ (Связи.Цена = ЕСТЬNULL(ПредРегистр.Цена, 0))

Проанализируем этот запрос: мы корректно сопоставили строки без риска зацикливания или дублирования строк, а в секции ГДЕ отфильтровали только те записи, по которым произошло реальное изменение ресурса Цена.

Способ 2. Использование функций системы компоновки данных (СКД)

Если отчет разрабатывается полностью на СКД, можно избежать тяжелых соединений в запросе, которые создают нагрузку на СУБД при больших объемах данных. Платформа 1С предоставляет мощный встроенный язык выражений компоновки данных.

Разберем порядок настройки отчета:

  1. В наборе данных формируем простой плоский запрос, выбирающий Период, измерения и ресурсы регистра, отсортированные по хронологии.
  2. Переходим на вкладку Вычисляемые поля схемы компоновки данных. Создаем поле ПредыдущееЗначение.
  3. В выражении вычисляемого поля используем специализированную функцию СКД:

ВычислитьВыражение("Цена", "Период", "Предыдущая")

Эта функция обращается к значению ресурса Цена из предыдущей строки текущей группировки. Далее в настройках структуры отчета (во вкладке Отбор группировки строк) достаточно наложить условие: поле Цена не равно вычисляемому полю ПредыдущееЗначение. В результате в итоговый отчет попадут только строки с зафиксированными изменениями.

Способ 3. Аудит изменений и механизм «История данных»

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

Для организации полноценного аудита применяются системные механизмы платформы 1С:

  1. Механизм «История данных»: в свойствах метаданных регистра сведений свойство История данных переводится в значение Использовать. Платформа начинает автоматически логировать каждую транзакцию изменения, сохраняя версионность данных, автора правки и момент времени в служебных таблицах. Для чтения этих данных используются специальные методы менеджера истории данных и виртуальные таблицы.
  2. Подписка на событие ПередЗаписью: для прикладного контроля изменений набора записей можно создать подписку на событие регистра сведений. В обработчике считывается текущее состояние набора из базы данных с помощью нового экземпляра РегистрСведенийНаборЗаписей, после чего прочитанные строки построчно сравниваются со строками записываемого набора. Различия программно фиксируются в специальный журнал аудита.

Таким образом, для анализа хронологии периодических записей оптимально использовать алгоритм запроса со связью по предыдущей дате либо функции языка выражений СКД, а для контроля перезаписи и действий пользователей — встроенный механизм истории данных платформы.

← На главную