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