Как зарегистрировать изменения документов для внутренней обработки без настройки обмена данными

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

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

Способ 1: Использование планов обмена (Классический метод)

Планы обмена в 1С предназначены для регистрации изменений данных для последующей передачи в другие базы. Однако никто не запрещает использовать их как внутренний «журнал изменений». Главное преимущество этого метода — авторегистрация. Вам не нужно писать код в каждом документе; достаточно указать в составе плана обмена нужные объекты и поставить флаг авторегистрации.

Проанализируем ситуацию с префиксами, которая часто пугает разработчиков. В типовых конфигурациях на базе БСП (Библиотека стандартных подсистем) включение плана обмена часто активирует механизмы префиксации номеров документов. Чтобы обойти это ограничение, можно использовать «пустой» или технический префикс (например, 00), либо программно отключить проверку префикса в модуле обмена данными. Если база не является распределенной (РИБ), флаг «Распределенная информационная база» в свойствах плана обмена должен быть снят — это избавит от многих жестких проверок платформы.

Для регистрации изменений вручную (если авторегистрация по каким-то причинам не подходит) можно использовать программный код в подписке на событие:


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

Способ 2: Регистр сведений + Подписка на событие

Если использование планов обмена кажется избыточным или мешает логика префиксации, разберем альтернативный вариант — создание простого регистра сведений (например, ОчередьТрансляцииПроводок). Этот способ дает полный контроль над процессом.

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

  1. Создаем непериодический регистр сведений с одним измерением Объект (тип: ДокументСсылка).
  2. Создаем подписку на событие ПриЗаписи для необходимых типов документов.
  3. В обработчике подписки записываем ссылку в регистр.

Рассмотрим пример кода для подписки:


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

После того как ваша обработка трансляции проводок выполнит свою работу, запись из регистра просто удаляется. Это исключает проблему «раздувания» базы данных.

Способ 3: Механизм «История данных» (для современных платформ)

Начиная с версии платформы 8.3.11, мы можем использовать встроенный механизм История данных. Это наиболее современный подход, который не требует создания дополнительных объектов метаданных типа планов обмена.

Выясним преимущества этого метода: он работает на уровне платформы, практически не снижает производительность при записи и позволяет получить не только ссылку на измененный объект, но и понять, что именно изменилось. Для решения нашей задачи достаточно включить историю данных для нужных документов в свойствах метаданных. Затем программно можно получить список измененных объектов через ИсторияДанныхМенеджер.

Как эффективно удалять регистрацию «отработанных» документов

Когда ваша обработка трансляции (или любая другая) закончила работу с документом, его нужно убрать из списка регистрации, иначе при следующем запуске он обработается повторно. Рассмотрим, как это сделать правильно в случае использования планов обмена.

Многие начинающие разработчики пытаются удалять регистрацию пообъектно в цикле. Это не совсем верно, так как может вызвать блокировки таблиц. Проанализируем более надежный метод с использованием номеров сообщений:

  1. При начале обработки получаем изменения и фиксируем НомерСообщения.
  2. После успешного завершения трансляции вызываем метод очистки по номеру сообщения.

Пример программного удаления регистрации:


// Удаление регистрации для конкретного объекта
ПланыОбмена.УдалитьРегистрациюИзменений(УзелСсылка, ОбъектРегистрации);

// Или более эффективный метод — удаление пакетом после обработки
// НомерСообщения — это число, полученное при вызове ПланыОбмена.ВыбратьИзменения()
ПланыОбмена.УдалитьРегистрациюИзменений(УзелСсылка, НомерСообщения);

Оптимизация производительности и нюансы транзакций

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

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

Также стоит предусмотреть механизм очистки таблиц регистрации. Если по какой-то причине регламентное задание перестанет работать, таблицы планов обмена могут вырасти до гигантских размеров, что замедлит всю систему. Рекомендуется настроить мониторинг количества записей в таблицах регистрации изменений.

Резюме

Для решения задачи регистрации изменений без внешнего обмена лучше всего подходит План обмена с авторегистрацией, если вы хотите минимизировать количество кода. Если же вам критически важно отсутствие префиксов и полный контроль над логикой — используйте Регистр сведений. Для баз на новейших версиях платформы наиболее элегантным решением будет использование Истории данных.

← На главную