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