К статье
Практический материал

Разработка и Конфигурация · 9 мин

Объединение двух таблиц значений запросом в 1С

Как объединить две таблицы значений в 1С через запрос: ОБЪЕДИНИТЬ, ОБЪЕДИНИТЬ ВСЕ, помещение ТЗ во временные таблицы, примеры кода и типичные ошибки.

Таблица значений в 1С — объект в памяти, и напрямую передать её в оператор ОБЪЕДИНИТЬ нельзя: запрос работает только с таблицами базы данных и временными таблицами. Поэтому объединение двух таблиц значений всегда строится по одной схеме: обе ТЗ передаются в запрос как параметры, помещаются во временные таблицы, а затем объединяются оператором ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ.

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

Общий принцип: от таблиц значений к временным таблицам

Язык запросов 1С не умеет читать таблицы значений напрямую, но умеет принимать их как параметр. Когда таблица значений передаётся параметром, в тексте запроса она доступна по имени параметра с амперсандом — &Таблица1. Из неё можно выбрать поля и поместить результат во временную таблицу через конструкцию ПОМЕСТИТЬ.

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

Пошаговый пример объединения через ОБЪЕДИНИТЬ ВСЕ

Ниже полный рабочий фрагмент кода. Предполагается, что переменные ТЗ1 и ТЗ2 уже заполнены и содержат колонки «Номенклатура» и «Количество».

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

Запрос.Текст =

"ВЫБРАТЬ

| Т.Номенклатура КАК Номенклатура,

| Т.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Первая

|ИЗ &ТЗ1 КАК Т

|;

|ВЫБРАТЬ

| Т.Номенклатура КАК Номенклатура,

| Т.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Вторая

|ИЗ &ТЗ2 КАК Т

|;

|ВЫБРАТЬ

| ВТ_Первая.Номенклатура,

| ВТ_Первая.Количество

|ИЗ ВТ_Первая

|ОБЪЕДИНИТЬ ВСЕ

|ВЫБРАТЬ

| ВТ_Вторая.Номенклатура,

| ВТ_Вторая.Количество

|ИЗ ВТ_Вторая";

Запрос.УстановитьПараметр("ТЗ1", ТЗ1);

Запрос.УстановитьПараметр("ТЗ2", ТЗ2);

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

Обратите внимание: имена и порядок полей в обеих частях объединения должны совпадать. Если в одной из исходных таблиц нет нужной колонки, её подставляют константой, например 0 КАК Количество или ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).

Порядок действий
  1. 1
    Создайте запрос и назначьте ему менеджер временных таблиц.
  2. 2
    Поместите первую таблицу значений во временную таблицу через параметр и ПОМЕСТИТЬ.
  3. 3
    Поместите вторую таблицу значений аналогично.
  4. 4
    Напишите итоговый запрос с ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ.
  5. 5
    Установите параметры и выполните запрос, выгрузив результат методом Выгрузить().
  6. 6
    Проверьте количество строк и отсутствие нежелательных дублей.

Разница между ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ

Оператор ОБЪЕДИНИТЬ ВСЕ складывает строки обеих таблиц как есть, включая полностью совпадающие дубли. Он работает быстрее, потому что платформе не нужно сравнивать строки между собой. Оператор ОБЪЕДИНИТЬ удаляет дубликаты: строки, у которых совпадают значения всех полей, останутся в результате в одном экземпляре.

Выбор зависит от задачи. Если нужно просуммировать остатки из двух источников, дубли не страшны — берите ОБЪЕДИНИТЬ ВСЕ и группируйте итог. Если нужен список уникальных позиций, используйте ОБЪЕДИНИТЬ либо сгруппируйте результат.

Сравнение вариантов

ОБЪЕДИНИТЬ ВСЕ

Быстро, сохраняет дубли. Подходит для последующей группировки и суммирования показателей.

ОБЪЕДИНИТЬ

Убирает полные дубли строк, но медленнее на больших объёмах. Подходит для списков уникальных значений.

Программное копирование строк

Цикл с ЗаполнитьЗначенияСвойств без запроса. Проще для маленьких таблиц, но не даёт группировок и соединений с данными базы.

Объединение с группировкой и суммированием

Частая практическая задача — не просто сложить строки, а свернуть их по ключу. Для этого итоговый запрос дополняют группировкой:

