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

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

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

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

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

Существует несколько способов записи данных: построчное добавление через метод Добавить(), массовая загрузка через Загрузить(), заполнение из результата запроса методом Выгрузить() и копирование структуры через Скопировать(). Выбор зависит от источника данных и требований к производительности.

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

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

Прежде чем записывать данные, нужно создать сам объект и описать его структуру. Таблица значений создаётся конструктором Новый ТаблицаЗначений, а колонки добавляются через коллекцию Колонки. Без явно созданных колонок обращение к полям строки вызовет ошибку «Поле объекта не обнаружено».

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

ТЗ.Колонки.Добавить("Номенклатура");

ТЗ.Колонки.Добавить("Количество");

ТЗ.Колонки.Добавить("Цена");

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

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

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

Имена колонок должны быть корректными идентификаторами: начинаться с буквы, не содержать пробелов и спецсимволов. Если имя сформировано динамически и может нарушать правила, обращаться к полю строки придётся через квадратные скобки, что усложняет код.

Построчная запись данных через Добавить()

Основной способ записи — добавление строки методом Добавить() и присвоение значений её полям. Метод возвращает ссылку на новую строку, которую сохраняют в переменную и сразу заполняют:

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

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("000000001");

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

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

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

Для Каждого СтрокаТЧ Из ДокументОбъект.Товары Цикл

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

НоваяСтрока.Номенклатура = СтрокаТЧ.Номенклатура;

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

КонецЦикла;

Если структуры колонок совпадают, перебор полей можно сократить через ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЧ) — функция скопирует значения одноимённых свойств. Это удобно, но работает медленнее прямых присваиваний при больших объёмах.

Порядок построчной записи
  1. 1
    Создайте таблицу: ТЗ = Новый ТаблицаЗначений
  2. 2
    Добавьте колонки через ТЗ.Колонки.Добавить() с нужными типами
  3. 3
    Вызовите Строка = ТЗ.Добавить() для каждой новой записи
  4. 4
    Присвойте значения полям строки через точку
  5. 5
    Проверьте результат: ТЗ.Количество() и содержимое первой строки

Массовая запись из результата запроса

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

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

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

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

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

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

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

При выгрузке запроса имена колонок таблицы совпадают с псевдонимами полей после КАК. Задавайте осмысленные псевдонимы сразу в тексте запроса — это избавит от переименования колонок в коде.
ПЗ
Практическое замечание

Загрузка данных методом Загрузить() и копирование таблиц

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

ТЗ.Очистить();

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

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

КопияТЗ = ТЗ.Скопировать(); // полная копия

Отбор = Новый Структура("Номенклатура", ИскомыйТовар);

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

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

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

Добавить() в цикле

Гибкий контроль над каждой строкой; медленнее на больших объёмах и требует ручного сопоставления полей

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

Самый быстрый вариант для данных из базы; структура колонок определяется запросом

Загрузить()

Подходит для табличных частей и массивов; не очищает таблицу, нужен вызов Очистить()

Скопировать()

Создаёт независимую копию с отбором; не подходит для первичного наполнения из внешних источников

Проверка результата и отладка

После записи данных полезно убедиться, что таблица заполнена ожидаемо. Минимальный набор проверок: количество строк через ТЗ.Количество(), наличие колонки через ТЗ.Колонки.Найти("ИмяКолонки") и содержимое конкретной строки через индекс ТЗ[0].

Для визуального контроля в отладчике используют табло: команда «Вычислить выражение» с вызовом ТЗ.ВыбратьСтроку() открывает таблицу в интерактивном окне (доступно в толстом клиенте и конфигураторе). В тонком клиенте таблицу можно вывести в сообщение, перебрав строки:

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

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

КонецЦикла;

Если таблица передаётся на форму как реквизит, проверьте, что реквизит формы имеет тип «ТаблицаЗначений» и колонки созданы либо в конфигураторе, либо программно через ИзменитьРеквизиты(). Без этого данные на форме не отобразятся, хотя в памяти будут присутствовать.

Контрольные точки

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

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

ТЗ.Количество() равно числу добавленных записей

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

Ноль — данные не записались; больше ожидаемого — задвоение из-за повторного Загрузить()

Значения полей
Норма

Поля строки содержат ожидаемые данные и типы

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

Неопределено или пустые значения — имена колонок не совпали с источником

Отображение на форме
Норма

Таблица видна в элементе формы

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

Пусто — реквизит формы не создан или не связан с элементом

Типичные ошибки при записи в таблицу значений

Частая ошибка — обращение к несуществующей колонке. Присваивание Строка.Цена = 100 при отсутствии колонки «Цена» вызывает исключение, и весь алгоритм прерывается. Перед циклом записи убедитесь, что структура колонок полностью описана.

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

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

Типичные ошибки
01
Запись в несозданную колонку — исключение «Поле объекта не обнаружено» и прерывание кода
02
Загрузить() без Очистить() — задвоение строк при повторном вызове
03
Сравнение ссылок из разных типов в отборе — НайтиСтроки() возвращает пустой массив
04
Наполнение таблицы в клиентском контексте управляемой формы — ошибки передачи данных между клиентом и сервером

Производительность и ограничения

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

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

Помните, что таблица значений — временная структура. Чтобы сохранить данные между сеансами, их нужно записать в базу: в регистр сведений, документ с табличной частью, справочник или хранилище значения. Сама по себе таблица исчезает при завершении сеанса или закрытии формы.

Итог

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

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

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

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

Используйте обращение через квадратные скобки: Строка[ИмяКолонки] = Значение, где ИмяКолонки — строковая переменная. Сначала проверьте наличие колонки через ТЗ.Колонки.Найти(ИмяКолонки), чтобы избежать исключения.

Почему после Загрузить() в таблице вдвое больше строк, чем ожидалось?

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

Как записать данные из таблицы значений в регистр сведений?

Создайте набор записей регистра, установите отбор при необходимости, затем в цикле перенесите строки: НоваяЗапись = Набор.Добавить() с присваиванием полей из строки таблицы. Завершите вызовом Набор.Записать(). Для больших объёмов используйте Набор.Загрузить(ТЗ) при совпадении имён полей.

Можно ли заполнить таблицу значений на клиенте в управляемой форме?

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

Как удалить дубли строк после записи данных?

Используйте свёртку: ТЗ.Свернуть("Колонка1,Колонка2", "СуммируемаяКолонка"). Метод сгруппирует строки по перечисленным колонкам и просуммирует числовые. Если суммировать нечего, укажите второй параметр пустым — останутся уникальные комбинации.

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

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