Как настроить динамическую подмену элементов справочника в запросах 1С и СКД для правильной группировки

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов в системе 1С:Предприятие часто возникает задача динамического объединения или подмены элементов справочников в группировках. Например, когда у нас есть три производителя (Производитель 1, Производитель 2 и Производитель 3), но бизнес-требования диктуют, что товары Производителя 2 должны отображаться в группе Производителя 3. В этой статье мы подробно разберем, как решить эту задачу правильно, избегая критических ошибок производительности, и рассмотрим несколько подходов — от простых запросов до изящных архитектурных решений.

Критическая ошибка проектирования: Смешение типов данных

Для начала проанализируем типичную ошибку, которую часто допускают начинающие разработчики. В попытках быстро решить задачу подмены в тексте запроса пишут следующую конструкцию:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    ВЫБОР
        КОГДА Номенклатура.Производитель.Наименование = "Компас здоровья"
            ТОГДА "Вивид"
        ИНАЧЕ Номенклатура.Производитель
    КОНЕЦ КАК ПроизводительДляГруппировки
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Давайте выясним причину, почему этот код является плохим решением. Здесь в конструкции ВЫБОР в ветке ТОГДА возвращается строковое значение (Строка), а в ветке ИНАЧЕ — ссылка на элемент справочника (СправочникСсылка.Производители).

В результате СУБД вынуждена формировать поле составного типа. Это приводит к следующим негативным последствиям:

  1. Падение производительности: Группировка по полям составного типа на уровне базы данных происходит значительно медленнее, так как СУБД тратит дополнительные ресурсы на неявные преобразования типов и дополнительные соединения таблиц.
  2. Потеря интерактивности в отчете: В результирующем отчете СКД пропадет возможность стандартной расшифровки. Пользователь не сможет дважды кликнуть на подмененного производителя ("Вивид") и открыть его карточку, так как для системы это будет обычная текстовая строка, а не ссылка на объект базы данных.

Важное правило разработки: Типы возвращаемых значений во всех ветках конструкции ВЫБОР обязательно должны совпадать. Если мы хотим сгруппировать данные по ссылкам, то подменять нужно ссылку на другую ссылку. Если группировка строится по текстовым наименованиям, то в секции ИНАЧЕ необходимо явно обращаться к наименованию: Номенклатура.Производитель.Наименование.

Способ 1. Динамическая подмена ссылок через параметры запроса

Если заменяемые элементы справочника определяются динамически в процессе работы программы, лучшим решением будет передача нужных ссылок через параметры запроса. Рассмотрим этот метод подробнее.

Сначала мы находим нужные элементы справочника во встроенном языке 1С и передаем их в качестве параметров запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	ВЫБОР
    |		КОГДА Номенклатура.Производитель = &ПроизводительИсточник
    |			ТОГДА &ПроизводительПриемник
    |		ИНАЧЕ Номенклатура.Производитель
    |	КОНЕЦ КАК ПроизводительДляГруппировки
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура";

// Заполняем параметры запроса конкретными ссылками
Запрос.УстановитьПараметр("ПроизводительИсточник", Справочники.Производители.НайтиПоКоду("000000002"));
Запрос.УстановитьПараметр("ПроизводительПриемник", Справочники.Производители.НайтиПоКоду("000000003"));

РезультатЗапроса = Запрос.Выполнить();

Этот способ гарантирует, что результирующее поле ПроизводительДляГруппировки всегда будет иметь строго один тип данных — СправочникСсылка.Производители. Отчет будет работать максимально быстро, а пользователи смогут стандартным образом открывать карточки производителей из отчета.

Способ 2. Использование функции ЗНАЧЕНИЕ() для предопределенных элементов

Бывают ситуации, когда заменяемые элементы справочника созданы разработчиком заранее на этапе конфигурирования как предопределенные. В этом случае нам не нужно передавать параметры из программного кода. Мы можем обратиться к ним напрямую в тексте запроса с помощью конструкции ЗНАЧЕНИЕ().