ВЫБРАТЬ

Объединение.Номенклатура КАК Номенклатура,

СУММА(Объединение.Количество) КАК Количество

ИЗ

(ВЫБРАТЬ

ВТ_Первая.Номенклатура КАК Номенклатура,

ВТ_Первая.Количество КАК Количество

ИЗ ВТ_Первая

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

ВТ_Вторая.Номенклатура,

ВТ_Вторая.Количество

ИЗ ВТ_Вторая) КАК Объединение

СГРУППИРОВАТЬ ПО

Объединение.Номенклатура

Вложенный запрос с объединением выступает источником, а внешний запрос группирует строки. Такой же приём работает, если после объединения нужно соединиться со справочником, чтобы подтянуть наименование или артикул.

Альтернатива: объединение без запроса

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

Для Каждого СтрокаТЗ Из ТЗ2 Цикл

НоваяСтрока = ТЗ1.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ);

КонецЦикла;

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

Маршрут решения

Как выбрать действие

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

Типичные ошибки и ограничения

Самая распространённая ошибка — несовпадение состава или порядка полей в частях объединения. Платформа сопоставляет поля по позиции, а не по имени, поэтому перестановка полей местами приведёт к ошибке типов или к молчаливой подстановке не тех значений.

Вторая группа проблем связана с объёмом. Таблица значений передаётся в запрос целиком, и при очень больших таблицах это расходует память и время. Если таблицы содержат сотни тысяч строк, стоит проверить, нельзя ли получить данные одним запросом к базе сразу, минуя промежуточные ТЗ.

Типичные ошибки
01
Разный порядок полей в частях объединения — поля сопоставляются по позиции, данные попадают не в те колонки.
02
Несовместимые типы колонок в двух таблицах — запрос падает с ошибкой; лечится приведением типов через ВЫРАЗИТЬ.
03
Использование ОБЪЕДИНИТЬ там, где нужны дубли для суммирования — теряются строки и искажаются итоги.
04
Забытый менеджер временных таблиц при раздельном выполнении запросов — временные таблицы не находятся.
05
Передача в запрос таблицы с колонками составного типа без необходимости — замедляет выполнение.

Проверка результата

После выполнения запроса убедитесь, что объединение прошло корректно. Минимальная проверка — количество строк: при ОБЪЕДИНИТЬ ВСЕ оно должно равняться сумме строк обеих исходных таблиц. При ОБЪЕДИНИТЬ — быть меньше или равно этой сумме.

Дополнительно полезно сверить контрольные суммы: например, сумму по количественному полю до и после объединения. Расхождение без видимых причин указывает на потерю строк из-за дублей или на ошибку в соответствии полей.

Контрольные точки

Как проверить результат

Количество строк при ОБЪЕДИНИТЬ ВСЕ
Норма

Равно сумме строк ТЗ1 и ТЗ2

Тревожный признак

Меньше суммы — часть строк потеряна

Сумма по числовому полю
Норма

Совпадает с суммой по обеим исходным таблицам

Тревожный признак

Расходится — проверяйте дубли и соответствие полей

Состав колонок результата
Норма

Все поля на месте, типы соответствуют ожиданиям

Тревожный признак

Лишние или пустые колонки — ошибка в порядке полей

Итог

Что важно запомнить

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

Частые вопросы

Можно ли объединить таблицы значений без запроса?

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

Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ?

ОБЪЕДИНИТЬ удаляет полностью совпадающие строки, ОБЪЕДИНИТЬ ВСЕ оставляет все строки обеих таблиц. Второй вариант быстрее и предпочтителен, если далее выполняется группировка с суммированием.

Почему запрос выдаёт ошибку несовместимости типов?

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

Можно ли объединить таблицу значений с данными регистра?

Да. Поместите таблицу значений во временную таблицу через параметр, а затем соедините её с виртуальной таблицей регистра обычным ЛЕВЫМ или ВНУТРЕННИМ СОЕДИНЕНИЕМ по ключевым полям.

Обязателен ли менеджер временных таблиц?

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

Есть ли ограничение на размер передаваемой таблицы значений?

Жёсткого ограничения нет, но большие таблицы передаются в запрос целиком и расходуют память. При сотнях тысяч строк стоит пересмотреть архитектуру и получать данные запросом напрямую из базы.