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