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

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

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

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

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

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

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

Что проверить перед объединением таблиц

Прежде чем писать код, сравните структуру обеих таблиц. Совпадение имён колонок — минимальное требование для большинства способов. Если в первой таблице колонка называется «Номенклатура», а во второй — «Товар», объединение «в лоб» создаст две разные колонки, и половина строк окажется с пустыми значениями.

Типы значений тоже имеют значение. Если в одной таблице колонка «Количество» имеет тип Число, а в другой — составной тип или Строка, при дальнейшей свёртке и сортировке возможны ошибки преобразования. Проверить состав колонок можно так:

Для Каждого Колонка Из Таблица1.Колонки Цикл

Сообщить(Колонка.Имя + " | " + Строка(Колонка.ТипЗначения));

КонецЦикла;

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

Колонки совпадают по именам и типамМожно объединять напрямую

Подойдёт любой способ: цикл или запрос

Имена колонок различаютсяНужна подготовка

Переименуйте колонки или сопоставьте их в запросе

Строк больше нескольких десятков тысячЦикл будет медленным

Используйте объединение через запрос

Нужны суммы по дублямПосле слияния нужна свёртка

Примените Свернуть() или СГРУППИРОВАТЬ ПО в запросе

Способ 1. Построчное копирование в цикле

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

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

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

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

КонецЦикла;

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

Если нужна независимая итоговая таблица, а не модификация первой, заранее создайте её копией: ИтоговаяТЗ = Таблица1.Скопировать(); — и добавляйте строки уже в неё. Метод Скопировать() создаёт полную независимую копию данных, тогда как простое присваивание скопирует только ссылку на объект.

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

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

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

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

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

"ВЫБРАТЬ Т.Номенклатура, Т.Количество, Т.Сумма

|ПОМЕСТИТЬ ВТ1 ИЗ &Таблица1 КАК Т

|;

|ВЫБРАТЬ Т.Номенклатура, Т.Количество, Т.Сумма

|ПОМЕСТИТЬ ВТ2 ИЗ &Таблица2 КАК Т

|;

|ВЫБРАТЬ Т.Номенклатура, Т.Количество, Т.Сумма

|ИЗ ВТ1 КАК Т

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

|ВЫБРАТЬ Т.Номенклатура, Т.Количество, Т.Сумма

|ИЗ ВТ2 КАК Т";

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

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

ИтоговаяТЗ = Запрос.Выполнить().Выгрузить();

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

Дополнительное преимущество запроса — можно сразу сгруппировать результат и посчитать итоги, добавив СГРУППИРОВАТЬ ПО и СУММА() к полям. Это заменяет связку «объединение + свёртка» одним действием.

bsl
Запрос.Текст = "ВЫБРАТЬ Т.Номенклатура, СУММА(Т.Количество) КАК Количество ИЗ (ВЫБРАТЬ Т.Номенклатура, Т.Количество ИЗ &Т1 КАК Т ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Т.Номенклатура, Т.Количество ИЗ &Т2 КАК Т) КАК Т СГРУППИРОВАТЬ ПО Т.Номенклатура";

Способ 3. Слияние со свёрткой методом Свернуть()

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

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

ЗаполнитьЗначенияСвойств(Таблица1.Добавить(), СтрокаТЗ);

КонецЦикла;

Таблица1.Свернуть("Номенклатура", "Количество,Сумма");

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

Сравнение способов и критерии выбора

Выбор зависит от объёма данных, необходимости группировки и того, где исполняется код. Ниже — сопоставление основных характеристик.

КритерийЦикл с Добавить()Запрос с ОБЪЕДИНИТЬСлияние + Свернуть()
Скорость на больших таблицахНизкаяВысокаяСредняя
Сложность кодаМинимальнаяСредняяМинимальная
Группировка и итогиНетДа, в том же запросеДа, через Свернуть()
Разные имена колонокНужна подготовкаСопоставляются в тексте запросаНужна подготовка
Удаление дублейНетДа (ОБЪЕДИНИТЬ без ВСЕ)Частично, через свёртку
Маршрут решения

Как выбрать способ

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

Частые ошибки при объединении таблиц

Ошибка номер один — присваивание вместо копирования. Конструкция ИтоговаяТЗ = Таблица1; не создаёт новую таблицу: обе переменные указывают на один объект, и добавление строк в «итоговую» меняет исходную. Если исходная таблица используется дальше по коду, данные окажутся испорчены.

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

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

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

Как проверить результат объединения

Минимальная проверка — сравнить количество строк: при слиянии без удаления дублей итоговое число строк должно равняться сумме строк исходных таблиц. Если строк меньше — где-то сработала группировка или свёртка; если больше — вероятно, цикл добавления выполнился несколько раз.

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

СуммаДо = Таблица1.Итог("Сумма") + Таблица2.Итог("Сумма");

СуммаПосле = ИтоговаяТЗ.Итог("Сумма");

Если СуммаДо <> СуммаПосле Тогда

Сообщить("Расхождение итогов: " + (СуммаПосле - СуммаДо));

КонецЕсли;

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

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

Количество строк итоговой таблицы
Норма

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

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

Меньше — сработала группировка; больше — цикл отработал повторно

Итоги по числовым колонкам
Норма

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

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

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

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

Все нужные колонки на месте и заполнены

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

Колонки исчезли после Свернуть() или пусты из-за разных имён

FAQ: частые вопросы

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

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

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

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

Как объединить таблицы и сразу удалить дубли строк?

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

Почему после Свернуть() пропали колонки?

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

Какой способ быстрее для таблиц по 100 тысяч строк?

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

Итог

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

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