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

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

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

Как загрузить данные в таблицу значений в 1С: заполнение из запроса, обходом строк, из Excel и CSV, выгрузка из табличной части. Примеры кода, ошибки и проверка результата.

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

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

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

Создание таблицы значений и описание колонок

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

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

ТЗ.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

ТЗ.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));

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

Загрузка из результата запроса

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

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

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

"ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| СУММА(Товары.Количество) КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

|СГРУППИРОВАТЬ ПО

| Товары.Номенклатура";

Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));

Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДатаСеанса()));

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

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

Обратный приём — передать готовую таблицу значений в запрос как параметр и поместить её во временную таблицу. Это стандартный способ соединить загруженные извне данные (например, из Excel) с данными информационной базы без построчных поисков в цикле:

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

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

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

"ВЫБРАТЬ

| ВТ.Артикул КАК Артикул,

| ВТ.Цена КАК Цена

|ПОМЕСТИТЬ ВТ_Данные

|ИЗ

| &ТЗ КАК ВТ";

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

Запрос.Выполнить();

Построчное заполнение в цикле

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

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

Пока Выборка.Следующий() Цикл

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

НоваяСтрока.Номенклатура = Выборка.Номенклатура;

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

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

КонецЦикла;

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

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

Загрузка из табличной части и между таблицами значений

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

ТЗ = ДокументОбъект.Товары.Выгрузить();

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

ДокументОбъект.Товары.Загрузить(ТЗ);

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

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

Загрузка из Excel и CSV

Для загрузки из внешних файлов таблицу значений создают вручную, а затем читают файл построчно. Текстовые файлы CSV читаются через ЧтениеТекста с разбором строки по разделителю. Файлы Excel обычно читают через построитель табличного документа (ТабличныйДокумент.Прочитать()) либо через COM-объект Excel на сервере Windows — второй способ медленнее и требует установленного Excel.

Чтение = Новый ЧтениеТекста(ИмяФайла, КодировкаТекста.UTF8);

СтрокаФайла = Чтение.ПрочитатьСтроку(); // пропускаем заголовок

СтрокаФайла = Чтение.ПрочитатьСтроку();

Пока СтрокаФайла <> Неопределено Цикл

Части = СтрРазделить(СтрокаФайла, ";");

Если Части.Количество() >= 3 Тогда

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

НоваяСтрока.Артикул = СокрЛП(Части[0]);

НоваяСтрока.Количество = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(Части[1]);

НоваяСтрока.Цена = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(Части[2]);

КонецЕсли;

СтрокаФайла = Чтение.ПрочитатьСтроку();

КонецЦикла;

Чтение.Закрыть();

Главная сложность при загрузке из файлов — преобразование типов. Все значения из файла приходят строками, поэтому числа, даты и ссылки нужно конвертировать явно. Строку «12 345,67» с неразрывным пробелом функция преобразования не поймёт без предварительной очистки. Ссылки на справочники ищут по коду, артикулу или наименованию; если элемент не найден, решайте заранее: создавать новый, пропускать строку или собирать ошибки в отдельную таблицу для отчёта пользователю.

Порядок загрузки файла в таблицу значений
  1. 1
    Создайте таблицу значений и опишите колонки с типами
  2. 2
    Откройте файл и прочитайте первую строку-заголовок, сверьте порядок колонок
  3. 3
    В цикле читайте строки, разбивайте по разделителю и очищайте значения от пробелов
  4. 4
    Преобразуйте строки в числа, даты и ссылки с контролем ошибок
  5. 5
    Проверьте количество загруженных строк и число пропущенных
  6. 6
    При необходимости передайте таблицу в запрос для сопоставления с данными базы

Загрузка без программирования: типовые обработки

Если нужно разово загрузить данные в табличную часть документа или справочник без доработки конфигурации, используйте универсальные обработки. В конфигурациях на БСП (УТ, ERP, КА, БП) есть «Загрузка данных из табличного документа»: она открывает файл Excel, сопоставляет колонки с реквизитами и заполняет табличную часть. Для управляемых форм также работает вставка из буфера обмена в табличную часть — данные копируются из Excel и вставляются прямо в строки документа.

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

