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