Как исправить ошибку «Попытка использования закрытого менеджера временных таблиц» при проведении документов в 1С:КА и 1С:ERP

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

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

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

Выясняем причину: почему возникает ошибка?

Для начала проанализируем технологическую цепочку проведения документа. В типовых конфигурациях ERP-класса процесс проведения разделен на несколько крупных этапов. Чтобы минимизировать количество обращений к базе данных и ускорить проведение, система использует сквозной МенеджерВременныхТаблиц (МВТ). Он инициализируется в самом начале транзакции проведения и передается «транзитом» через структуру дополнительных свойств документа: ДополнительныеСвойства.ДляПроведения.СтруктураВременныеТаблицы.МенеджерВременныхТаблиц.

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


Запрос.МенеджерВременныхТаблиц = СтруктураВременныеТаблицы.МенеджерВременныхТаблиц;

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

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

Способ №1: Интеграция доработки в общий конвейер проведения (Рекомендуемый путь)

Самая частая ошибка разработчиков — попытка добавить или изменить движения регистров накопления через подписку на событие при записи регистра. В ERP-системах это считается плохой практикой. Изменять движения необходимо непосредственно в процессе подготовки данных для проведения.

В конфигурациях 1С:КА и 1С:ERP за подготовку таблиц движений отвечает модуль менеджера документа. Разберем по шагам, как правильно добавить новый ресурс в движения регистра ТоварыНаСкладах:

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

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


&После("ИнициализироватьДанныеДокумента")
Процедура Расш_ИнициализироватьДанныеДокумента(Ссылка, ДополнительныеСвойства, Отказ)
    
    // Получаем текст запроса из дополнительных свойств, если он там формируется
    // Или модифицируем таблицы, которые будут записаны в движения.
    // Пример заполнения кастомного ресурса "НашНовыйРесурс" непосредственно в таблице движений:
    
    ДвиженияДокумента = ДополнительныеСвойства.ДляПроведения.ТаблицыДвижений;
    Если ДвиженияДокумента.Свойство("ТаблицаТоварыНаСкладах") Тогда
        ТаблицаДвижений = ДвиженияДокумента.ТаблицаТоварыНаСкладах;
        Для Каждого СтрокаДвижения Из ТаблицаДвижений Цикл
            // Наша кастомная логика заполнения нового ресурса
            СтрокаДвижения.НашНовыйРесурс = СтрокаДвижения.Количество * 1.2; 
        КонецЦикла;
    КонецЕсли;

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

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

Способ №2: Отключение расчета изменений при программной записи набора (Обходной путь)

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

Для этого перед вызовом метода Записать() у набора записей следует передать специальный флаг в дополнительные свойства. Проанализируем пример кода:


НаборЗаписей = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка);

// Заполняем движения...
НоваяСтрока = НаборЗаписей.Добавить();
НоваяСтрока.Период = ТекущаяДата();
НоваяСтрока.Склад = СсылкаНаСклад;
НоваяСтрока.Номенклатура = СсылкаНаНоменклатуру;
НоваяСтрока.Количество = 10;
НоваяСтрока.НашНовыйРесурс = 12;

// Важнейшая строка для обхода ошибки менеджера временных таблиц:
НаборЗаписей.ДополнительныеСвойства.Вставить("РассчитыватьИзменения", Ложь);

// Теперь запись пройдет без вызова запросов по контролю остатков
НаборЗаписей.Записать();

При получении свойства РассчитыватьИзменения = Ложь обработчик ПередЗаписью в модуле набора записей регистра просто прервет свое выполнение на раннем этапе и не будет обращаться к закрытому или несуществующему менеджеру временных таблиц.

Способ №3: Анализ свойства документа «Удаление движений»

Иногда ошибка возникает из-за некорректно настроенных свойств самого метаобъекта документа в конфигураторе. Проверим важную настройку:

  1. Откроем конфигуратор и найдем документ, при проведении которого возникает ошибка.
  2. Перейдем на вкладку «Движения».
  3. Обратим внимание на свойство «Удаление движений».

Для корректной работы проведения в ERP-конфигурациях это свойство должно быть установлено в значение «Не удалять автоматически». Если там выбрано «Удалять автоматически», платформа 1С принудительно очищает движения перед началом проведения, ломая внутренние структуры транзакции и очищая ДополнительныеСвойства, что ведет к уничтожению менеджера временных таблиц раньше времени.

Способ №4: Корректное восстановление контекста при отмене проведения

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

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


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

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

← На главную