При получении данных об остатках товарно-материальных ценностей (ТМЦ) часто возникает необходимость детализировать информацию не только по сериям, но и по характеристикам номенклатуры. Рассмотрим, как правильно модифицировать запрос к остаткам в конфигурациях 1С, использующих построитель отчета (например, Управление торговлей или Управление торговым предприятием), и разберем распространенные ошибки, из-за которых итоговая таблица может оставаться пустой.
Проанализируем базовый запрос, который выбирает номенклатуру и серии. Обычно структура строится из двух основных частей:
Номенклатура и подчиненных справочников (СерииНоменклатуры, ХарактеристикиНоменклатуры).ТоварыНаСкладах.Остатки, ТоварыВРознице.Остатки, ТоварыВНТТ.Остатки).Чтобы добавить разрез ХарактеристикаНоменклатуры, необходимо внедрить это измерение на всех уровнях вложенных подзапросов и в условиях соединения таблиц.
Рассмотрим доработанный вариант запроса, в который добавлена работа с характеристиками номенклатуры:
ТекстЗапроса = "
|ВЫБРАТЬ
| ИСТИНА КАК Печать,
| СпрНоменклатура.Номенклатура КАК Номенклатура,
| СпрНоменклатура.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| СпрНоменклатура.СерияНоменклатуры КАК СерияНоменклатуры,
| СпрНоменклатура.Номенклатура.ЕдиницаХраненияОстатков КАК ЕдиницаИзмерения,
| 0 КАК Цена,
| 1 КАК Количество
|ИЗ
| (ВЫБРАТЬ
| СпрНоменклатура.Ссылка КАК Номенклатура,
| ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка) КАК ХарактеристикаНоменклатуры,
| ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка) КАК СерияНоменклатуры
| ИЗ
| Справочник.Номенклатура КАК СпрНоменклатура
| ГДЕ
| НЕ СпрНоменклатура.ЭтоГруппа
| {ГДЕ
| СпрНоменклатура.Ссылка.* КАК Номенклатура}
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| СпрСерии.Владелец,
| ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка),
| СпрСерии.Ссылка
| ИЗ
| Справочник.СерииНоменклатуры КАК СпрСерии
| {ГДЕ
| СпрСерии.Владелец.* КАК Номенклатура,
| СпрСерии.Ссылка.* КАК СерияНоменклатуры}
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| СпрХарактеристики.Владелец,
| СпрХарактеристики.Ссылка,
| ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка)
| ИЗ
| Справочник.ХарактеристикиНоменклатуры КАК СпрХарактеристики
| {ГДЕ
| СпрХарактеристики.Владелец.* КАК Номенклатура,
| СпрХарактеристики.Ссылка.* КАК ХарактеристикаНоменклатуры}
| ) КАК СпрНоменклатура
|";
Если ТолькоИмеющиесяВНаличии Тогда
ТекстЗапроса = ТекстЗапроса + "
|ЛЕВОЕ СОЕДИНЕНИЕ
| (ВЫБРАТЬ
| НаСкладе.Номенклатура КАК Номенклатура,
| НаСкладе.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| НаСкладе.СерияНоменклатуры КАК СерияНоменклатуры,
| СУММА(НаСкладе.Количество) КАК Количество
| ИЗ
| (ВЫБРАТЬ
| НаСкладе.Номенклатура КАК Номенклатура,
| НаСкладе.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| НаСкладе.СерияНоменклатуры КАК СерияНоменклатуры,
| НаСкладе.КоличествоОстаток КАК Количество
| ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, {Номенклатура.* КАК Номенклатура,
| ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| СерияНоменклатуры.* КАК СерияНоменклатуры,
| Склад.* КАК Склад}) КАК НаСкладе
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ВРознице.Номенклатура,
| ВРознице.ХарактеристикаНоменклатуры,
| ВРознице.СерияНоменклатуры,
| ВРознице.КоличествоОстаток КАК Количество
| ИЗ
| РегистрНакопления.ТоварыВРознице.Остатки(, {Номенклатура.* КАК Номенклатура,
| ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| СерияНоменклатуры.* КАК СерияНоменклатуры,
| Склад.* КАК Склад}) КАК ВРознице
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ВНТТ.Номенклатура,
| ВНТТ.ХарактеристикаНоменклатуры,
| ВНТТ.СерияНоменклатуры,
| ВНТТ.КоличествоОстаток КАК Количество
| ИЗ
| РегистрНакопления.ТоварыВНТТ.Остатки(, {Номенклатура.* КАК Номенклатура,
| ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| СерияНоменклатуры.* КАК СерияНоменклатуры,
| Склад.* КАК Склад}) КАК ВНТТ
| ) КАК НаСкладе
| СГРУППИРОВАТЬ ПО
| НаСкладе.Номенклатура,
| НаСкладе.ХарактеристикаНоменклатуры,
| НаСкладе.СерияНоменклатуры
| ) КАК НаСкладе
|ПО
| СпрНоменклатура.Номенклатура = НаСкладе.Номенклатура
| И СпрНоменклатура.ХарактеристикаНоменклатуры = НаСкладе.ХарактеристикаНоменклатуры
| И СпрНоменклатура.СерияНоменклатуры = НаСкладе.СерияНоменклатуры
|ГДЕ
| ЕСТЬNULL(НаСкладе.Количество, 0) > 0
|";
КонецЕсли;
Часто после внедрения кода таблица остатка перестает заполняться или возвращает пустой результат при включенном флаге ТолькоИмеющиесяВНаличии. Разберем основные причины этого поведения:
В секции формирования разрезов справочники объединяются через ОБЪЕДИНИТЬ ВСЕ. Это создает строки, где либо заполнения серии нет (пустая ссылка), либо нет характеристики. Однако если на складе лежит товар, у которого одновременно заполнены и серия, и характеристика, условие соединения по равенству всех трех полей (Номенклатура, ХарактеристикаНоменклатуры, СерияНоменклатуры) не найдет совпадения в объединении справочников. Фильтр ЕСТЬNULL(НаСкладе.Количество, 0) > 0 полностью исключит такие строки.
Проанализируем код заполнении табличной части после выполнения построителя отчета. Типичной ошибкой является замена значения характеристики прямой ссылкой через реквизит серии:
// Некорректный код обработки:
Для Каждого Стр Из Товары Цикл
Стр.ХарактеристикаНоменклатуры = Стр.СерияНоменклатуры.ХарактеристикаНоменклатуры;
КонецЦикла;
В типовых конфигурациях (УТ, УТП) справочники ХарактеристикиНоменклатуры и СерииНоменклатуры являются независимыми и связаны только через владельца — справочник Номенклатура. У элемента серии нет реквизита ХарактеристикаНоменклатуры. Запуск такого кода вызывает ошибку либо обнуляет заполненость поля.
Для гарантированного получения корректных результатов применим следующие решения:
ТолькоИмеющиесяВНаличии = ИСТИНА, выборка из справочников не требуется. Таблицы ТоварыНаСкладах.Остатки уже содержат актуальные комбинации Номенклатура + Характеристика + Серия.Товары.Загрузить(ПостроительОтчета.Результат.Выгрузить()). Дополнительно переобходить строки циклами для заполнения характеристик не требуется — все колонки уже заполнил запрос.