Как исправить задваивание записей в запросе 1С при использовании левых соединений?

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

В процессе разработки отчетов или сложных выборок данных в 1С разработчики часто сталкиваются с проблемой «задваивания» или «затраивания» строк. Рассмотрим, почему это происходит и как правильно организовать архитектуру запроса, чтобы избежать дублирования итоговых показателей.

Понимание природы проблемы

Основная причина возникновения дублей заключается в механизме работы ЛЕВОЕ СОЕДИНЕНИЕ. Когда мы присоединяем к таблице-источнику (например, Инциденты) таблицу с детальными данными (например, Наряды), где для одного инцидента существует несколько записей, 1С создает столько строк в итоговом результате, сколько записей найдено в правой таблице.

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

Пошаговое решение: используем временные таблицы

Для исправления данной проблемы мы будем использовать стратегию «разделяй и властвуй». Разделим задачу на два этапа: сначала подготовим корректные данные, затем присоединим их к основному запросу.

Шаг 1: Предварительная агрегация данных

Рассмотрим детальный запрос, который подготавливает суммы по нарядам. Важно, чтобы на этом этапе в результирующей таблице была ровно одна строка для каждого ГлавныйДокумент. Мы используем СГРУППИРОВАТЬ ПО, чтобы схлопнуть все наряды в единую сумму.


ВЫБРАТЬ
    НарядРасходы.Ссылка.ГлавныйДокумент КАК ГлавныйДокумент,
    СУММА(НарядРасходы.СуммаФакт) КАК СуммаФакт
ПОМЕСТИТЬ ВТ_СуммаПоНарядам
ИЗ
    Документ.Наряд.Расходы КАК НарядРасходы
СГРУППИРОВАТЬ ПО
    НарядРасходы.Ссылка.ГлавныйДокумент
;

Шаг 2: Присоединение подготовленных данных

Теперь, когда у нас есть готовая временная таблица ВТ_СуммаПоНарядам, мы можем смело присоединять ее к основному запросу. Поскольку в этой таблице для одного документа всегда только одна строка, количество записей основного запроса не увеличится.


ВЫБРАТЬ
    СвойстваДокументов.Документ КАК Документ,
    СвойстваДокументов.Документ.Клиент КАК ДокументКлиент,
    СвойстваДокументов.Документ.Услуга КАК ДокументУслуга,
    СвойстваДокументов.Документ.Клиент.Контрагент КАК ДокументКлиентКонтрагент,
    СУММА(ВЫРАЗИТЬ(СвойстваДокументов.Значение КАК ЧИСЛО(15, 2))) КАК СуммаОбращения,
    ПараметыУровняСервиса.ФактическаяДатаЗакрытия КАК ФактическаяДатаЗакрытия,
    СвойстваДокументов.Документ.Ответственный КАК Ответственный,
    ВТ_СуммаПоНарядам.ГлавныйДокумент КАК ГлавныйДокумент,
    СУММА(ВТ_СуммаПоНарядам.СуммаФакт) КАК СуммаФакт
ИЗ
    РегистрСведений.СвойстваДокументов КАК СвойстваДокументов
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПараметыУровняСервиса КАК ПараметыУровняСервиса
        ПО СвойстваДокументов.Документ = ПараметыУровняСервиса.Инцидент
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_СуммаПоНарядам КАК ВТ_СуммаПоНарядам
        ПО СвойстваДокументов.Документ = ВТ_СуммаПоНарядам.ГлавныйДокумент
ГДЕ
    СвойстваДокументов.Документ ССЫЛКА Документ.Инцидент
    И НЕ СвойстваДокументов.Документ.Клиент.Контрагент ЕСТЬ NULL
    И СвойстваДокументов.Свойство = &Свойство
    И ПараметыУровняСервиса.ФактическаяДатаЗакрытия МЕЖДУ &НачДата И &КонДата
СГРУППИРОВАТЬ ПО
    СвойстваДокументов.Документ,
    СвойстваДокументов.Документ.Клиент,
    СвойстваДокументов.Документ.Услуга,
    СвойстваДокументов.Документ.Клиент.Контрагент,
    ПараметыУровняСервиса.ФактическаяДатаЗакрытия,
    СвойстваДокументов.Документ.Ответственный,
    ВТ_СуммаПоНарядам.ГлавныйДокумент

Рекомендации для отладки

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

  1. Анализ «сырых» данных: Временно уберите СГРУППИРОВАТЬ ПО и выведите все поля из обеих таблиц. Это позволит визуально увидеть, какая именно запись создает дубль.
  2. Проверка условий связи: Убедитесь, что в блоке ПО вы используете только ключевые поля, которые однозначно связывают документы.
  3. Минимализм в группировке: Никогда не добавляйте лишние поля из присоединенной таблицы в СГРУППИРОВАТЬ ПО, если они не являются необходимыми для вывода результата. Любое лишнее поле в группировке может привести к нежелательному дроблению записей.

Использование временных таблиц — это стандарт де-факто при работе со сложными отчетами 1С. Этот подход не только исключает ошибки задваивания, но и значительно повышает производительность запросов, так как 1С оптимизирует работу с ПОМЕСТИТЬ, создавая индексированные промежуточные структуры.

← На главную