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

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

НайтиСтроки в 1С: как работает поиск строк по отбору

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

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

Метод работает одинаково для объекта «ТаблицаЗначений», для табличных частей объектов конфигурации и для данных формы типа «ДанныеФормыТаблица». Различия касаются только типа возвращаемых элементов массива: для таблицы значений это строки таблицы значений, для табличной части — строки табличной части объекта.

Понимание того, как именно выполняется сравнение значений, критично: большинство ошибок с НайтиСтроки связано не с самим методом, а с несовпадением типов данных в отборе и в колонке таблицы. Далее разберём синтаксис, примеры, ограничения и типичные проблемы.

Синтаксис и принцип работы метода

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

Поиск выполняется по всем указанным в структуре условиям одновременно, то есть условия объединяются по логике «И». Если передать пустую структуру, метод вернёт все строки таблицы — это иногда используют для быстрого копирования строк в массив.

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

Пример поиска в таблице значений

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

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

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

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

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

КонецЦикла;

Если нужна только одна строка (например, по уникальному ключу), всё равно возвращается массив, и обращаться к результату нужно через индекс после проверки количества:

Если НайденныеСтроки.Количество() > 0 Тогда

СтрокаТовара = НайденныеСтроки[0];

Иначе

// строка не найдена — обработать ситуацию

КонецЕсли;

Поиск в табличной части документа

Для табличных частей метод работает аналогично. Например, нужно проверить, есть ли в документе «Реализация товаров» строки с определённой номенклатурой, и при необходимости увеличить количество, а не добавлять дубль:

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

Строки = ДокументОбъект.Товары.НайтиСтроки(Отбор);

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

Строки[0].Количество = Строки[0].Количество + 1;

Иначе

НоваяСтрока = ДокументОбъект.Товары.Добавить();

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

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

КонецЕсли;

Этот приём — стандартный способ избежать дублей строк при программном заполнении документов. Найденные строки являются ссылками на реальные строки табличной части, поэтому изменения в них сразу отражаются на объекте, дополнительно ничего «записывать обратно» не нужно.

Для управляемых форм метод доступен и у реквизита формы типа «ДанныеФормыТаблица», но найденные элементы там — объекты «ДанныеФормыЭлементКоллекции». Менять их можно напрямую, форма отобразит изменения автоматически.

Сравнение значений и проблема типов данных

Ключевое ограничение метода — строгое сравнение без приведения типов. Если в колонке хранится строка «001», а в отбор передать число 1, строка не будет найдена. Аналогично ссылка на элемент справочника не равна строке с наименованием этого элемента, даже если визуально они совпадают.

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

Типичные ошибки
01
Передача строкового представления вместо ссылки: поиск по наименованию товара в колонке типа СправочникСсылка ничего не найдёт
02
Поиск по числу в строковой колонке: "10" и 10 — разные значения, отбор не сработает
03
Опечатка в имени колонки структуры: метод вызовет исключение «Неверное имя колонки»
04
Ожидание Неопределено при отсутствии результата: метод возвращает пустой массив, а проверка на Неопределено всегда ложна
05
Изменение значений отбора прямо в отборе внутри цикла без пересоздания структуры — результаты становятся непредсказуемыми

Для дат тоже действует точное сравнение: дата с временем 10:30:00 не равна дате 00:00:00 того же дня. Если нужно искать по дате без времени, используйте функции НачалоДня() при формировании значения отбора или сравнивайте в цикле.

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

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

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

Маршрут решения

Как выбрать способ поиска

Нужно точное равенство по одной-двум колонкамИспользуйте НайтиСтроки со структурой отбора
Нужны условия «больше», «содержит», «в списке»Перебирайте строки в цикле с условием или используйте запрос к таблице значений
Поиск выполняется многократно по большой таблицеДобавьте индекс по колонкам отбора перед циклом поиска
Нужна только первая найденная строка по одному значениюРассмотрите метод Найти — он короче и возвращает строку или Неопределено

НайтиСтроки и метод Найти: в чём разница

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

Различие принципиально: Найти ищет только по одной колонке, а НайтиСтроки — по произвольному набору условий. Если условий несколько, но нужна лишь первая строка, используют НайтиСтроки и берут элемент [0] после проверки.

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

НайтиСтроки

Массив всех строк по множественному отбору. Подходит для обработки дублей и групп строк

Найти

Одна первая строка или Неопределено, поиск по одной колонке. Проще код для уникальных ключей

Запрос к таблице значений

Произвольные условия, группировки, сортировка. Тяжелее по коду, оправдан для сложной логики

Цикл с условием

Полная гибкость сравнения, но больше кода и выше риск ошибок

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

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

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

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

Количество найденных строк
Норма

НайденныеСтроки.Количество() больше 0

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

Пустой массив при гарантированно существующей строке — проверяйте типы и значения отбора

Тип значения в отборе
Норма

Тип совпадает с типом колонки (ссылка к ссылке, число к числу)

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

Передаётся строка вместо ссылки или число вместо строки

Имена ключей структуры
Норма

Ключи точно совпадают с именами колонок таблицы

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

Опечатка вызывает исключение «Неверное имя колонки»

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

Итог

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

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

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

Что возвращает НайтиСтроки, если ничего не найдено?

Пустой массив, а не Неопределено. Поэтому корректная проверка — НайденныеСтроки.Количество() = 0. Проверка на Неопределено не сработает и приведёт к ложной логике.

Можно ли искать по нескольким значениям одной колонки?

Напрямую — нет, отбор работает только на равенство одному значению. Варианты: несколько вызовов НайтиСтроки с объединением массивов, цикл с проверкой вхождения в список значений или запрос с условием «В».

Изменятся ли данные объекта, если изменить найденную строку?

Да. Элементы возвращаемого массива — это сами строки таблицы, а не их копии. Изменение свойств найденной строки сразу меняет табличную часть документа или таблицу значений.

Работает ли метод на клиенте в управляемой форме?

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

Как ускорить поиск при многократных вызовах?

Добавьте индекс по колонкам отбора: Таблица.Индексы.Добавить("ИмяКолонки"). Это оправдано, когда поисков много, а таблица большая. Для разового поиска индекс не нужен.

Учитывается ли регистр при сравнении строк?

Нет, сравнение строк в 1С регистронезависимое: «Товар» и «товар» считаются равными. Но учитываются пробелы, включая неразрывные, — это частая причина «неработающего» поиска.