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

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

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

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

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

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

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

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

Каждая строка таблицы — это объект типа «СтрокаТаблицыЗначений». Доступ к значениям идёт по имени колонки (Строка.Номенклатура) или через квадратные скобки со строковым именем (Строка["Номенклатура"]). Второй вариант удобен, когда имя колонки хранится в переменной.

Добавление строки в конец таблицы методом Добавить()

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

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

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

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

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

НоваяСтрока.Номенклатура = "Кабель ВВГ 3х2,5";

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

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

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

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

Вставка строки в произвольную позицию методом Вставить()

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

// Вставка строки на вторую позицию

НоваяСтрока = ТЗ.Вставить(1);

НоваяСтрока.Номенклатура = "Приоритетная позиция";

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

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

Заполнение строки данными и копирование существующих строк

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

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

ЗаполнитьЗначенияСвойств(НоваяСтрока, ИсходнаяСтрока);

Этот приём удобен при дублировании строк с небольшими изменениями: скопировали значения, затем переопределили одно-два поля. Учтите, что ЗаполнитьЗначенияСвойств копирует только свойства с совпадающими именами; колонки, которых нет в источнике, останутся со значениями по умолчанию.

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

Добавление строк в таблицу значений на форме и в табличную часть

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

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

Сравнение способов наполнения

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

Универсально и читаемо; подходит для большинства обработок. Требует аккуратности со ссылкой на строку внутри цикла.

Вставить(Индекс)

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

Загрузить(ТЗ)

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

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

Создаёт новую таблицу с той же структурой и данными. Не добавляет строки в существующую таблицу, а формирует отдельную.

Типичные ошибки и как их проверить

Первая группа ошибок связана с колонками: обращение к колонке, которую забыли добавить, приводит к исключению «Поле объекта не обнаружено». Перед заполнением убедитесь, что колонка описана, — программно это проверяется через ТЗ.Колонки.Найти("ИмяКолонки").

Вторая группа — работа с индексами. Метод Вставить() с отрицательным индексом или индексом больше количества строк завершится ошибкой. Если позиция вычисляется динамически, например через ТЗ.Индекс(НайденнаяСтрока), учтите: когда строка не найдена, Индекс() возвращает -1, и передавать это значение в Вставить() нельзя без проверки.

Третья типичная ситуация — модификация таблицы во время её перебора циклом Для Каждого. Добавление строк внутри такого цикла приведёт к обработке и новых строк, что часто даёт бесконечный или некорректный цикл. Безопасный приём — собирать новые строки во временную таблицу, а после цикла переносить их в основную.

Типичные ошибки
01
Вызов Добавить() один раз вне цикла — все итерации перезаписывают одну строку, в таблице остаётся только последняя запись
02
Обращение к колонке, не добавленной в таблицу, — ошибка «Поле объекта не обнаружено»
03
Передача в Вставить() индекса -1 из метода Индекс(), когда строка не найдена, — ошибка исполнения
04
Добавление строк в таблицу внутри цикла Для Каждого по этой же таблице — обработка лишних строк или зацикливание
05
Ожидание, что таблица значений сохранится в базе — данные теряются после завершения кода, их нужно перенести в табличную часть или регистр
Контрольные точки

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

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

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

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

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

Позиция вставленной строки
Норма

ТЗ.Индекс(НоваяСтрока) возвращает нужную позицию

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

Строка оказалась в конце или в начале — перепутан порядок аргументов или использован Добавить() вместо Вставить()

Значения в колонках
Норма

Поля заполнены данными нужного типа

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

Пустые значения или ноль — колонка не заполнена либо тип колонки отсек переданное значение

Производительность при массовом добавлении строк

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

Для ускорения поиска по большой таблице создайте индекс: ТЗ.Индексы.Добавить("Номенклатура"). После этого методы Найти() и НайтиСтроки() по индексированной колонке выполняются существенно быстрее. Индексы оправданы, когда поиск выполняется многократно; для однократного прохода затраты на построение индекса могут не окупиться.

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

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

Чем отличается Добавить() от Вставить() в таблице значений?

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

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

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

Как вставить строку после найденной?

Найдите строку через Найти() или НайтиСтроки(), получите её позицию методом ТЗ.Индекс(НайденнаяСтрока) и вызовите Вставить(Индекс + 1). Перед вставкой проверьте, что строка действительно найдена, иначе Индекс() вернёт -1 и произойдёт ошибка.

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

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

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

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

Как удалить ошибочно добавленную строку?

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

Итог

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

Строки в таблицу значений 1С добавляются методом Добавить() в конец или Вставить(Индекс) в нужную позицию; оба возвращают строку для заполнения колонок. Перед работой опишите колонки, вызывайте Добавить() внутри цикла, проверяйте индексы и помните, что таблица значений хранится только в памяти.