Посмотрим на пример реализации такого запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    ВЫБОР
        КОГДА Номенклатура.Производитель = ЗНАЧЕНИЕ(Справочник.Производители.КомпасЗдоровья)
            ТОГДА ЗНАЧЕНИЕ(Справочник.Производители.Вивид)
        ИНАЧЕ Номенклатура.Производитель
    КОНЕЦ КАК ПроизводительДляГруппировки
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Данный подход лаконичен, не требует написания кода на встроенном языке для заполнения параметров и работает чрезвычайно быстро, так как ссылки определяются платформой на этапе компиляции запроса.

Способ 3. Элегантное решение через Вычисляемые поля СКД

Если ваш отчет строится на базе Системы компоновки данных (СКД), то вносить изменения в исходный текст запроса не обязательно. Мы можем настроить подмену элементов на уровне самой схемы компоновки, используя встроенный механизм вычисляемых полей. Это существенно упрощает дальнейшую поддержку отчета.

Разберем этот процесс по шагам:

  1. Откройте схему компоновки данных вашего отчета и перейдите на вкладку Вычисляемые поля.
  2. Добавьте новую строку. В колонке Путь к данным укажите имя нового поля, например: ПроизводительДляГруппировки.
  3. Задайте понятный Заголовок для пользователя, например: Производитель (для группировки).
  4. В колонке Выражение напишите условие на языке выражений СКД:
    Выбор Когда Производитель = &ПараметрПроизводительИсточник Тогда &ПараметрПроизводительПриемник Иначе Производитель Конец
  5. Перейдите на вкладку Параметры. Платформа автоматически добавит туда новые параметры &ПараметрПроизводительИсточник и &ПараметрПроизводительПриемник. При необходимости вы можете сделать их доступными для изменения пользователем или задать значения по умолчанию.
  6. На вкладке Настройки в структуре отчета добавьте группировку не по стандартному полю Производитель, а по созданному вычисляемому полю ПроизводительДляГруппировки.

При таком подходе СКД автоматически объединит все данные по заменяемому производителю в общую ветку отчета. При этом сохраняются все связи, механизмы расшифровки и типы данных ссылок.

Способ 4. Профессиональный архитектурный подход (Избавление от жесткого кодирования)

Прописывание конкретных кодов, наименований или даже предопределенных элементов непосредственно в запросах или настройках отчетов (так называемый "хардкод") считается плохим тоном в программировании. Если завтра бизнес-требования изменятся и потребуется объединить других производителей, разработчику придется снова открывать конфигуратор и переписывать код.

Проанализируем универсальное решение, которое полностью переносит управление группировками на сторону пользователей в режиме "1С:Предприятие".

Для реализации этого подхода выполним следующие действия:

  1. В конфигураторе откроем справочник Производители и добавим в него новый реквизит с именем ГоловнойПроизводитель (тип данных: СправочникСсылка.Производители).
  2. Если конфигурацию менять нельзя, мы можем использовать механизм дополнительных реквизитов из Библиотеки стандартных подсистем (БСП).
  3. В режиме "1С:Предприятие" пользователь сам заходит в карточку Производителя 2 и указывает в поле ГоловнойПроизводитель значение "Производитель 3". Для всех остальных производителей это поле остается пустым.
  4. В запросе отчета мы пишем простое и универсальное условие, которое никогда не придется менять:

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    ВЫБОР
        КОГДА Номенклатура.Производитель.ГоловнойПроизводитель = ЗНАЧЕНИЕ(Справочник.Производители.ПустаяСсылка)
            ТОГДА Номенклатура.Производитель
        ИНАЧЕ Номенклатура.Производитель.ГоловнойПроизводитель
    КОНЕЦ КАК ПроизводительДляГруппировки
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Рассмотрим, как работает это условие. Если у производителя не заполнен головной контрагент (то есть там пустая ссылка), система группирует данные по самому производителю. Если же связь заполнена, система автоматически подставляет в группировку головную компанию. Это гибкое решение, которое делает вашу систему масштабируемой и удобной для конечных пользователей.

← На главную