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

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

В процессе разработки отчетов на базе Системы компоновки данных (СКД) или обычных запросов 1С, программисты часто сталкиваются с задачей объединения данных из нескольких источников (для отладки которых пригодится консоль запросов для управляемых форм). Типичная ситуация: есть две таблицы (например, остатки и обороты или основные и подчиненные документы), и нужно вывести их в одну строку, сохранив при этом записи, которые присутствуют только в одном из источников. Стандартное ЛЕВОЕ СОЕДИНЕНИЕ часто приводит к потере данных из «правой» таблицы, а ПОЛНОЕ СОЕДИНЕНИЕ может работать некорректно при наличии множественных связей или специфических условий в секции ГДЕ.

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

Метод 1: Эмуляция полного соединения через таблицу ключей

Проанализируем ситуацию (провести быстрый анализ данных поможет правильный подход), когда у нас есть две временные таблицы: ВТ1 и ВТ2. В первой таблице хранятся документы и их связи, во второй — количественные показатели. Основная проблема заключается в том, что ключи (например, ссылки на документы или номенклатуру) могут не совпадать полностью. Если мы просто присоединим одну таблицу к другой, данные, не имеющие пары, пропадут.

Разберем наиболее надежный способ решения этой задачи — создание «эталонной» таблицы ключей (поможет инструменты разработки на 1С с помощью LLM):

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

Метод 2: Особенности связи по Номенклатуре и Характеристикам

Выясним причину, по которой обычное соединение может не работать для товарных справочников. При работе с Номенклатурой критически важно учитывать Характеристику. Если в одной таблице характеристика заполнена, а в другой нет, простое условие ПО Т1.Номенклатура = Т2.Номенклатура даст неверный результат (декартово произведение).

Рассмотрим правильный подход к условию связи:

Если в вашей конфигурации используются характеристики, связь всегда должна идти по паре полей. Однако здесь кроется ловушка: значение NULL (отсутствие записи) и ПустаяСсылка (объект не выбран) в 1С воспринимаются по-разному. Рекомендуем использовать конструкцию ЕСТЬNULL в условии связи или предварительно типизировать пустые значения во временных таблицах.

Пример корректной связи в запросе:


ПО Т1.Номенклатура = Т2.Номенклатура
И ЕСТЬNULL(Т1.Характеристика, ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) = 
  ЕСТЬNULL(Т2.Характеристика, ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка))

Реализация через механизмы СКД

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

Использование нескольких наборов данных:

Вместо того чтобы объединять всё в одном огромном запросе, создадим два независимых Набора данных - запрос (для ВТ1 и ВТ2). На закладке Связи наборов данных укажем параметры связи. Важно помнить, что СКД по умолчанию выполняет левое соединение от первого набора ко второму. Чтобы получить эффект полного соединения в интерфейсе отчета, нужно создать третий набор — «Список ключей» — и сделать его ведущим для первых двух.

Роль ресурсов:

Проанализируем ситуацию с «разными строками», на которые жалуются многие разработчики. В СКД это не является проблемой, если правильно настроены Ресурсы. Если вы объединили таблицы через ОБЪЕДИНИТЬ ВСЕ, и у вас получились две строки, где в одной есть документ, но нет количества, а в другой — количество, но пустой документ, просто укажите поле Количество как ресурс с функцией Сумма. При выводе в группировку по документу СКД автоматически объединит эти строки в одну.

Важные рекомендации по оптимизации

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

← На главную