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

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

Как объединить таблицы значений в 1С

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

Объединение таблиц значений — типовая задача при разработке отчётов, обработок и обменов данными в 1С. Например, нужно собрать остатки по нескольким складам в одну таблицу, склеить результаты двух запросов с одинаковой структурой или собрать данные из разных периодов перед выгрузкой. Встроенного метода «Объединить()» у объекта ТаблицаЗначений нет, поэтому разработчику приходится выбирать один из рабочих приёмов.

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

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

Проверка структуры таблиц перед объединением

Перед любым объединением убедитесь, что колонки обеих таблиц совместимы. Совпадать должны имена колонок и желательно их типы: если в первой таблице колонка «Сумма» имеет тип Число(15,2), а во второй — Строка, при копировании значения будут приведены к типу колонки-приёмника, что может обнулить данные или вызвать ошибку преобразования.

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

bsl
Для Каждого Колонка Из Таблица1.Колонки Цикл
    Если Таблица2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
        Сообщить("Во второй таблице нет колонки: " + Колонка.Имя);
    КонецЕсли;
КонецЦикла;

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

Способ 1. Объединение циклом с копированием строк

Самый прямой приём: перебрать строки второй таблицы и добавить их в первую. Значения переносятся через ЗаполнитьЗначенияСвойств() — это быстрее и надёжнее, чем присваивать каждую колонку вручную, потому что метод сам сопоставляет свойства по именам.

bsl
Для Каждого Строка Из Таблица2 Цикл
    НоваяСтрока = Таблица1.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
КонецЦикла;

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

Важный нюанс: ЗаполнитьЗначенияСвойств переносит только те свойства, которые есть у приёмника. Если в приёмнике колонки нет, данные молча теряются. Поэтому перед массовым переносом стоит выполнить проверку структуры из предыдущего раздела.

Способ 2. Объединение через запрос с ОБЪЕДИНИТЬ ВСЕ

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

bsl
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ <em> ПОМЕСТИТЬ ВТ_1 ИЗ &Таб1 КАК Т
|;
|ВЫБРАТЬ </em> ПОМЕСТИТЬ ВТ_2 ИЗ &Таб2 КАК Т
|;
|ВЫБРАТЬ <em> ИЗ ВТ_1
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ </em> ИЗ ВТ_2";
Запрос.УстановитьПараметр("Таб1", Таблица1);
Запрос.УстановитьПараметр("Таб2", Таблица2);
Результат = Запрос.Выполнить().Выгрузить();

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

Если нужно не просто склеить, а сложить числовые показатели по совпадающим ключам, добавьте группировку: выберите ключевые поля и СУММА() по числовым колонкам. Это заменяет связку «цикл + Свернуть» одним запросом.

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

Цикл с Добавить()

Простой код, гибкая логика на строку. Медленно на больших объёмах, нагружает память.

Запрос с ОБЪЕДИНИТЬ ВСЕ

Быстро на десятках и сотнях тысяч строк, сразу доступны группировка и соединения. Требует совпадения типов колонок.

Копия + Свернуть()

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

Способ 3. Слияние с суммированием через Свернуть()

Частая задача — не просто склеить таблицы, а объединить их так, чтобы строки с одинаковыми ключами (номенклатура, контрагент, склад) схлопнулись в одну, а количества и суммы сложились. Для этого после копирования строк вызывается метод Свернуть().

bsl
Для Каждого Строка Из Таблица2 Цикл
    ЗаполнитьЗначенияСвойств(Таблица1.Добавить(), Строка);
КонецЦикла;
Таблица1.Свернуть("Номенклатура, Склад", "Количество, Сумма");

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

Объединение с разной структурой колонок

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

Второй вариант — использовать запрос: в каждой части объединения явно перечислить поля, а недостающие заменить литералами (0, пустая строка, НЕОПРЕДЕЛЕНО). Типы соответствующих полей в частях объединения должны быть совместимы, иначе запрос вернёт ошибку.

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

Проверка результата и типичные ошибки

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

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

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

Количество строк
Норма

Равно сумме строк исходных таблиц (без свёртки)

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

Меньше ожидаемого — строки потеряны или свёрнуты лишние

Итоги по суммам
Норма

Итог объединённой таблицы равен сумме итогов исходных

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

Расхождение — потеря колонок или ошибка преобразования типов

Значения в строках
Норма

Данные в соответствующих колонках на своих местах

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

Пустые ячейки там, где в источнике были значения, — не совпали имена колонок

Типичные ошибки
01
Использование ОБЪЕДИНИТЬ без ВСЕ — неожиданно исчезают совпадающие строки, итоги занижаются
02
Свернуть() без копии — исходная таблица безвозвратно теряет детализацию и лишние колонки
03
Разные типы колонок в источниках — значения обрезаются или обнуляются при копировании
04
Построчное копирование миллионов строк в цикле — долгое выполнение и риск нехватки памяти
05
Опечатка в имени колонки в Свернуть() — исключение или свёртка не по тем ключам

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

Есть ли в 1С готовый метод для объединения таблиц значений?

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

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

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

Как объединить таблицы, чтобы одинаковые строки сложились по сумме?

Скопируйте строки второй таблицы в первую и вызовите Свернуть(), указав колонки-ключи и суммируемые колонки. Альтернатива — запрос с ОБЪЕДИНИТЬ ВСЕ, группировкой по ключам и СУММА() по числовым полям.

Почему после копирования часть данных пустая?

Чаще всего в таблице-приёмнике отсутствуют колонки с именами источника — ЗаполнитьЗначенияСвойств переносит только совпадающие по имени свойства. Проверьте состав колонок обеих таблиц и совпадение типов.

Что выбрать для таблиц по несколько сотен тысяч строк?

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

Можно ли объединить больше двух таблиц?

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

Итог

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

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