В процессе разработки на платформе 1С часто возникает задача не просто фиксировать текущее состояние данных, но и хранить историю всех изменений, которые вносил пользователь в документ. Стандартное поведение системы при использовании подчиненных регистров сведений может сбивать с толку начинающих разработчиков. Разберем по шагам, почему записи затираются, и как реализовать полноценное логирование изменений несколькими способами.
Проанализируем ситуацию: у нас есть периодический регистр сведений ВыдачаВАренду, который подчинен регистратору (нашему документу). В процедуре ОбработкаПроведения написан стандартный код для записи движений:
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ВыдачаВАренду.Записывать = Истина;
Движение = Движения.ВыдачаВАренду.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = Номенклатура;
Движение.Количество = Количество;
КонецПроцедуры
Когда мы проводим документ в первый раз, в регистре появляется запись. Однако, если мы изменим номенклатуру в документе и проведем его снова, старая запись исчезнет, а на ее месте появится новая. Выясним причину такого поведения. Техническая особенность платформы 1С заключается в том, что при перепроведении документа система сначала полностью очищает все записи в подчиненных регистрах по данному регистратору, а затем записывает новые наборы данных. То же самое происходит и при отмене проведения — записи просто удаляются. Именно поэтому подчиненный регистр всегда отражает только актуальный срез данных последнего проведения и не может служить инструментом для отслеживания истории «как было до этого».
Чтобы обойти автоматическую очистку движений, мы можем перевести регистр в режим «Независимый» (снять галочку «Подчинен регистратору»). В этом случае мы берем управление записью в свои руки. Посмотрим, как изменить программный код в модуле документа, чтобы при каждом проведении в регистр добавлялась новая запись, а старые сохранялись.
Рассмотрим пример реализации через МенеджерЗаписи:
Процедура ОбработкаПроведения(Отказ, Режим)
МенеджерЗаписи = РегистрыСведений.ВыдачаВАренду.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата(); // Важно использовать точное время
МенеджерЗаписи.Номенклатура = Номенклатура;
МенеджерЗаписи.Количество = Количество;
// Добавим ссылку на документ в измерения, чтобы знать, кто автор изменений
МенеджерЗаписи.ДокументОснование = Ссылка;
МенеджерЗаписи.Записать();
КонецПроцедуры
Важный нюанс: Чтобы в регистре сохранялись разные записи по одному и тому же документу, они должны различаться по ключевым полям (измерениям) или по периоду. Если вы проводите документ дважды в течение одной секунды, и у регистра периодичность «В пределах секунды», то вторая запись все равно заместит первую. Чтобы этого избежать, рекомендуется добавить в измерения регистра уникальный идентификатор или номер версии (например, числовой реквизит НомерВерсии), который будет увеличиваться при каждом изменении.
Начиная с версии платформы 8.3.11, разработчикам доступен встроенный механизм, который делает всю работу по логированию автоматически. Рассмотрим, как его включить:
Этот метод гораздо эффективнее «самописных» регистров по нескольким причинам:
Если вы работаете в типовой конфигурации (например, 1С:ERP, УТ 11 или БП 3.0), там уже интегрирована Библиотека стандартных подсистем (БСП). Подсистема «Версионирование объектов» — это «золотой стандарт» для бизнес-приложений.
Проанализируем, как она работает. Вместо создания отдельных записей для каждого поля, БСП делает XML-слепок всего объекта и сохраняет его в регистр сведений ВерсииОбъектов. Для включения этой функции не нужно писать код — достаточно зайти в пользовательский режим (Администрирование — Общие настройки — История изменений) и выбрать нужные документы для версионирования (например, «Версионировать при проведении»).
Выясним, какой метод выбрать для вашей задачи:
Записать() и управлении уникальностью записей.Помните, что избыточное хранение истории может привести к быстрому росту базы данных. Поэтому всегда анализируйте, для каких именно объектов история действительно необходима, и настраивайте регламентные задания по очистке устаревших версий (например, хранение только за последний год).