При разработке отчетов в 1С нередко возникает задача показать динамику изменения показателей: вывести список записей периодического регистра сведений и наглядно отобразить, какие именно значения ресурсов изменились по сравнению с предыдущей записью. Разберем особенности устройства регистров сведений, проанализируем типовые ограничения и рассмотрим практические способы решения этой задачи с помощью запросов, СКД и платформенных механизмов версионирования.
Перед тем как строить алгоритм сравнения, важно учитывать технические особенности хранения данных в 1С:
Период. Две записи с абсолютно одинаковым набором измерений могут существовать в базе только тогда, когда у них различаются даты.Рассмотрим классический и надежный алгоритм на языке запросов 1С. Чтобы избежать избыточного размножения записей, разобьем задачу на последовательные шаги:
Период1 > Период2, вычисляя функцию МАКСИМУМ(Период2). Это позволяет найти дату строго предыдущей записи для каждого набора измерений.Посмотрим на пример текста запроса для периодического регистра сведений:
ВЫБРАТЬ
Регистр.Период КАК Период,
Регистр.Номенклатура КАК Номенклатура,
Регистр.Цена КАК Цена
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Регистр
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТекДанные.Период КАК Период,
ТекДанные.Номенклатура КАК Номенклатура,
ТекДанные.Цена КАК Цена,
МАКСИМУМ(ПредДанные.Период) КАК ПредыдущийПериод
ПОМЕСТИТЬ ВТ_СвязиПериодов
ИЗ
ВТ_ИсходныеДанные КАК ТекДанные
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК ПредДанные
ПО ТекДанные.Номенклатура = ПредДанные.Номенклатура
И ТекДанные.Период > ПредДанные.Период
СГРУППИРОВАТЬ ПО
ТекДанные.Период,
ТекДанные.Номенклатура,
ТекДанные.Цена
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Связи.Номенклатура КАК Номенклатура,
Связи.Период КАК ДатаИзменения,
Связи.Цена КАК НоваяЦена,
ЕСТЬNULL(ПредРегистр.Цена, 0) КАК СтараяЦена
ИЗ
ВТ_СвязиПериодов КАК Связи
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ПредРегистр
ПО Связи.Номенклатура = ПредРегистр.Номенклатура
И Связи.ПредыдущийПериод = ПредРегистр.Период
ГДЕ
НЕ (Связи.Цена = ЕСТЬNULL(ПредРегистр.Цена, 0))
Проанализируем этот запрос: мы корректно сопоставили строки без риска зацикливания или дублирования строк, а в секции ГДЕ отфильтровали только те записи, по которым произошло реальное изменение ресурса Цена.
Если отчет разрабатывается полностью на СКД, можно избежать тяжелых соединений в запросе, которые создают нагрузку на СУБД при больших объемах данных. Платформа 1С предоставляет мощный встроенный язык выражений компоновки данных.
Разберем порядок настройки отчета:
Период, измерения и ресурсы регистра, отсортированные по хронологии.ПредыдущееЗначение.
ВычислитьВыражение("Цена", "Период", "Предыдущая")
Эта функция обращается к значению ресурса Цена из предыдущей строки текущей группировки. Далее в настройках структуры отчета (во вкладке Отбор группировки строк) достаточно наложить условие: поле Цена не равно вычисляемому полю ПредыдущееЗначение. В результате в итоговый отчет попадут только строки с зафиксированными изменениями.
Если задача заключается не просто в просмотре срезов периодического регистра, а в контроле действий пользователей (кто изменил запись, когда она была перезаписана или удалена), стандартных запросов к периодическому регистру недостаточно. Выясним причину: при перезаписи набора записей с теми же ключевыми полями старые значения стираются из базы.
Для организации полноценного аудита применяются системные механизмы платформы 1С:
История данных переводится в значение Использовать. Платформа начинает автоматически логировать каждую транзакцию изменения, сохраняя версионность данных, автора правки и момент времени в служебных таблицах. Для чтения этих данных используются специальные методы менеджера истории данных и виртуальные таблицы.ПередЗаписью: для прикладного контроля изменений набора записей можно создать подписку на событие регистра сведений. В обработчике считывается текущее состояние набора из базы данных с помощью нового экземпляра РегистрСведенийНаборЗаписей, после чего прочитанные строки построчно сравниваются со строками записываемого набора. Различия программно фиксируются в специальный журнал аудита.Таким образом, для анализа хронологии периодических записей оптимально использовать алгоритм запроса со связью по предыдущей дате либо функции языка выражений СКД, а для контроля перезаписи и действий пользователей — встроенный механизм истории данных платформы.