Почему при программном проведении Перемещения товаров со статусом Принято не появляются остатки в УТ 11

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

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

В данной статье мы подробно разберем причины такого поведения системы, проанализируем архитектурные особенности конфигураций на базе ERP и УТ 11, а также выработаем надежные алгоритмы программного проведения документов.

Разбор первой причины: Ордерная схема склада

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

Рассмотрим два варианта развития событий:

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

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

Анализ программного проведения и свойства ОбменДанными.Загрузка

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

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

Проанализируем правильный подход к записи объекта:


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

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

Важный нюанс: В некоторых релизах УТ 11.4 наблюдалась особенность — если менять статус одновременно с вызовом метода Записать(РежимЗаписиДокумента.Проведение), система могла отработать по старой логике (как для статуса Отгружено). Чтобы этого избежать, попробуйте применить двухэтапную схему: сначала записать документ со статусом в режиме Запись, а затем вызвать процедуру проведения.

Влияние блокировок и транзакционных ошибок

Если проблема возникает редко (1 док из 100) и в логах нет ошибок, стоит рассмотреть теорию скрытых конфликтов блокировок. На платформе 8.3.11 и выше в кластере 1С возможна ситуация, когда транзакция завершается на уровне встроенного языка, но из-за таймаута или специфики работы СУБД (MS SQL или PostgreSQL) изменения в регистрах не фиксируются.

Рассмотрим, как это происходит. В УТ 11 используется управляемый режим блокировок. Если одновременно с вашей загрузкой выполняется тяжелое фоновое задание (например, расчет себестоимости или распределение запасов), система может не успеть записать данные в таблицы итогов. Хотя метод Записать() не выкинет исключение Исключение, данные физически не попадут в базу из-за особенностей кэширования сервера приложений.

Для минимизации таких рисков рекомендуется:

  1. Не проводить все 150 документов в одной большой транзакции. Каждое проведение должно быть в своем блоке Попытка...Исключение.
  2. Использовать регламентное задание для «допроведения» проблемных документов.

Использование регламентного задания как «костыля» или решения

Разберем вариант, предложенный опытными разработчиками: создание регламентного задания, которое ищет документы со статусом Принято, у которых отсутствуют движения по регистру ТоварыНаСкладах (или ТоварыОрганизаций).

Посмотрим на пример запроса для поиска таких «пустых» документов:


ВЫБРАТЬ
    ПеремещениеТоваров.Ссылка КАК Ссылка
ИЗ
    Документ.ПеремещениеТоваров КАК ПеремещениеТоваров
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
        ПО ПеремещениеТоваров.Ссылка = ТоварыНаСкладах.Регистратор
ГДЕ
    ПеремещениеТоваров.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыПеремещенийТоваров.Принято)
    И ПеремещениеТоваров.Проведен = ИСТИНА
    И ТоварыНаСкладах.Регистратор ЕСТЬ NULL

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

Специфика регистра «Распределение запасов»

Начиная с версий 11.4, в системе появился регистр сведений РаспределениеЗапасов. Именно на его данных строятся многие отчеты по остаткам. Иногда движения в регистре накопления ТоварыНаСкладах физически существуют, но отчеты показывают пустоту. Это происходит из-за того, что запись в регистр сведений по каким-то причинам не обновилась.

Проанализируем ситуацию: если в консоли запросов вы видите приход по складу, а в отчете «Остатки и доступность товаров» — нет, значит, проблема в регистре распределения. В типовых конфигурациях есть обработка «Исправление ошибок в регистре сведений "Распределение запасов"». Рекомендуется запускать её периодически при массовых программных загрузках.

Итоговые рекомендации по исправлению

Для того чтобы решить проблему гарантированно, мы рекомендуем придерживаться следующего алгоритма:

Пример кода с проверкой движений:


ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
ДвиженияСформированы = Ложь;
Для Каждого Набор Из ДокОбъект.Движения Цикл
    Если Набор.Метаданные().Имя = "ТоварыНаСкладах" И Набор.Количество() > 0 Тогда
        ДвиженияСформированы = Истина;
        Прервать;
    КонецЕсли;
КонецЦикла;

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

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

← На главную