Разработка и Конфигурация · 9 мин
Как объединить таблицы значений в 1С
Способы объединения таблиц значений в 1С: цикл с добавлением строк, запрос с ОБЪЕДИНИТЬ ВСЕ, свертка итогов. Примеры кода, ошибки и проверка результата.
Объединение таблиц значений — типовая задача при разработке отчётов, обработок и обменов данными в 1С. Например, нужно собрать остатки по нескольким складам в одну таблицу, склеить результаты двух запросов с одинаковой структурой или собрать данные из разных периодов перед выгрузкой. Встроенного метода «Объединить()» у объекта ТаблицаЗначений нет, поэтому разработчику приходится выбирать один из рабочих приёмов.
Основных подхода три: программное копирование строк в цикле, объединение через запрос с конструкцией ОБЪЕДИНИТЬ ВСЕ и объединение с агрегацией через метод Свернуть(). Выбор зависит от того, нужно ли складывать числовые значения по совпадающим ключам, важна ли скорость на больших объёмах и совпадает ли структура колонок у исходных таблиц.
Ниже разобраны все три способа с примерами кода, критериями выбора, типичными ошибками и способами проверить корректность результата.
Проверка структуры таблиц перед объединением
Перед любым объединением убедитесь, что колонки обеих таблиц совместимы. Совпадать должны имена колонок и желательно их типы: если в первой таблице колонка «Сумма» имеет тип Число(15,2), а во второй — Строка, при копировании значения будут приведены к типу колонки-приёмника, что может обнулить данные или вызвать ошибку преобразования.
Порядок колонок значения не имеет — обращение к ячейкам идёт по имени. А вот лишние колонки в одной из таблиц приведут к тому, что часть данных просто не перенесётся. Проверить состав колонок можно в отладчике или программно, перебрав коллекцию Колонки каждой таблицы.
Для Каждого Колонка Из Таблица1.Колонки Цикл
Если Таблица2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Сообщить("Во второй таблице нет колонки: " + Колонка.Имя);
КонецЕсли;
КонецЦикла;Если таблицы получены из разных источников (например, одна из запроса, другая загружена из файла), типы колонок почти наверняка различаются. В этом случае безопаснее создать новую таблицу с явно заданными типами колонок и наполнять её из обоих источников.
Способ 1. Объединение циклом с копированием строк
Самый прямой приём: перебрать строки второй таблицы и добавить их в первую. Значения переносятся через ЗаполнитьЗначенияСвойств() — это быстрее и надёжнее, чем присваивать каждую колонку вручную, потому что метод сам сопоставляет свойства по именам.
Для Каждого Строка Из Таблица2 Цикл
НоваяСтрока = Таблица1.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
КонецЦикла;Способ подходит для таблиц небольшого и среднего размера (до десятков тысяч строк) и для ситуаций, когда нужна дополнительная логика на каждой строке: фильтрация, преобразование значений, пропуск дублей по условию. Если логика не нужна, а объём большой, цикл заметно проигрывает запросу по скорости.
Важный нюанс: ЗаполнитьЗначенияСвойств переносит только те свойства, которые есть у приёмника. Если в приёмнике колонки нет, данные молча теряются. Поэтому перед массовым переносом стоит выполнить проверку структуры из предыдущего раздела.
Способ 2. Объединение через запрос с ОБЪЕДИНИТЬ ВСЕ
Для больших таблиц эффективнее поместить обе в менеджер временных таблиц и объединить запросом. Это также единственный удобный путь, когда результат нужно сразу сгруппировать, отсортировать или соединить с данными информационной базы.
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ <em> ПОМЕСТИТЬ ВТ_1 ИЗ &Таб1 КАК Т
|;
|ВЫБРАТЬ </em> ПОМЕСТИТЬ ВТ_2 ИЗ &Таб2 КАК Т
|;
|ВЫБРАТЬ <em> ИЗ ВТ_1
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ </em> ИЗ ВТ_2";
Запрос.УстановитьПараметр("Таб1", Таблица1);
Запрос.УстановитьПараметр("Таб2", Таблица2);
Результат = Запрос.Выполнить().Выгрузить();Ключевое различие: ОБЪЕДИНИТЬ ВСЕ сохраняет все строки обеих таблиц, включая дубли, а ОБЪЕДИНИТЬ без ВСЕ удаляет полностью совпадающие строки, но работает медленнее из-за дополнительной группировки. Если дубли допустимы или их заведомо нет, всегда используйте вариант с ВСЕ.
Если нужно не просто склеить, а сложить числовые показатели по совпадающим ключам, добавьте группировку: выберите ключевые поля и СУММА() по числовым колонкам. Это заменяет связку «цикл + Свернуть» одним запросом.
Сравнение вариантов
Простой код, гибкая логика на строку. Медленно на больших объёмах, нагружает память.
Быстро на десятках и сотнях тысяч строк, сразу доступны группировка и соединения. Требует совпадения типов колонок.
Подходит для сложения итогов по ключам без запроса. Удаляет неключевые колонки, дубли складываются.
Способ 3. Слияние с суммированием через Свернуть()
Частая задача — не просто склеить таблицы, а объединить их так, чтобы строки с одинаковыми ключами (номенклатура, контрагент, склад) схлопнулись в одну, а количества и суммы сложились. Для этого после копирования строк вызывается метод Свернуть().
Для Каждого Строка Из Таблица2 Цикл
ЗаполнитьЗначенияСвойств(Таблица1.Добавить(), Строка);
КонецЦикла;
Таблица1.Свернуть("Номенклатура, Склад", "Количество, Сумма");Первый параметр — колонки группировки через запятую, второй — суммируемые числовые колонки. Всё, что не вошло ни в один список, из таблицы удаляется. Поэтому перед свёрткой убедитесь, что в таблице нет нужных колонок вне этих двух списков — при необходимости сначала сделайте копию через Скопировать().
Объединение с разной структурой колонок
Когда у таблиц разный набор колонок, есть два рабочих варианта. Первый — привести структуру к общему виду: создать итоговую таблицу с полным набором колонок и нужными типами, затем наполнить её из обоих источников циклом. Отсутствующие в источнике колонки останутся пустыми.
Второй вариант — использовать запрос: в каждой части объединения явно перечислить поля, а недостающие заменить литералами (0, пустая строка, НЕОПРЕДЕЛЕНО). Типы соответствующих полей в частях объединения должны быть совместимы, иначе запрос вернёт ошибку.
- 1Составьте полный список колонок из обеих таблиц и определите тип каждой
- 2Создайте итоговую таблицу с этим набором колонок через Колонки.Добавить()
- 3Перенесите строки из обеих таблиц циклом с ЗаполнитьЗначенияСвойств()
- 4Проверьте итоговое число строк и контрольные суммы по числовым колонкам
Проверка результата и типичные ошибки
После объединения обязательно сверьте результат с ожиданием. Минимальный контроль — количество строк: при склеивании без агрегации оно должно равняться сумме строк исходных таблиц. Для числовых колонок полезно сравнить итоги до и после через Итог() по каждой таблице.
Как проверить результат
Равно сумме строк исходных таблиц (без свёртки)
Меньше ожидаемого — строки потеряны или свёрнуты лишние
Итог объединённой таблицы равен сумме итогов исходных
Расхождение — потеря колонок или ошибка преобразования типов
Данные в соответствующих колонках на своих местах
Пустые ячейки там, где в источнике были значения, — не совпали имена колонок
Частые вопросы
Есть ли в 1С готовый метод для объединения таблиц значений?
Нет, специального метода «Объединить» у объекта ТаблицаЗначений не существует. Используются обходные приёмы: цикл с Добавить(), запрос с ОБЪЕДИНИТЬ ВСЕ или комбинация копирования со Свернуть().
Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ в запросе?
ОБЪЕДИНИТЬ ВСЕ сохраняет все строки обеих выборок, включая полные дубли, и работает быстрее. ОБЪЕДИНИТЬ без ВСЕ дополнительно устраняет дубликаты, что требует группировки и замедляет выполнение на больших объёмах.
Как объединить таблицы, чтобы одинаковые строки сложились по сумме?
Скопируйте строки второй таблицы в первую и вызовите Свернуть(), указав колонки-ключи и суммируемые колонки. Альтернатива — запрос с ОБЪЕДИНИТЬ ВСЕ, группировкой по ключам и СУММА() по числовым полям.
Почему после копирования часть данных пустая?
Чаще всего в таблице-приёмнике отсутствуют колонки с именами источника — ЗаполнитьЗначенияСвойств переносит только совпадающие по имени свойства. Проверьте состав колонок обеих таблиц и совпадение типов.
Что выбрать для таблиц по несколько сотен тысяч строк?
Запрос с помещением таблиц во временные и ОБЪЕДИНИТЬ ВСЕ. Построчный цикл на таких объёмах работает значительно медленнее и создаёт лишнюю нагрузку на память сервера или клиента.
Можно ли объединить больше двух таблиц?
Да. В цикле — последовательно переносить строки из каждой таблицы в итоговую. В запросе — добавить нужное число частей ОБЪЕДИНИТЬ ВСЕ, каждая со своей временной таблицей или источником данных.
Что важно запомнить
Готового метода объединения нет: для малых таблиц достаточно цикла с ЗаполнитьЗначенияСвойств, для больших — запроса с ОБЪЕДИНИТЬ ВСЕ, для сложения итогов — Свернуть(). Перед объединением проверяйте имена и типы колонок, после — количество строк и контрольные суммы.