Как отменить регистрацию документа в плане обмена при его проведении, но оставить при записи

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

В процессе эксплуатации информационных систем на базе 1С, особенно таких нагруженных, как «Бухгалтерия предприятия 3.0», администраторы часто сталкиваются с проблемой избыточного обмена данными. Типичная ситуация: пользователю необходимо, чтобы документ регистрировался для обмена при его создании или ручном редактировании (сохранении), но при этом массовое перепроведение документов (например, при закрытии месяца или выполнении групповых обработок) не должно приводить к «вываливанию» тысяч неизменных объектов в очередь обмена. Рассмотрим подробно, как решить эту задачу программно.

Анализ механизма регистрации: почему документ регистрируется дважды?

Для начала разберем внутреннюю механику платформы 1С. Важно понимать, что метод Провести() не существует в вакууме — он всегда инициирует запись объекта. Таким образом, когда пользователь нажимает «Провести и закрыть», срабатывает целая цепочка событий: ПередЗаписью, ПриЗаписи, а внутри этой транзакции — логика проведения. Если в плане обмена для данного документа установлено свойство «Авторегистрация — Разрешить», платформа регистрирует изменения автоматически в момент фиксации транзакции записи.

Проблема, озвученная в обсуждении, заключается в том, что стандартная попытка удалить регистрацию в событии ПриПроведении часто оказывается неэффективной или запоздалой. Выясним причину: событие ПриПроведении срабатывает уже после того, как основные механизмы регистрации «пометили» объект. Кроме того, удаление регистрации внутри транзакции может конфликтовать с автоматическими механизмами платформы.

Способ 1: Использование коллекции ОбменДанными.Получатели (Рекомендуемый)

Самый надежный и «чистый» способ предотвратить регистрацию — это управление коллекцией ОбменДанными.Получатели непосредственно перед тем, как платформа начнет процесс записи. Проанализируем, как это реализовать через подписку на событие ПередЗаписью.

Алгоритм действий следующий:

  1. Создадим общую подписку на событие ПередЗаписью для интересующих нас документов.
  2. В обработчике проверим режим записи документа.
  3. Если документ записывается в режиме проведения, мы очистим список получателей и отключим автозаполнение.

Посмотрим на пример кода:


Процедура ПередЗаписьюДокументаДляОбмена(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    // Если это не проведение, ничего не трогаем
    Если РежимЗаписи <> РежимЗаписиДокумента.Проведение Тогда
        Возврат;
    КонецЕсли;
    
    // Отключаем автоматическое заполнение списка получателей
    Источник.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
    
    // Очищаем коллекцию, чтобы регистрация не создалась
    Источник.ОбменДанными.Получатели.Очистить();
    
КонецПроцедуры

Этот метод хорош тем, что он предотвращает само создание записи в таблице изменений, а не пытается удалить её постфактум. Это экономит ресурсы сервера и исключает блокировки таблиц регистрации.

Способ 2: Использование ДополнительныхСвойств объекта

Рассмотрим ситуацию, когда логика определения «нужна ли регистрация» более сложная и рассредоточена по разным модулям. Мы можем использовать свойство ДополнительныеСвойства объекта для передачи флага между событиями ПередЗаписью и ПриЗаписи.

Разберем по шагам:

  1. В событии ПередЗаписью анализируем контекст. Например, если это проведение, устанавливаем наш флаг.
  2. В событии ПриЗаписи (когда ссылка документа уже точно существует в базе) проверяем наличие флага и выполняем удаление регистрации.

Пример реализации в модуле документа или подписке:


// В обработчике ПередЗаписью
Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
    Источник.ДополнительныеСвойства.Вставить("ОтказОтРегистрацииПриПроведении", Истина);
КонецЕсли;

// В обработчике ПриЗаписи
Если Источник.ДополнительныеСвойства.Свойство("ОтказОтРегистрацииПриПроведении") 
   И Источник.ДополнительныеСвойства.ОтказОтРегистрацииПриПроведении Тогда
    
    УзелОбмена = ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.НайтиПоКоду("001");
    ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, Источник.Ссылка);
    
КонецЕсли;

Важный нюанс: как было отмечено в сообщении №8 форума, при таком подходе есть риск «потерять» важные изменения. Если пользователь одновременно изменил сумму в документе и нажал «Провести», то отмена регистрации при проведении приведет к тому, что новые данные не попадут в обмен. Поэтому данный метод стоит использовать с осторожностью или дополнять проверкой модифицированности данных.

Способ 3: Проверка существенности изменений (Подход БСП)

Если ваша конфигурация построена на Библиотеке стандартных подсистем (БСП), как в случае с БП 3.0, лучше всего использовать встроенные механизмы правил регистрации объектов. В БСП можно настроить регистрацию так, чтобы она срабатывала только при изменении значимых реквизитов (например, контрагента, суммы или даты).

Проанализируем преимущества этого подхода:

Для настройки этого механизма не нужно писать код. Достаточно зайти в раздел Администрирование — Синхронизация данных — Состав отправляемых данных и настроить правила регистрации для конкретных объектов, указав список контролируемых полей. Для автоматизации регулярной отправки зарегистрированных объектов по расписанию без изменения конфигураций можно использовать программу регулярного обмена данными между базами 1С.

Почему не работает УдалитьРегистрациюИзменений в ПриПроведении?

Выясним причину неудачи автора темы (сообщение №7). Когда мы вызываем УдалитьРегистрациюИзменений внутри процедуры ПриПроведении, транзакция записи объекта еще не завершена. Платформа 1С работает таким образом, что автоматическая регистрация изменений (согласно настройкам плана обмена) может быть «накатана» финальным аккордом в момент завершения всей транзакции (Commit). Таким образом, ваш программный вызов удаления срабатывает раньше, чем платформа завершает свою автоматическую операцию записи изменений. Именно поэтому управление коллекцией Источник.ОбменДанными.Получатели в событии ПередЗаписью является более приоритетным и корректным методом.

Итоговые рекомендации

Для решения задачи «Запись — регистрируем, проведение — нет» мы рекомендуем придерживаться следующей стратегии:

  1. Для типовых конфигураций: Используйте стандартные возможности БСП по настройке правил регистрации (фильтрация по полям). Это самый безопасный способ, не требующий вмешательства в код.
  2. Для кастомных решений: Используйте подписку на ПередЗаписью с очисткой ОбменДанными.Получатели, но только при условии, что РежимЗаписи = РежимЗаписиДокумента.Проведение.
  3. Безопасность: Всегда информируйте пользователей, что программная отмена регистрации может привести к десинхронизации баз, если при проведении все же были изменены какие-то данные (например, программно в обработке ОбработкаПроведения).

Используя эти методы, вы сможете существенно снизить нагрузку на каналы связи и ускорить процессы закрытия периода в 1С. Чтобы гарантировать отсутствие расхождений в учете после оптимизации правил регистрации, рекомендуется выполнять автоматическую сверку бухгалтерских проводок между базами 1С.

← На главную