Как очистить движения регистра накопления в подписке на событие «Обработка проведения» в 1С?

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

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

Разберем детально, почему так происходит в современных типовых конфигурациях (1С:ERP, 1С:Управление торговлей 11, 1С:Комплексная автоматизация) и рассмотрим проверенные способы очистки движений.

Выясним причину проблемы

Поведение платформы и типовых конфигураций на базе БСП обусловлено двухфазным механизмом проведения документов:

  1. Перезапись движений платформой: По умолчанию платформа не удаляет старые движения перед проведением, а обновляет их. При вызове метода Очистить() набора записей без установки флага Записывать = Истина платформа считает, что набор записей не менялся, и оставляет прежние записи в базе данных.
  2. Очистка менеджера временных таблиц: В конфигурациях ERP, УТ 11 и КА проведение документа использует временные таблицы для выполнения проверок (например, контроля остатков и себестоимости). В момент выполнения глобального обработчика подписки основной код проведения документа уже сформировал и записал наборы записей, после чего менеджер временных таблиц очищается и уничтожается для освобождения памяти. Когда подписка пытается повторно записать движения, модуль набора записей снова запускает встроенные проверки ПередЗаписью, и обращение к уже уничтоженному менеджеру ВТ приводит к ошибке.

Рассмотрим практические варианты решения этой задачи.

Способ 1. Использование подписки на событие «Перед записью» набора записей регистра (Рекомендуемый)

Наиболее корректный и безопасный способ — перенести логику очистки из подписки на проведение документа в подписку на событие набора записей самого регистра накопления.

Проанализируем алгоритм решения по шагам:

  1. Создадим подписку на событие с типом объекта РегистрНакопленияНаборЗаписей.<ИмяРегистра>.
  2. Укажем событие ПередЗаписью.
  3. В обработчике подписки проверим тип регистратора и, если это целевой документ, очистим набор записей.

Рассмотрим пример кода обработчика подписки:


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

КонецПроцедуры

При таком подходе очистка происходит непосредственно в момент записи набора записей в базу данных, не нарушая работу встроенных механизмов проведения документа и не вызывая ошибок инициализации менеджера временных таблиц.

Способ 2. Инициализация нового менеджера временных таблиц в подписке «Обработка проведения»

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

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


Процедура ПодпискаПриПроведенииОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт

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

КонецПроцедуры

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

Способ 3. Использование расширения конфигурации

Если требуется полностью исключить формирование движений по определенному регистру без снятия конфигурации с поддержки, можно применить расширение:

  1. Добавим в расширение модуль менеджера документа или общий модуль проведения.
  2. Используем аннотацию &После к процедуре формирования движений или подготовки таблиц проведения.
  3. Удалим нужную таблицу из коллекции подготовленных движений до того, как система начнет их запись в базу данных.

Этот подход позволяет избежать полного переопределения алгоритмов проведения через &Вместо и сохраняет прозрачность конфигурации при обновлениях.

Подведем итоги

Мы разобрали причины, по которым простое очищение движений в подписке на событие ОбработкаПроведения не дает результата или приводит к ошибке менеджера временных таблиц. Для типовых конфигураций (1С:ERP, 1С:УТ 11, 1С:КА) наиболее надёжным и архитектурно верным решением является использование подписки на событие ПередЗаписью набора записей регистра накопления.

← На главную