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