Версионирование новых объектов в 1С: от настройки до своего механизма хранения версий
Содержание
Версионирование в 1С хранит снимки объекта на каждую запись: кто, когда и что изменил. В типовых конфигурациях на БСП подключается без кода — в Администрирование → Общие настройки → Версионирование объектов. Для собственных объектов, которых в настройках нет, механизм добавляется двумя путями: зарегистрировать объект во встроенной подсистеме версионирования либо написать своё хранилище версий на регистре сведений и подписках на события.
Ниже — оба способа с рабочим примером, настройка хранения и очистки, восстановление из версии и ошибки, на которых чаще всего спотыкаются при внедрении. Версия платформы — 8.3 с интерфейсом «Такси».
Что даёт история версий и когда она действительно нужна
Версия — это сериализованный снимок состояния объекта в момент записи. По нему видно прежние значения реквизитов, состав табличных частей, автора и дату. Три типичные задачи, ради которых версионирование включают:
- 🔍 Разбор спорных правок. Документ перепровели задним числом, суммы «поехали» — история показывает, кто и когда поменял реквизит.
- ↩️ Откат ошибочного изменения. Не весь документ, а конкретное значение можно вернуть из прошлой версии.
- 📋 Аудит и регламент. Для чувствительных справочников (контрагенты, договоры, банковские реквизиты) история правок — часть внутреннего контроля.
Версионирование не заменяет резервную копию и не журналирует удаление объекта целиком — оно про изменения существующих данных. Если нужен учёт именно факта доступа или удаления, это журнал регистрации, а не версии.
Включать версии «на всё подряд» не стоит. Снимок пишется на каждую запись, и на активно изменяемых объектах база быстро распухает. Выбирайте объекты, где история правок реально нужна.
Встроенный механизм версионирования в типовых конфигурациях
В конфигурациях на Библиотеке стандартных подсистем (БП 3.0, ЗУП 3.1, УТ 11, КА, ERP) подсистема версионирования уже есть. Открывается в Администрирование → Общие настройки → Версионирование объектов. В таблице перечислены объекты метаданных, для каждого задаётся вариант:
| Вариант | Когда пишется версия | Для чего |
|---|---|---|
| Не версионировать | никогда | объект без истории |
| Версионировать при записи | при любой записи | справочники, договоры |
| Версионировать при проведении | только при проведении | документы с движениями |
Для просмотра истории в форме или списке объекта есть команда истории изменений — она открывает список версий с автором и датой и позволяет сравнить две версии между собой.
Ограничение, о котором часто забывают: в списке настроек видны только те объекты, которые уже «известны» подсистеме. Собственный справочник или документ, добавленный в расширении или в доработанной конфигурации, в этом списке не появится сам — его нужно зарегистрировать в механизме. Как это сделать — в следующем разделе.
Версии БСП хранит в служебном регистре сведений: само состояние объекта пишется в ресурс типа ХранилищеЗначения, рядом — автор, дата, номер версии. Это важно для оценки объёма: одна версия крупного документа с большой табличной частью весит прилично, а версий на один объект может накопиться десятки.
Как подключить версионирование к своему объекту
Задача формулируется так: новый справочник или документ (ваш, из расширения или доработки) должен попасть в механизм версий. Порядок действий для варианта на БСП:
- Откройте переопределяемый модуль подсистемы версионирования (в типовых это общий модуль с суффиксом
Переопределяемый, отвечающий за версионирование). - В процедуре, формирующей список версионируемых объектов, добавьте свой объект метаданных в состав настроек — по аналогии со строками, которые там уже есть для типовых объектов.
- Пересоберите конфигурацию, зайдите в
Администрирование → Общие настройки → Версионирование объектов— ваш объект появится в таблице. Задайте ему вариант «при записи» или «при проведении».
Этот путь хорош тем, что переиспользует готовое: форму сравнения версий, хранилище, регламентную очистку. Минус — он завязан на конкретную версию БСП, и при обновлении библиотеки правки переопределяемого модуля нужно переносить.
Перед тем как включать механизм на рабочей базе, пройдитесь по короткому списку — это снимает большинство проблем, которые иначе вылезут через месяцы:
Правки в переопределяемых модулях типовой конфигурации снимают её с полной поддержки на уровне этих модулей. Если конфигурация должна оставаться типовой, разумнее вынести регистрацию в расширение — многие переопределяемые процедуры БСП доступны для переопределения через механизм расширений.
Свой механизм версий: регистр сведений и подписка на событие
Когда БСП в конфигурации нет (самописная база) или встроенный механизм не подходит, версионирование собирается из трёх частей: регистр-хранилище, подписка на событие записи и процедура, которая строит снимок. Такой механизм ни от чего не зависит и переносится между базами.
Шаг 1. Регистр сведений для хранения версий
Создайте независимый регистр сведений
, например ВерсииОбъектов:
- измерение
Объект— типСправочникСсылка(или составной тип ссылок тех объектов, что версионируете); - измерение
НомерВерсии— число; - ресурс
ДанныеВерсии— типХранилищеЗначения; - реквизиты
ДатаИзменения(дата),Автор(СправочникСсылка.Пользователи).
Периодичность — непериодический, так проще управлять номерами версий вручную.
Шаг 2. Подписка на событие записи
Добавьте объект ПодпискаНаСобытия: источник — ваш справочник (или несколько объектов), событие — ПередЗаписью, обработчик — процедура в серверном общем модуле. Снимок удобнее строить до записи: так в обработчик приходит объект уже с новыми значениями, но запись в регистр лучше выполнять после успешной записи самого объекта, чтобы не плодить версии при отказе.
Шаг 3. Процедура, которая строит снимок
Снимок надёжнее собирать не сериализацией объекта целиком, а в структуру из значений реквизитов и табличных частей — такая структура гарантированно кладётся в ХранилищеЗначения:
Процедура ПриЗаписиОбъекта(Источник) Экспорт
Снимок = Новый Структура;
// Реквизиты шапки
Реквизиты = Новый Структура;
Для Каждого Реквизит Из Источник.Метаданные().Реквизиты Цикл
Реквизиты.Вставить(Реквизит.Имя, Источник[Реквизит.Имя]);
КонецЦикла;
Снимок.Вставить("Реквизиты", Реквизиты);
// Табличные части
ТабЧасти = Новый Структура;
Для Каждого ТЧ Из Источник.Метаданные().ТабличныеЧасти Цикл
ТабЧасти.Вставить(ТЧ.Имя, Источник[ТЧ.Имя].Выгрузить());
КонецЦикла;
Снимок.Вставить("ТабличныеЧасти", ТабЧасти);
НомерВерсии = СледующийНомерВерсии(Источник.Ссылка);
Запись = РегистрыСведений.ВерсииОбъектов.СоздатьМенеджерЗаписи();
Запись.Объект = Источник.Ссылка;
Запись.НомерВерсии = НомерВерсии;
Запись.ДатаИзменения = ТекущаяДатаСеанса();
Запись.Автор = ПользователиСсылка(); // ваш способ получить текущего пользователя
Запись.ДанныеВерсии = Новый ХранилищеЗначения(Снимок, Новый СжатиеДанных(9));
Запись.Записать();
КонецПроцедуры
Отдельная функция СледующийНомерВерсии выбирает максимальный номер по объекту из регистра и прибавляет единицу. СжатиеДанных(9) заметно уменьшает размер хранилища — для текстовых реквизитов и табличных частей сжатие даёт кратную экономию.
Для ЗначениеВСтрокуВнутр и аналогичных «быстрых» способов сериализации есть ограничения по совместимости между релизами. Структура из примитивов и ссылок, упакованная в ХранилищеЗначения, читается стабильнее.
Чтобы база не распухла: хранение и регламентная очистка версий
Главный риск версионирования — неконтролируемый рост таблицы версий. Снимок большого документа при каждом перепроведении — десятки килобайт, умножьте на поток документов за год. Что помогает:
- Версионировать точечно. Включайте историю только для объектов, где она нужна, а не для всех документов подряд.
- «При проведении», а не «при записи» для документов — иначе версия пишется на каждое открытие-сохранение без изменения движений.
- Сжимать хранилище через второй параметр
ХранилищеЗначения(как в примере выше). - Ограничить срок хранения. В БСП для этого есть регламентное задание очистки устаревших версий — задайте, сколько версий или за какой период хранить. В своём механизме добавьте аналогичное регламентное задание, которое удаляет из регистра версии старше заданного срока, оставляя последние N.
Очистку версий лучше ставить на ночь или в окно низкой нагрузки: массовое удаление из регистра сведений создаёт блокировки и нагружает журнал транзакций SQL.
Если версий уже накопилось много и база тяжёлая — сначала настройте очистку и дайте ей отработать, и только потом при необходимости делайте реструктуризацию, чтобы освободить место на уровне СУБД.
Восстановление версий и применение истории в работе
Снимок бесполезен, если из него нельзя вернуть данные. Логика восстановления для своего механизма:
- Прочитайте нужную запись регистра и достаньте снимок:
Снимок = Запись.ДанныеВерсии.Получить(). - Получите объект:
Объект = Ссылка.ПолучитьОбъект(). - Присвойте реквизиты из
Снимок.Реквизитыи загрузите табличные части черезОбъект.ИмяТЧ.Загрузить(...). - Запишите объект.
Перед массовым восстановлением версий в рабочей базе сделайте резервную копию: откат объекта затирает текущие значения, и если в снимке была ошибка, вы распространите её дальше. В БСП восстановление удобнее — форма сравнения версий показывает отличия построчно и позволяет вернуться к выбранной версии через команду в самой форме истории.
Частый сценарий: нужно не вернуть весь объект, а посмотреть одно прежнее значение (например, какой был договор у контрагента полгода назад). Для этого объект восстанавливать не нужно — достаточно открыть снимок и прочитать поле из структуры реквизитов.
История версий встраивается и в бизнес-процессы, а не только в разбор инцидентов. Несколько практичных связок:
- 🧾 Согласование изменений. Автор версии и дата из записи регистра подшиваются к задаче согласования: видно, какую именно правку утверждают и кто её внёс.
- 🔔 Уведомления об изменении чувствительных данных. В ту же подписку на запись добавляется проверка: поменялись банковские реквизиты контрагента или условия договора — ответственному уходит оповещение со ссылкой на сравнение версий.
- 📊 Периодический аудит. Регламентное задание раз в период выбирает из регистра все версии по контрольным объектам и формирует сводку правок для ответственного за внутренний контроль.
Такие сценарии не требуют отдельного механизма — они переиспользуют уже собранное хранилище версий, добавляя к нему реакцию (задачу, письмо, отчёт). Это и есть главный аргумент в пользу версионирования: один раз собранная история закрывает и аудит, и откат, и согласование.
Альтернативы: расширения конфигурации и внешние решения
Если лезть в типовую конфигурацию
нельзя, версионирование своих объектов реализуют в расширении конфигурации (доступны с платформы 8.3.6). В расширение выносят и регистр версий, и подписку на событие, и обработчик — типовая конфигурация остаётся нетронутой и обновляется штатно. Загрузка расширения (.cfe) и обновление конфигурации
базы данных — два отдельных шага, не забывайте про второй.
Когда речь не о данных, а об истории изменений самой конфигурации (код, формы, метаданные) — это зона хранилища конфигурации: оно версионирует разработку, а не прикладные данные, и путать эти две задачи не нужно.
Для сквозного аудита по нескольким базам используют внешние системы сбора истории, которые читают регистр версий или журнал регистрации. Но для одной базы это избыточно — встроенного механизма или своего регистра достаточно.
Типичные ошибки при внедрении
Эти промахи всплывают уже в работающей базе, когда переделывать дороже:
- ❌ Версионирование всех документов «при записи». Версия пишется даже без изменения данных — таблица растёт в разы быстрее, чем ожидали. Для документов почти всегда нужен режим «при проведении».
- ❌ Нет очистки. Механизм включили, про срок хранения забыли — через год база тяжелее на несколько гигабайт только от версий.
- ❌ Сериализация объекта целиком несовместимым способом. После обновления платформы или конфигурации старые снимки перестают читаться. Снимок в виде структуры примитивов надёжнее.
- ❌ Правки в переопределяемом модуле типовой без расширения. Конфигурация слетает с поддержки, при обновлении правки затираются.
- ❌ Восстановление версии прямо в рабочей базе без копии. Откат затирает текущие данные — если в снимке была ошибка, вернёте её обратно.
Частые вопросы
Можно ли версионировать регистры сведений и накопления?
Версии занимают место в основной базе или отдельно?
ХранилищеЗначения). Отдельного файла нет — поэтому так важны сжатие и регламентная очистка.Увидит ли версионирование изменения, сделанные обработкой через `ОбъектБД.Записать()`?
ПередЗаписью и встроенный механизм срабатывают на любую запись объекта из кода, включая обработки и обмены. Это и плюс (полнота истории), и риск (массовые загрузки плодят версии).