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