При настройке синхронизации данных между конфигурациями 1С часто возникает задача: выгрузить документ только один раз (при его создании) и игнорировать любые последующие изменения. Типичный пример — перенос документов Реализация товаров и услуг из «1С:Комплексная автоматизация 2.4» (КА) в «1С:Бухгалтерия предприятия 3.0» (БП). Бухгалтеры часто требуют, чтобы после первичной загрузки менеджеры в КА не могли случайно изменить уже проведенные и согласованные документы в БП.
В этой статье мы подробно рассмотрим, как устроен механизм регистрации изменений в современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) и разберем три практических сценария реализации этой задачи без снятия конфигурации с поддержки.
Прежде чем переходить к коду, давайте разберем логику работы платформы. Регистрация объектов для обмена происходит не в момент самой выгрузки (сеанса связи), а непосредственно в момент модификации данных — при записи или проведении документа пользователем.
В современных конфигурациях 1С свойство авторегистрации в планах обмена для большинства документов обычно установлено в значение «Запретить». Это сделано для того, чтобы разработчики могли гибко управлять процессом регистрации программно. Вместо платформенного механизма используются подписки на события (например, подписка ПередЗаписьюДокументаДляОбмена или аналогичные), которые обращаются к специальным общим модулям БСП и анализируют Правила регистрации объектов (ПРО).
Рассмотрим три способа решения нашей задачи, начиная от самого простого программного метода и заканчивая настройкой правил обмена.
---
В Библиотеке стандартных подсистем заложен штатный и очень элегантный механизм, позволяющий временно или постоянно отключать регистрацию изменений для конкретного объекта при его записи. Для этого используется коллекция ДополнительныеСвойства, которая есть у каждого ссылочного объекта в 1С.
Для реализации этого метода нам не нужно изменять типовую конфигурацию — достаточно использовать механизм расширений. Мы перехватим событие записи документа и, если документ изменяется (то есть он не новый), передадим БСП команду проигнорировать регистрацию.
Пошаговый алгоритм реализации:
РеализацияТоваровУслуг.ПередЗаписью в модуле объекта документа через аннотацию &Перед). Назовем нашу подписку БлокировкаРегистрацииИзмененийПередЗаписью.ДокументОбъект.РеализацияТоваровУслуг, событие — ПередЗаписью.
Процедура БлокировкаРегистрацииИзмененийПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Проверяем, что документ записывается не в режиме загрузки данных
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Если документ не новый (т.е. он изменяется, перепроводится или редактируется реквизит),
// даем БСП команду полностью проигнорировать регистрацию этого изменения на планах обмена
Если Не Источник.ЭтоНовый() Тогда
Источник.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов", Истина);
КонецЕсли;
КонецПроцедуры
Почему это работает? При обработке подписок на события БСП проверяет наличие ключа ОтключитьМеханизмРегистрацииОбъектов в дополнительных свойствах объекта. Если этот ключ равен Истина, система просто пропускает шаг регистрации данного документа на всех узлах обмена. Конфигурация при этом остается на полной поддержке, а решение работает максимально быстро и надежно.
---
Если по каким-то причинам вы не можете или не хотите использовать расширения конфигурации (например, политика безопасности запрещает использование стороннего кода), задачу можно решить на уровне настройки Правил регистрации объектов (ПРО).
Эти правила создаются и редактируются в специализированной конфигурации «Конвертация данных 2.1» (даже если сам обмен между КА и БП настроен по технологии КД 3.0 через формат EnterpriseData, правила регистрации все равно используют XML-формат КД 2.1).
Разберем этот процесс по шагам:
РеализацияТоваровУслуг.Важный нюанс: В момент выполнения правил регистрации документ уже физически записан в базу данных. Это значит, что стандартный метод ЭтоНовый() всегда будет возвращать значение Ложь. Как же определить, был ли документ уже выгружен ранее?
Рассмотрим два профессиональных подхода к решению этой проблемы внутри правил регистрации:
Если бизнес-процесс предполагает, что документы выгружаются в день их создания, а любые изменения происходят позже, мы можем блокировать регистрацию документов, дата которых значительно отличается от текущей даты. В обработчике «Перед регистрацией объекта» пишем:
// Разрешаем регистрацию только в том случае, если документ создан сегодня или вчера
Если Объект.Дата < (ТекущаяДата() - 86400 * 2) Тогда
Отказ = Истина;
КонецЕсли;
Минус метода: Если старый документ действительно нужно будет перевыгрузить в первый раз (например, восстанавливают учет за прошлый месяц), этот код заблокирует его выгрузку.
Чтобы точно знать, выгружался ли документ ранее, мы можем фиксировать факт успешной выгрузки. Для этого реализуем следующую схему:
ИсторияВыгрузкиОбъектов с одним измерением Объект (тип: ДокументСсылка.РеализацияТоваровУслуг).
// Фиксируем факт успешной выгрузки
МенеджерЗаписи = РегистрыСведений.ИсторияВыгрузкиОбъектов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Источник.Ссылка;
МенеджерЗаписи.Записать(Истина);
// Делаем запрос к нашему регистру истории
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Первые 1
| История.Объект КАК Объект
|ИЗ
| РегистрСведений.ИсторияВыгрузкиОбъектов КАК История
|ГДЕ
| История.Объект = &Объект";
Запрос.УстановитьПараметр("Объект", Объект.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Документ уже выгружался ранее, отменяем повторную регистрацию изменения
Отказ = Истина;
КонецЕсли;
После внесения изменений выгрузите правила регистрации из «Конвертации данных» в XML и загрузите их обратно в настройку синхронизации в КА 2.4 через пользовательский интерфейс.
---
Часто возникает ситуация, когда повторная регистрация документов происходит лавинообразно — например, при закрытии месяца, групповом перепроведении или пакетном изменении реквизитов (скажем, обработкой поменяли ставку НДС или ответственного менеджера). Если вам нужно разово провести старые документы «тихо», чтобы они не полетели повторно в БП, используйте свойство платформы ОбменДанными.Загрузка.
Перед программной записью или проведением документов в обработке установите это свойство:
ДокументОбъект = ВыбраннаяСсылка.ПолучитьОбъект();
// Устанавливаем признак "Загрузка"
ДокументОбъект.ОбменДанными.Загрузка = Истина;
// Записываем документ в режиме проведения
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Важно понимать: При установке свойства ОбменДанными.Загрузка = Истина платформа 1С автоматически отключает обработку всех подписок на события, транзакционные триггеры и авторегистрацию изменений на узлах всех планов обмена. Документ запишется абсолютно «молча» и гарантированно не попадет в очередь выгрузки.
Предостережение: Будьте осторожны с этим признаком, так как при его использовании отключаются также и прикладные проверки (например, проверка остатков на складах или заполнение связанных регистров), заложенные разработчиками в процедуру ПередЗаписью или ОбработкаПроведения.
---
Проанализировав все варианты, сделаем выводы:
ДополнительныеСвойства. Это наиболее лаконичный, быстрый и современный подход, использующий штатные возможности БСП.