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

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

1. Стандартный метод Объединить(): простой способ для одинаковых структур

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

Пример кода:

Таблица1.Объединить(Таблица2);

Где:

  • 📌 Таблица1 — таблица, в которую будут добавлены данные
  • 📌 Таблица2 — таблица-источник (её строки копируются)
⚠️ Внимание: Если в таблицах есть колонки с одинаковыми именами, но разными типами данных (например, в одной колонка Сумма типа Число, а в другой — Строка), метод вызовет ошибку. Перед объединением проверьте структуру через Таблица.Колонки.

Преимущества метода:

  • Максимальная скорость — работает быстрее ручных циклов
  • 🔄 Сохраняет порядок строк (сначала все строки из Таблица1, затем из Таблица2)
  • 📝 Не требует дополнительного кода для простых случаев
💡

Если нужно объединить более двух таблиц, используйте цепочку вызовов: Таблица1.Объединить(Таблица2).Объединить(Таблица3);

2. Метод Загрузить(): когда структуры таблиц отличаются

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

Синтаксис:

Таблица1.Загрузить(Таблица2, СоответствиеКолонок, ПараметрыЗагрузки);

Пример с разными структурами:

Соответствие = Новый СоответствиеКолонокТаблицыЗначений;

Соответствие.Добавить("Наименование", "ИмяТовара"); // Колонка "Наименование" из Таблица1 ← "ИмяТовара" из Таблица2

Соответствие.Добавить("Цена", "Стоимость");

Таблица1.Загрузить(Таблица2, Соответствие);

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

Важные нюансы:

  • 🔄 Если не указать СоответствиеКолонок, метод попытается сопоставить колонки по именам (может привести к ошибкам!).
  • 🚫 Колонки, для которых не указано соответствие, будут проигнорированы.
  • ⚠️ При использовании ПараметрыЗагрузки.Заменять строки с одинаковыми ключами будут перезаписаны.
📊 Какой метод объединения таблиц вы используете чаще?
Объединить()
Загрузить()
Цикл по строкам
Запрос
Другой

3. Объединение через запрос: гибкость и контроль дубликатов

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

Пример кода для объединения с удалением дубликатов по колонке Код:

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

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

"ВЫБРАТЬ

| Таблица1.Код КАК Код,

| Таблица1.Наименование КАК Наименование,

| Таблица1.Цена КАК Цена

|ИЗ

| &Таблица1 КАК Таблица1

|

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

|

|ВЫБРАТЬ

| Таблица2.Код КАК Код,

| Таблица2.Наименование КАК Наименование,

| Таблица2.Цена КАК Цена

|ИЗ

| &Таблица2 КАК Таблица2";

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

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

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

ОбъединеннаяТаблица = Результат.Выгрузить();

Преимущества метода:

  • 🔍 Возможность использовать ГДЕ, УПОРЯДОЧИТЬ ПО, ГРУППИРОВКА
  • 🚀 Удаление дубликатов через ОБЪЕДИНИТЬ (без ВСЕ)
  • 🔄 Объединение таблиц с разной структурой (можно выбрать только нужные колонки)
⚠️ Внимание: При большом количестве строк запрос может работать медленнее, чем Объединить(). Для оптимизации используйте индексы или временные таблицы.
Как ускорить запрос при объединении больших таблиц?

Для ускорения добавьте в текст запроса конструкцию ИНДЕКСИРОВАТЬ ПО Код (если объединяете по ключевому полю). Также можно разбить запрос на части или использовать пакетную обработку через ВыполнитьПакетно().

4. Ручное объединение через цикл: когда нужна максимальная гибкость

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

Пример кода с проверкой дубликатов:

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

Найдена = Ложь;

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

Если СущСтрока.Код = Строка.Код Тогда

Найдена = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если Не Найдена Тогда

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

НоваяСтрока.Код = Строка.Код;

НоваяСтрока.Наименование = Строка.Наименование;

НоваяСтрока.Цена = Строка.Цена;

КонецЕсли;

КонецЦикла;

Когда стоит использовать этот метод:

  • 🔧 Нужна индивидуальная обработка каждой строки (например, преобразование данных)
  • 🔍 Требуется сложная проверка дубликатов (не только по одному полю)
  • 📊 Нужно агрегировать данные (например, суммировать значения при совпадении ключей)

Проверьте совпадение типов данных в колонках|Создайте резервную копию исходных таблиц|Определите ключевые поля для проверки дубликатов|Оцените производительность для больших таблиц (более 10 000 строк)

-->

5. Объединение с агрегацией: суммирование значений по ключам

Частая задача — не просто объединить таблицы, а просуммировать значения по совпадающим ключам. Например, если в обеих таблицах есть товары с одинаковым кодом, и нужно сложить их количество или стоимость.

Решение через запрос:

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

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

"ВЫБРАТЬ

| Код,

| СУММА(Количество) КАК Количество,

| СУММА(Сумма) КАК Сумма

|ИЗ

| (ВЫБРАТЬ

| Таблица1.Код КАК Код,

| Таблица1.Количество,

| Таблица1.Сумма

| ИЗ

| &Таблица1 КАК Таблица1

|

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

|

| ВЫБРАТЬ

| Таблица2.Код КАК Код,

| Таблица2.Количество,

| Таблица2.Сумма

| ИЗ

| &Таблица2 КАК Таблица2)

|ГРУППИРОВКА ПО Код";

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

ИтоговаяТаблица = Результат.Выгрузить();

Альтернативный вариант через циклы (если нужно больше контроля):

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

Найдена = Ложь;

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

Если СущСтрока.Код = Строка.Код Тогда

