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

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

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

Почему возникают дубли в запросах?

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

Шаг 1: Правильная архитектура запроса через временные таблицы

Чтобы избежать хаоса, разделим задачу на этапы. Вместо попытки «нанизать» все документы в одном огромном соединении, мы будем использовать ПОМЕСТИТЬ для формирования промежуточных наборов данных.

Рассмотрим пошаговый алгоритм:

  1. Создаем временную таблицу для каждого документа, выбирая только необходимые поля и ссылки.
  2. Группируем данные во временных таблицах, если требуется уникальность позиций.
  3. Соединяем подготовленные таблицы строго по ссылке на документ или по связке Ссылка + Номенклатура.

Шаг 2: Реализация на примере кода

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


// Создаем временную таблицу товаров заказа поставщику
ВЫБРАТЬ 
    ЗаказПоставщикуТовары.Ссылка КАК Ссылка,
    ЗаказПоставщикуТовары.Номенклатура КАК Номенклатура,
    ЗаказПоставщикуТовары.Количество КАК Количество
ПОМЕСТИТЬ ВТ_ТоварыЗП
ИЗ Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
ГДЕ ЗаказПоставщикуТовары.Ссылка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
;

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

Шаг 3: Соединение данных

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

Если документы связаны по цепочке (КП -> Заказ -> Заказ поставщику), используйте поле ДокументОснование или связь по ссылке на документ-родитель. Если же вы работаете с товарами, используйте уникальный ключ, например:


ВЫБРАТЬ
    Т1.Ссылка КАК ЗаказПоставщику,
    Т1.Номенклатура,
    Т2.ЦенаЗК
ИЗ ВТ_ТоварыЗП КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ТоварыЗК КАК Т2
    ПО Т1.Ссылка.ДокументОснование = Т2.Ссылка 
    И Т1.Номенклатура = Т2.Номенклатура

Советы по отладке

Чтобы точно понять, на каком этапе «двоятся» данные, следуйте этим рекомендациям:

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

← На главную