Мы с вами часто сталкиваемся с ситуацией, когда необходимо предотвратить проведение документа в 1С, если фактически или по данным учета отсутствуют необходимые остатки товаров или материалов. Это критически важно для поддержания актуальности складского учета, предотвращения "минусов" и обеспечения корректности взаиморасчетов. Давайте подробно разберем, как эффективно реализовать такой контроль.
В системе 1С:Предприятие исторически сложились две принципиально разные методики контроля остатков при проведении документов. Мы рассмотрим каждую из них, чтобы понять их особенности и преимущества, а также выясним, какая из них является более предпочтительной в современных условиях.
Эта методика является более традиционной и использовалась с ранних версий 1С:Предприятие 8.0. Ее суть заключается в том, что проверка доступных остатков выполняется до того, как система попытается записать какие-либо движения в регистры накопления. Если по результатам проверки выясняется, что остатков недостаточно, документ просто не проводится, и пользователю сообщается о дефиците.
При таком подходе мы сначала формируем набор движений, которые документ должен был бы сделать, затем по этим движениям собираем необходимые остатки и сравниваем их с фактическими на складе. Если мы видим, что списание приведет к отрицательному остатку, то устанавливаем параметр Отказ в значение Истина и тем самым отказываем в проведении. Этот метод прост для понимания, но может быть менее эффективным в условиях высокой конкуренции за остатки.
Эта методика считается более современной и оптимальной, особенно при работе с управляемыми блокировками и высоконагруженными системами. Она активно применяется с версии 1С:Предприятие 8.2 (с 2010 года) и заключается в следующем:
Преимущество этого подхода заключается в его производительности и масштабируемости. Мы минимизируем количество обращений к базе данных до фактического списания и используем механизмы транзакций для обеспечения целостности данных. Это особенно актуально в многопользовательских системах, где несколько пользователей могут одновременно пытаться списать один и тот же товар, и нам необходимо исключить появление "минусов" из-за параллельных операций.
Давайте посмотрим, как можно реализовать "новую" методику контроля остатков в коде 1С. Подобный код не размещают на формах, поскольку это логика проведения документа, а не интерактивного взаимодействия с пользователем. Он должен находиться в общих модулях или непосредственно в модуле объекта документа, в процедуре ОбработкаПроведения.
Мы будем использовать параметр Отказ обработки проведения. Если проверка выявила дефицит, то мы устанавливаем Отказ = Истина, что автоматически отменяет фиксацию результатов транзакции проведения документа.
Для эффективной проверки отрицательных остатков мы можем использовать МенеджерВременныхТаблиц. Это позволяет нам получать остатки только для той номенклатуры, которая участвует в текущем документе, не загружая всю базу остатков и оптимизируя выполнение запроса.
Рассмотрим пример общей логики, которую мы можем применить в процедуре ОбработкаПроведения:
// Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Шаг 1: Подготовим движения документа.
// Например, заполним табличные части движений на основании данных документа.
// ... (Ваш код заполнения движений)
// Пример: Движения.ОстаткиНоменклатуры.Записывать = Истина;
// Для Каждого СтрокаТЧ Из ТабличнаяЧастьДокумента Цикл
// Движение = Движения.ОстаткиНоменклатуры.Добавить();
// Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
// Движение.Период = Дата;
// Движение.Номенклатура = СтрокаТЧ.Номенклатура;
// Движение.Количество = СтрокаТЧ.Количество;
// // ... другие измерения и ресурсы
// КонецЦикла;
// Шаг 2: Запишем движения в регистры.
// Важно: Эта запись происходит внутри транзакции проведения документа.
// Если Отказ будет установлен в Истина, эти движения будут отменены.
Движения.Записать();
// Шаг 3: Проверим отрицательные остатки после предполагаемого проведения.
// Мы формируем запрос к регистру накопления "ОстаткиНоменклатуры" (или аналогичному).
// Для оптимизации используем МенеджерВременныхТаблиц.
МенеджерВТ = Новый МенеджерВременныхТаблиц;
// Создаем временную таблицу с номенклатурой из движений текущего документа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Движения.Номенклатура КАК Номенклатура
|ПОМЕСТИТЬ ВТ_НоменклатураДокумента
|ИЗ
| РегистрНакопления.ОстаткиНоменклатуры КАК Движения
|ГДЕ
| Движения.Регистратор = &Регистратор"; // &Регистратор - это ссылка на текущий документ
Запрос.УстановитьПараметр("Регистратор", Ссылка);
Запрос.Выполнить(МенеджерВТ);
// Теперь выполняем запрос на остатки, проверяя только нужную номенклатуру
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиНоменклатурыОстатки.Номенклатура,
| ОстаткиНоменклатурыОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &МоментВремени, // Момент времени для получения остатков
| Номенклатура В (ВЫБРАТЬ Номенклатура ИЗ ВТ_НоменклатураДокумента)
| ) КАК ОстаткиНоменклатурыОстатки
|ГДЕ
| ОстаткиНоменклатурыОстатки.КоличествоОстаток < 0";
Запрос.УстановитьПараметр("МоментВремени", МоментВремени()); // Или Дата документа
РезультатЗапроса = Запрос.Выполнить(МенеджерВТ);
Если Не РезультатЗапроса.Пустой() Тогда
// Если есть отрицательные остатки, сообщаем пользователю и отменяем проведение
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Недостаточно остатков по следующим позициям:";
Сообщение.Поле = "Объект"; // Привязываем к объекту документа
Сообщение.УстановитьОбъект(ЭтотОбъект);
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщение.Текст = Сообщение.Текст + Символы.ПС +
" - " + Выборка.Номенклатура +
" (дефицит: " + Формат(-Выборка.КоличествоОстаток, "ЧЦ=15; ЧДЦ=3") + ")";
КонецЦикла;
Сообщение.Сообщить();
КонецЕсли;
// Конец Процедуры
Важный нюанс: для корректной работы этого механизма в многопользовательской среде, мы также можем рассмотреть использование БлокировкаДанных для предотвращения одновременного списания одних и тех же остатков разными документами. Однако, "новая" методика с транзакциями уже сама по себе обеспечивает значительную часть необходимой защиты.
Мы можем сделать контроль остатков более гибким, используя функциональные опции. Функциональные опции позволяют описывать функциональность конфигурации и автоматически изменять ее поведение в зависимости от настроек, которые может задавать пользователь или администратор.
ИспользоватьКонтрольОтрицательныхОстатков типа Булево.ОбработкаПроведения.В типовых конфигурациях 1С, таких как УправлениеТорговлей (УТ 11) и БухгалтерияПредприятия (БП 3.0), уже реализованы подобные настройки. Например, в БП 8 мы можем отключить контроль отрицательных остатков при списании товаров, установив флажок "Разрешить списание запасов при отсутствии остатков по данным учета" в разделе "Администрирование – Проведение документов".
Это позволяет пользователям адаптировать систему под свои бизнес-процессы, например, временно отключать строгий контроль в период инвентаризации или при работе с предварительными документами.
Помимо основных методик, нам следует проанализировать ряд дополнительных факторов, влияющих на контроль остатков:
При оперативном проведении документа система обычно присваивает текущее время и не позволяет проводить документы будущей датой. В этом режиме мы должны выполнять максимум проверок, включая строгий контроль остатков, чтобы исключить одновременную продажу одного товара несколькими продавцами или списание несуществующих позиций. При неоперативном проведении (например, для ввода документов прошлым периодом) контроль остатков может быть менее строгим или вовсе не иметь смысла, если мы предполагаем последующую корректировку.
Некоторые конфигурации, например, 1С:УНФ, имеют специфический контроль остатков, который может заблокировать операцию, если при отмене проведения приходной накладной может появиться отрицательный остаток. Это важный аспект, который мы должны учитывать, чтобы не допустить "минусов" из-за обратных операций.
Как мы уже упоминали, в некоторых конфигурациях есть возможность отключить контроль отрицательных остатков. Однако мы должны понимать, что при отключении контроля возрастает риск появления отрицательных остатков. Это может привести к искажению данных учета, некорректным отчетам и сложностям при закрытии периода. В таких случаях проводка может быть сформирована только в количественном выражении без сумм. Отрицательные остатки затем придется исправлять с помощью специальных отчетов или обработок.
Нам важно выяснить причины появления отрицательных остатков, чтобы предотвратить их. Чаще всего они связаны с несостыковкой времени и даты проведения документов поступления и реализации, ошибками при вводе начальных остатков, пересортом товарно-материальных ценностей между складами или субсчетами, а также нарушениями последовательности проведения документов.
Для предотвращения отрицательных остатков мы рекомендуем регулярно актуализировать данные, проводить инвентаризации и сверять физические остатки с данными системы. Для выявления и исправления отрицательных остатков в 1С существуют специальные отчеты, например, "Контроль отрицательных остатков ТМЗ" или "Остатки товаров", которые помогут нам оперативно найти и устранить проблемы.
Внимательно проанализировав все эти аспекты, мы сможем эффективно настроить контроль остатков в 1С, обеспечив точность и целостность нашего учета.
← К списку