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