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