При разработке внешних отчетов на СКД (системе компоновки данных) программисты часто сталкиваются с проблемой, когда при наличии нескольких серий (сроков годности) у одного товара общее количество остатка «размножается». Вместо того чтобы распределить остаток по срокам, отчет выводит общую сумму склада напротив каждой серии. Проанализируем, почему это происходит, и найдем верное решение для конфигурации 1С:Розница 2.3.
Рассмотрим стандартную механику запроса, которая приводит к ошибке. Когда мы соединяем таблицу ТоварыНаСкладах.Остатки с таблицей движений серий, происходит следующее: в таблице остатков нет разреза по сериям (если это не предусмотрено политикой учета), там хранится просто общее число, например, 10 штук. В таблице серий при этом есть две записи: «Срок 1» и «Срок 2». При левом соединении система 1С сопоставляет общее число 10 каждой найденной серии. В итоге в отчете мы видим 10 штук для первого срока и 10 для второго, что дает ложный итог в 20 штук.
Проанализируем ситуацию в контексте 1С:Розница 2.3. В этой конфигурации учет серий часто носит справочный характер или настраивается через политику учета серий. Если в регистре накопления ТоварыНаСкладах измерение Серия отсутствует, получить остаток в разрезе сроков годности из этой таблицы напрямую невозможно.
Чтобы отчет выводил корректные данные, нам необходимо изменить логику получения остатка. Мы будем использовать регистр ДвиженияСерийТоваров. Это основной источник информации о том, какая серия когда пришла и когда ушла.
Разберем по шагам, как составить правильный запрос. Нам нужно получить не просто обороты, а вычислить итоговый остаток по каждой серии. В данном регистре остатки как таковые не хранятся, поэтому мы используем математический подход: Приход - Расход = Остаток.
Посмотрим на пример структуры запроса, который позволит избежать дублирования:
ВЫБРАТЬ
ДвиженияСерий.Номенклатура КАК Номенклатура,
ДвиженияСерий.Характеристика КАК Характеристика,
ДвиженияСерий.Серия КАК Серия,
ДвиженияСерий.Серия.ГоденДо КАК СрокГодности,
СУММА(ВЫБОР
КОГДА ДвиженияСерий.КоличествоОборот > 0
ТОГДА ДвиженияСерий.КоличествоОборот
ИНАЧЕ -ДвиженияСерий.КоличествоОборот
КОНЕЦ) КАК РеальныйОстаток
ИЗ
РегистрНакопления.ДвиженияСерийТоваров.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ДвиженияСерий
СГРУППИРОВАТЬ ПО
ДвиженияСерий.Номенклатура,
ДвиженияСерий.Характеристика,
ДвиженияСерий.Серия
В этом примере мы используем виртуальную таблицу Обороты. Важно понимать, что в некоторых версиях конфигурации приход и расход могут определяться типом складской операции. Проанализируем, как добавить учет продаж, чтобы остаток был актуальным.
Если в вашем отчете отображаются только поступления, но не учитываются продажи, значит, в условии ГДЕ или в операторе ВЫБОР ограничены типы операций. Для полноценного отчета по остаткам сроков годности необходимо учитывать все движения.
Рассмотрим подробнее логику распределения операций в ВЫБОР КОГДА:
Проанализируем обновленный фрагмент кода, который учитывает направление движения товара:
СУММА(ВЫБОР
КОГДА ДвиженияСерийТоваровОбороты.СкладскаяОперация В (
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ПриемкаОтПоставщика),
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ВводОстатков),
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ОтражениеИзлишков)
) ТОГДА ДвиженияСерийТоваровОбороты.КоличествоОборот
КОГДА ДвиженияСерийТоваровОбороты.СкладскаяОперация В (
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ОтгрузкаКлиенту),
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ОтгрузкаВРозницу),
ЗНАЧЕНИЕ(Перечисление.СкладскиеОперации.ОтражениеНедостач)
) ТОГДА -ДвиженияСерийТоваровОбороты.КоличествоОборот
ИНАЧЕ 0
КОНЕЦ) КАК КонечныйОстатокПоСерии
Если вы предпочитаете разделять получение общих данных (наименование, артикул, цена) и данных по сериям, необходимо правильно настроить Связи наборов данных в схеме компоновки.
Выясним типичную ошибку в связях: если вы связываете наборы только по полю Номенклатура, СКД все равно может продублировать остаток из первого набора. Чтобы этого не происходило:
Номенклатура и Характеристика (обязательно, если используются характеристики).КоличествоОстаток (общее) должно быть ресурсом только для того набора, где нет серий.Серии внутри группировки по Номенклатуре.Чтобы отчет был полезен для бизнеса, часто требуется видеть, сколько дней осталось до конца срока годности. Для этого в СКД на вкладке Вычисляемые поля добавим поле ДнейДоКонцаСрока.
Используем функцию РАЗНОСТЬДАТ:
РАЗНОСТЬДАТ(ТекущаяДата(), Серия.ГоденДо, "ДЕНЬ")
Это позволит в настройках отчета установить условное оформление: например, подсвечивать красным строки, где срок годности истекает менее чем через 10 дней.
Проанализируем еще несколько технических моментов, которые помогут оптимизировать отчет:
Складу или Магазину внутри параметров виртуальных таблиц, а не в секции ГДЕ.ВЫБРАТЬ РАЗРЕШЕННЫЕ, чтобы избежать ошибок при запуске отчета пользователями с ограниченными правами (RLS).СГРУППИРОВАТЬ ПО). Перенесите расчет итогов на вкладку Ресурсы. Это даст системе больше гибкости при построении различных вариантов отчета пользователем.Таким образом, решив проблему через расчет остатков на основе регистра ДвиженияСерийТоваров, мы получаем точный и надежный инструмент для контроля сроков годности в 1С:Розница 2.3, исключая дублирование данных и некорректные итоговые суммы.