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