Как программно отключить контроль остатков в 1С:УПП при проведении документов?

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

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

В этой статье мы подробно разберем, какими методами можно временно «усыпить бдительность» системы, чтобы провести документ даже при отсутствии товара на складе или незаполненных сериях. Мы проанализируем различные подходы — от самых простых до профессиональных методов, используемых в архитектуре 1С.

Метод 1. Использование неоперативного режима проведения

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

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


// Получаем объект документа
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();

// Устанавливаем режим проведения — Неоперативный
// Это позволит обойти проверку остатков, которая настроена для оперативной работы
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);

Почему это работает? В большинстве типовых механизмов УПП встроенная проверка остатков срабатывает только в том случае, если РежимПроведения равен РежимПроведенияДокумента.Оперативный. При неоперативном проведении система предполагает, что данные вводятся за прошедшее время, и контроль остатков либо отключается вовсе, либо проверяется по иным алгоритмам.

Метод 2. Программное изменение настроек пользователя

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

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

Метод 3. Использование Дополнительных Свойств (AdditionalProperties)

Посмотрим на более «продвинутый» способ, который часто используют разработчики конфигураций. У каждого объекта 1С есть коллекция ДополнительныеСвойства. Это структура, данные из которой видны в модуле документа (в процедурах ПередЗаписью и ОбработкаПроведения).

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


ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

// Добавляем флаг отказа от контроля остатков в дополнительные свойства объекта
// Название ключа может отличаться в зависимости от версии УПП (например, "ОтказОтКонтроляОстатков")
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтказОтКонтроляОстатков", Истина);

// Теперь при проведении код внутри документа может увидеть этот флаг и пропустить проверку
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

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

Метод 4. Режим «ОбменДанными.Загрузка»

Разберем радикальный способ — использование свойства ОбменДанными.Загрузка. Многие начинающие разработчики считают его «панацеей» для записи документов без проверок. Выглядит это так:


ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

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

Метод 5. Техническое заполнение серий

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

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

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


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

Метод 6. Использование привилегированного режима

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


УстановитьПривилегированныйРежим(Истина);

// Выполняем проведение документа
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

УстановитьПривилегированныйРежим(Ложь);

Обратите внимание, что это сработает только в том случае, если в коде ОбработкаПроведения есть явное условие вида: Если Не РольДоступна("ПолныеПрава") Тогда ВыполнитьКонтроль(); КонецЕсли;.

Резюме и рекомендации

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

  1. Если нужно, чтобы документ просто провелся и вы не боитесь «минусов» в учете — используйте неоперативное проведение (Метод 1). Это самый чистый и безопасный способ с точки зрения логики УПП.
  2. Если вам нужно обойти проверки, не меняя логику движений — изучите ДополнительныеСвойства объекта (Метод 3).
  3. Если движения по регистрам вообще не нужны, а нужна только «галочка» о проведении — используйте ОбменДанными.Загрузка (Метод 4).
  4. Если проблема только в сериях — реализуйте техническое заполнение серий перед проведением (Метод 5).

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

← На главную