При разработке обработок заполнения табличных частей документов (например, Перемещение товаров или Списание товаров) разработчики часто сталкиваются с парадоксальной ситуацией: табличная часть документа заполняется напрямую из виртуальной таблицы остатков регистра накопления ТоварыНаСкладах.Остатки, однако при попытке провести документ система выдает ошибку вида:
«Остатка товара на складе недостаточно. Не хватает N шт; Остаток 0 шт; Требуется N шт»
Разберем подробно причины, по которым возникает подобная ошибка, и рассмотрим способы её решения.
Проанализируем, как система 1С работает с временем при оперативном проведении документов. Когда документ проводится оперативно (параметр РежимПроведенияДокумента.Оперативный), типовой модуль проведения проверяет остатки на текущую системную дату и время (ТекущаяДата()).
Если в коде заполнения табличной части запрос получал остатки на КонецДня(Дата) или на дату документа в будущем, в выборку могли попасть поступления товаров, зафиксированные позже текущего момента времени, но в рамках того же дня. В результате запрос видит остаток, заполняет строку в документе, но при проведении на текущую секунду этого прихода ещё нет, и проведение блокируется контролем остатков.
Для корректного получения остатков на нужную точку времени необходимо использовать объект Граница:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТоварыНаСкладахОстатки.СерияНоменклатуры КАК СерияНоменклатуры,
| ТоварыНаСкладахОстатки.Качество КАК Качество,
| ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Склад", СкладОтправитель);
// Устанавливаем границу на момент времени или конец дня включительно
Запрос.УстановитьПараметр("Период", Новый Граница(КонецПериода(Дата, ВидПериода.День), ВидГраницы.Включая));
В конфигурации 1С:Управление торговлей 10.3 алгоритмы контроля остатков по умолчанию срабатывают только при оперативном проведении документов. При неоперативном проведении проверка остатков алгоритмами проведения опускается (если в дополнительных правах пользователя не включен жесткий контроль остатков при неоперативном проведении).
Если документ создается или проводится за прошедшую дату, проведение в оперативном режиме вызовет ошибку контроля. В таком случае помогает смена режима проведения на неоперативный.
Проанализируем детальность учета товаров. В регистре ТоварыНаСкладах учет ведением остатков разворачивается по нескольким измерениям:
НоменклатураХарактеристикаНоменклатурыСерияНоменклатурыКачествоЕсли при заполнении табличной части документа хотя бы одно из измерений заполнено некорректно (например, подставилась пустая ссылка другого типа, значение NULL или неподходящее качество), алгоритм проведения будет искать остаток по конкретной комбинации аналитики и не найдет его.
Убедитесь, что для пустых значений передаются правильные пустые ссылки справочников, например, Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка().
В регистре накопления ТоварыНаСкладах количество товара всегда хранится в базовой единице (единице хранения остатков с коэффициентом 1). При проведении документа перемещения типовой механизм пересчитывает количество для списания по формуле:
КоличествоКCписанию = Количество * Коэффициент
Если при программном заполнении табличной части в поле Количество записывается значение КоличествоОстаток (которое уже выражено в базовых единицах), и при этом подставляется единица измерения с коэффициентом, отличным от 1 (например, упаковка по 10 шт. с коэффициентом 10), система при проведении умножит количество еще раз. В итоге требуется списать 20 шт. вместо 2 шт., что приведет к ошибке недостачи.
Выясним влияние смежных регистров. Если для склада включен ордерный учет или в настройках учета активны механизмы свободного остатка:
ТоварыНаСкладах не гарантирует его доступность для проведения документа перемещения, так как проведение может дополнительно проверять ордерный регистр ТоварыКПередачеСоСкладов.СвободныеОстатки получать данные о доступном товаре следует из этого регистра, а не из ТоварыНаСкладах, так как часть товара может быть зарезервирована документами заказа.Граница с видом ВидГраницы.Включая или ВидГраницы.Исключая.NULL.