Сравнение способов загрузки

Выгрузить() из запроса

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

Построчное добавление в цикле

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

Выгрузить()/Загрузить() табличной части

Удобен для обработки данных документа: свертка, сортировка, расчёты. Требует контроля служебных полей.

Типовые обработки загрузки

Без программирования, для пользователей. Ограничены сценариями загрузки в объекты базы.

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

После загрузки убедитесь, что таблица содержит ожидаемые данные. Минимальная проверка — количество строк (ТЗ.Количество()) и выборочный контроль нескольких значений. В отладчике таблица значений просматривается через «Вычислить выражение» с включённым показом коллекции. Для вывода пользователю таблицу можно показать в табличном документе или на форме через реквизит типа «ТаблицаЗначений».

Контрольные точки: совпадает ли число строк с количеством строк источника минус заголовок и отбракованные записи; не пустые ли ключевые колонки; корректно ли распознаны числа и даты (дата «01.02.03» могла уехать не в тот век). Если таблица передаётся в запрос — проверьте, что имена и типы колонок совпадают с полями текста запроса.

Типичные ошибки
01
Колонки без описания типов — при передаче таблицы в запрос возникает ошибка или неверные сравнения типов
02
Числа из файла не преобразованы из строк — сортировка и итоги работают как для текста, «10» оказывается раньше «2»
03
Загрузить() табличной части после свертки с потерей ключей связи — документ не проводится или теряет связанные строки
04
Разделитель CSV не совпадает с фактическим (точка с запятой вместо запятой) — вся строка попадает в одну колонку
05
Не очищены неразрывные пробелы и лишние символы — ссылки не находятся, числа не преобразуются
06
Отсутствие подсчёта пропущенных строк — пользователь не узнает, что часть данных не загрузилась
Контрольные точки

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

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

ТЗ.Количество() равно числу строк источника за вычетом заголовка и отбракованных

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

Строк меньше, а протокола пропусков нет — данные потеряны молча

Типы колонок
Норма

Числа и даты имеют соответствующий тип, итоги по колонкам считаются

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

Значения строковые, Свернуть() складывает текст вместо чисел

Ключевые поля
Норма

Ссылочные колонки заполнены найденными элементами

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

Пустые ссылки там, где элемент должен был найтись

Итог

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

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

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

Чем таблица значений отличается от дерева значений?

Таблица значений — плоский набор строк и колонок. Дерево значений поддерживает иерархию: у каждой строки могут быть подчинённые строки. Из запроса дерево получают методом Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам). Для большинства задач загрузки достаточно таблицы значений.

Как удалить дубли строк в таблице значений?

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

Можно ли отсортировать таблицу значений?

Да, методом Сортировать("Колонка1 Возр, Колонка2 Убыв"). Сортировка выполняется в памяти и работает корректно только при правильных типах колонок: строковые числа сортируются по алфавиту, а не по значению.

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

Напрямую таблица значений не сериализуется для передачи. На управляемых формах используют реквизит формы типа «ТаблицаЗначений» — платформа сама переносит данные. Для передачи вне формы таблицу преобразуют в массив структур или помещают во временное хранилище через ЗначениеВСтрокуВнутр.

Как найти строку в таблице значений?

Методом Найти(Значение, "ИмяКолонки") — возвращает первую подходящую строку или Неопределено. Для поиска по нескольким условиям используйте НайтиСтроки(Отбор) со структурой отбора — метод вернёт массив всех подходящих строк. Для ускорения поиска в больших таблицах добавьте индекс: ТЗ.Индексы.Добавить("Артикул").

Почему запрос ругается на таблицу значений в параметре?

Чаще всего причина в колонках без явного типа или в именах колонок, не совпадающих с полями текста запроса. Опишите типы через ОписаниеТипов при создании колонок и проверьте, что в тексте запроса обращение идёт к тем же именам, что и в таблице.