СущСтрока.Количество = СущСтрока.Количество + Строка.Количество;

СущСтрока.Сумма = СущСтрока.Сумма + Строка.Сумма;

Найдена = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если Не Найдена Тогда

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

НоваяСтрока.Код = Строка.Код;

НоваяСтрока.Количество = Строка.Количество;

НоваяСтрока.Сумма = Строка.Сумма;

КонецЕсли;

КонецЦикла;

💡

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

6. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с проблемами при объединении таблиц. Вот самые распространённые ошибки и способы их решения:

⚠️ Внимание: Если после объединения в таблице появляются пустые строки или данные "съезжают", скорее всего, не совпадает порядок или типы колонок. Всегда проверяйте структуру через Таблица.Колонки.Счет() и Таблица.Колонки[Имя].ТипЗначения.
Ошибка Причина Решение
Ошибка приведение типов Колонки с одинаковыми именами имеют разные типы (например, Число и Строка) Приведите типы к общему перед объединением: Таблица2.Колонки["Цена"].ТипЗначения = Тип("Число");
Потеря данных Использован режим Заменять вместо Добавлять в ПараметрыЗагрузки Явно укажите ПараметрыЗагрузки.Режим = РежимЗагрузкиДанныхТаблицыЗначений.Добавлять
Дублирование строк При объединении не учтены повторяющиеся ключи Используйте ОБЪЕДИНИТЬ без ВСЕ в запросе или проверяйте дубли в цикле
Медленная работа Цикл по строкам для таблиц с >10 000 записей Замените цикл на запрос или используйте Объединить()/Загрузить()

Дополнительные советы:

  • 🔍 Перед объединением проверяйте размер таблиц: если в одной из них >50 000 строк, рассмотрите вариант пакетной обработки.
  • 📌 Для отладки используйте Сообщить(Таблица1.Количество()) до и после объединения.
  • 🔄 Если структура таблиц часто меняется, выносите логику объединения в отдельную функцию с проверкой колонок.

7. Оптимизация производительности для больших таблиц

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

1. Используйте временные таблицы в запросах:

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

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

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ТоварыОстатки.Код КАК Код,

| ТоварыОстатки.Количество

|ПОМЕСТИТЬ ВТОстатки

|ИЗ

| &Таблица1 КАК ТоварыОстатки

|

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

|

|ВЫБРАТЬ

| ТоварыПриход.Код КАК Код,

| ТоварыПриход.Количество

|ИЗ

| &Таблица2 КАК ТоварыПриход";

2. Разбивайте большие таблицы на пакеты:

РазмерПакета = 1000;

КоличествоПакетов = Цел(Таблица2.Количество() / РазмерПакета) + 1;

Для Сч = 0 По КоличествоПакетов - 1 Цикл

Начало = Сч * РазмерПакета;

КонецПакета = Мин(Начало + РазмерПакета, Таблица2.Количество()) - 1;

Пакет = Таблица2.ПолучитьСтроки(Начало, КонецПакета);

Таблица1.Объединить(Пакет);

КонецЦикла;

3. Отключайте проверку прав при массовых операциях:

Прав = ПраваДоступа.ТекущиеПрава();

Попытка

ПраваДоступа.УстановитьПрава(Новый ПраваДоступа(Истина, Истина, Истина, Истина, Истина));

// Код объединения таблиц

Исключение

ПраваДоступа.УстановитьПрава(Прав);

ВызватьИсключение;

КонецПопытки;

ПраваДоступа.УстановитьПрава(Прав);

⚠️ Внимание: Отключение проверки прав ускоряет работу, но может нарушить логику безопасности. Используйте только в доверенных процедурах.
💡

Для таблиц с >100 000 строк оптимальный способ — выгрузка в временные таблицы базы данных с последующим объединением через SQL-запрос (если используется клиент-серверный вариант 1С).

Часто задаваемые вопросы

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

Да, но только через метод Загрузить() с явным указанием соответствия колонок или через запрос, где вы выбираете только нужные поля. Метод Объединить() требует одинаковой структуры.

Как объединить таблицы и удалить дубликаты по нескольким полям?

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

ВЫБРАТЬ

Код,

Артикул,

Наименование

ИЗ

(ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВЫБРАТЬ ...)

ГРУППИРОВКА ПО Код, Артикул, Наименование

Почему после объединения данные в колонках "съехали"?

Это происходит, если колонки в таблицах имеют одинаковые имена, но разный порядок. Метод Объединить() сопоставляет колонки по позиции, а не по имени. Решение:

  1. Проверьте порядок колонок через Таблица.Колонки.Индекс(ИмяКолонки).
  2. Используйте Загрузить() с явным соответствием.
  3. Или переупорядочьте колонки перед объединением: Таблица.Колонки.Переместить(Индекс1, Индекс2).
Как объединить таблицы и просуммировать только числовые колонки?

Лучше всего использовать запрос с агрегацией:

ВЫБРАТЬ

Код,

Наименование,

СУММА(Количество) КАК Количество,

МАКСИМУМ(Цена) КАК Цена // Цену берем из любой таблицы

ИЗ

(ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ...)

ГРУППИРОВКА ПО Код, Наименование

Если нужно суммировать не все числовые колонки, укажите их явно в запросе.

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

Прямого метода нет, но есть два обходных пути:

  1. Выгрузите таблицу базы в таблицу значений через запрос, затем объедините стандартными методами.
  2. Используйте временные таблицы в запросе:
    ВЫБРАТЬ ... ИЗ &ТаблицаЗначений ПОМЕСТИТЬ ВТВременная
    

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

    ВЫБРАТЬ ... ИЗ Справочник.Товары