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

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

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

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

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

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

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

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

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

Индексация строк начинается с нуля: первая строка — ТЗ[0], последняя — ТЗ[ТЗ.Количество() - 1]. Попытка обратиться к несуществующему индексу вызовет ошибку выполнения, поэтому перед прямым обращением стоит проверять количество строк.

Изменение строки по известному индексу

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

Если ТЗ.Количество() > 0 Тогда

СтрокаТЗ = ТЗ[0]; // первая строка

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

СтрокаТЗ.Сумма = СтрокаТЗ.Количество * СтрокаТЗ.Цена;

КонецЕсли;

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

Поиск и изменение строки по условию

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

Изменение одной строки через Найти()

НайденнаяСтрока = ТЗ.Найти(КодТовара, "Артикул");

Если НайденнаяСтрока <> Неопределено Тогда

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

Иначе

// строки с таким артикулом в таблице нет

КонецЕсли;

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

Изменение нескольких строк через НайтиСтроки()

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

Отбор = Новый Структура;

Отбор.Вставить("Склад", СкладОтгрузки);

Отбор.Вставить("Отгружено", Ложь);

НайденныеСтроки = ТЗ.НайтиСтроки(Отбор);

Для Каждого Строка Из НайденныеСтроки Цикл

Строка.Отгружено = Истина;

Строка.ДатаОтгрузки = ТекущаяДатаСеанса();

КонецЦикла;

Структура отбора поддерживает только сравнение на равенство. Если нужно условие вида «больше», «содержит» или комбинация ИЛИ — используйте полный перебор таблицы с проверкой внутри цикла.

Порядок действий
  1. 1
    Сформируйте структуру отбора с именами колонок и искомыми значениями
  2. 2
    Вызовите НайтиСтроки(Отбор) и получите массив строк
  3. 3
    Пройдите по массиву циклом и присвойте новые значения колонкам
  4. 4
    Проверьте результат: выведите изменённые строки или сравните итоги таблицы до и после

Изменение строк в цикле по произвольному условию

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

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

Если Строка.Количество >= 10 Тогда

Строка.Скидка = 10;

ИначеЕсли Строка.Количество >= 5 Тогда

Строка.Скидка = 5;

КонецЕсли;

Строка.Сумма = Строка.Количество Строка.Цена (100 - Строка.Скидка) / 100;

КонецЦикла;

Если внутри цикла нужно знать позицию строки, используйте цикл со счётчиком по индексам: Для Инд = 0 По ТЗ.Количество() - 1 Цикл. Это также единственный безопасный вариант, если в процессе обхода вы добавляете или удаляете строки таблицы — итератор «Для Каждого» в такой ситуации может пропустить элементы или обработать лишние.

Массовая замена значений и заполнение колонки

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

// Заполнить всю колонку одним значением

ТЗ.ЗаполнитьЗначения(ТекущаяДатаСеанса(), "ДатаОбработки");

// Заполнить только в строках, отобранных по условию

ТЗ.ЗаполнитьЗначения(Истина, "Проверено");

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

Сравнение вариантов

Обращение по индексу ТЗ[Инд]

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

Найти()

Одна строка по равенству значения колонки. Возвращает Неопределено, если ничего не найдено — проверка обязательна.

НайтиСтроки()

Несколько строк по отбору на равенство. Возвращает массив, удобен для пакетного изменения.

Цикл по таблице

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

ЗаполнитьЗначения()

Одно значение для всей колонки или части колонок. Не поддерживает условия и вычисления.

Типичные ошибки при изменении строк

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

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

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

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

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

Простейший способ — вывести изменённые данные сразу после присваивания: Сообщить(СтрокаТЗ.Сумма) или просмотреть таблицу в отладчике через «Вычислить выражение». В толстом клиенте и управляемом приложении удобно вывести таблицу на форму в элемент «Таблица» и визуально убедиться в результате.

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

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

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

Повторный поиск строки по новому значению
Норма

Найти() возвращает строку с обновлёнными данными

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

Возвращается Неопределено или старые значения — присваивание не сработало

Итог по изменяемой колонке
Норма

ТЗ.Итог() изменился на ожидаемую величину

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

Итог не изменился — обрабатывалась копия строки

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

Совпадает с ожиданием после обработки

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

Строк меньше или больше — в цикле шло удаление или добавление

FAQ

Нужно ли «записывать» строку обратно в таблицу после изменения?

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

Как изменить строку, если имя колонки хранится в переменной?

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

Как найти строку по условию «больше» или «содержит»?

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

Чем отличается изменение строки от изменения её копии?

Метод Скопировать() у строки создаёт новую независимую строку. Её изменение не влияет на исходную таблицу. Чтобы перенести изменения обратно, используйте ЗаполнитьЗначенияСвойств(ИсходнаяСтрока, ИзменённаяКопия).

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

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

Почему после Найти() возникает ошибка «Поле объекта не обнаружено»?

Метод вернул Неопределено, потому что строка с заданным значением не найдена, а код обратился к колонке без проверки. Всегда проверяйте результат: Если НайденнаяСтрока <> Неопределено Тогда.

Итог

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

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