Как убрать дубли в запросе 1С и настроить сложную шапку в СКД

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Причина возникновения дублей: декартово произведение

Проанализируем ситуацию: когда мы выполняем ЛЕВОЕ СОЕДИНЕНИЕ основной таблицы (например, Заказы клиентов) с табличной частью (Контактная информация), система создает новую строку для каждого совпадения. Если у одного контрагента в базе заведено три номера телефона (рабочий, мобильный и личный), то одна строка заказа превратится в три. Если же мы добавим соединение с таблицей Товары, где в заказе пять позиций, количество строк увеличится кратно (3 телефона * 5 товаров = 15 строк на один заказ).

Рассмотрим, как ограничить выборку, чтобы оставить только нужные данные и избежать "размножения" записей.

Способ 1. Фильтрация контактной информации по типу

Самый простой способ избавиться от лишних строк — четко указать системе, какой именно тип контактной информации нас интересует. В 1С контактная информация хранится в разрезе типов (Телефон, Адрес, Электронная почта и т.д.).

Посмотрим на пример правильного формирования временной таблицы для получения телефонов:


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

Использование ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон) позволяет гарантировать, что в выборку не попадут почтовые адреса, которые также хранятся в этой таблице. Однако, этого может быть недостаточно, если у клиента введено два разных телефона.

Способ 2. Уточнение по виду контактной информации

Чтобы максимально сузить выборку до одной строки, рекомендуется использовать фильтр не только по типу, но и по конкретному Виду контактной информации. Например, "Личный мобильный" или "Телефон для счетов".

Проанализируем пример запроса с фильтрацией по наименованию вида:


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

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

Способ 3. Агрегация данных для гарантированного отсутствия дублей

Если нам не принципиально, какой именно телефон будет выведен (если их несколько), или мы хотим "схлопнуть" записи, следует использовать группировку. Выясним, как это реализовать:


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

Функция МАКСИМУМ выберет один (старший по алфавиту) номер телефона из всех доступных для данного контрагента. Это гарантирует, что для каждой ссылки контрагента в нашей временной таблице КонтрагентыВТ будет ровно одна запись.

Особенности работы в расширениях

Если вы пишете запрос в расширении конфигурации, вы можете столкнуться с тем, что конструктор запросов не видит стандартные перечисления. В этом случае у вас есть два пути:

  1. Добавить перечисление в расширение: Нужно найти ТипыКонтактнойИнформации в основной конфигурации и нажать "Добавить в расширение".
  2. Использовать параметры: Вместо написания ЗНАЧЕНИЕ(...) в тексте запроса, используйте параметр &ТипТелефон и устанавливайте его значение в коде на языке 1С.

Настройка сложных шапок в СКД

Перейдем ко второй части задачи — визуальному оформлению отчета. Стандартная таблица СКД выводит поля в один ряд. Но что делать, если нужно объединить несколько колонок под одним заголовком (например, "Данные контрагента", а под ним "ФИО" и "Телефон")?

Метод "Группа выбранных полей"

Рассмотрим наиболее простой и эффективный метод:

  1. Откройте вкладку Настройки в схеме компоновки данных.
  2. Перейдите на закладку Выбранные поля.
  3. Нажмите правой кнопкой мыши на поле или в пустом месте и выберите Новая группа выбранных полей.
  4. В поле "Заголовок" впишите общее название для группы (например, "Информация о купоне").
  5. В поле "Расположение" выберите Горизонтально.
  6. Перетащите нужные поля (Номер купона, Статус) внутрь этой группы.

В результате СКД автоматически сформирует двухэтажную шапку, где общим заголовком будет название группы, а под ним — названия конкретных полей.

Метод "Макет оформления"

Если стандартных групп недостаточно и требуется индивидуальный дизайн (например, определенные цвета, границы или объединение ячеек в шахматном порядке), необходимо использовать вкладку Макеты.

Разберем алгоритм действий:

  1. На вкладке Макеты нажмите "Добавить макет заголовка группировки".
  2. В появившемся окне выберите область ячеек в табличном документе.
  3. Оформите ячейки так, как они должны выглядеть в отчете (объедините, раскрасьте).
  4. В параметрах макета сопоставьте ваши нарисованные ячейки с именами полей из набора данных СКД.

Этот метод более трудоемкий, но он дает 100% контроль над визуальным представлением отчета.

Использование флага "Без повторяющихся"

В завершение проанализируем совет использовать флаг Без повторяющихся (аналог DISTINCT в SQL). Этот флаг помогает только в том случае, если строки дублируются абсолютно полностью во всех выбранных колонках. Если же у вас в одной строке телефон "123", а в другой "456", при этом остальные поля (ФИО, Заказ, Дата) одинаковые — флаг РАЗЛИЧНЫЕ не поможет, так как строки технически разные. В таких случаях поможет только грамотная фильтрация через ГДЕ или агрегация через СГРУППИРОВАТЬ ПО.

Таким образом, для получения чистого и корректного отчета мы всегда должны сначала "подготовить" данные во временных таблицах, исключив множественные связи, и только потом выводить их в финальную выборку, используя средства оформления СКД для создания красивых заголовков.

← На главную