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

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

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

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

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

Разработчику важно различать поиск на стороне клиента (перебор данных, уже загруженных в память) и поиск на стороне сервера или СУБД (запрос к базе). Первый вариант проще в написании, но не масштабируется: перебор миллиона строк в цикле займёт заметное время. Второй требует знания языка запросов, зато выполняется быстро даже на больших объёмах.

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

Определите, с какой таблицей вы работаете

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

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

Найдите строки методом НайтиСтроки

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

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

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

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

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

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

КонецЦикла;

Если нужна только одна строка, удобнее метод Найти(Значение, ИмяКолонки) — он вернёт первую найденную строку или Неопределено, если совпадений нет. Всегда проверяйте результат на Неопределено перед обращением к полям строки, иначе получите ошибку выполнения.

Важная особенность: сравнение значений выполняется по строгому равенству с учётом типа. Число 100 и строка «100» — разные значения, и поиск не сработает. Если тип колонки не совпадает с типом искомого значения, приведите их к одному типу заранее.

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

Используйте цикл для сложных условий поиска

Метод НайтиСтроки() поддерживает только равенство. Если условие сложнее — диапазон значений, частичное совпадение строки, сравнение нескольких полей по «ИЛИ» — нужен перебор в цикле с проверкой условия внутри.

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

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

И СтрНайти(Строка.Наименование, "кабель") > 0 Тогда

// строка подходит под условие

КонецЕсли;

КонецЦикла;

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

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

Выполните поиск через запрос к базе данных

Когда данные хранятся в информационной базе — регистрах, справочниках, документах — искать их перебором объектов крайне неэффективно. Правильный инструмент — запрос с условием ГДЕ. Запрос выполняется на сервере СУБД и возвращает только нужные строки.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура,

| Товары.Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка

| И Товары.Номенклатура = &Номенклатура";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

Запрос.УстановитьПараметр("Номенклатура", ИскомаяНоменклатура);

Результат = Запрос.Выполнить().Выгрузить();

Для поиска по части строки в запросе используется оператор ПОДОБНО с шаблоном: символ % означает любую последовательность символов. Например, условие Наименование ПОДОБНО "%кабель%" найдёт все позиции, где слово встречается в любом месте наименования.

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

Сравнение способов поиска

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

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

Перебор циклом

Универсален, поддерживает любые условия. Медленнее на больших таблицах и требует больше кода.

Запрос с ГДЕ

Единственный правильный способ поиска по данным базы. Требует знания языка запросов, но масштабируется на любые объёмы.

Отбор динамического списка

Используется для поиска в формах списков. Не подходит для программной обработки данных.

Настройте поиск в динамическом списке и на форме

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

Программная установка отбора в управляемой форме выглядит так: нужно добавить элемент в Список.Отбор.Элементы, указать поле, вид сравнения и значение. Для поиска по подстроке используется вид сравнения «Содержит». Изменение отбора автоматически обновляет отображаемые строки.

Если речь идёт не о программировании, а о повседневной работе пользователя, в большинстве форм списков доступна строка поиска (обычно вызывается сочетанием Ctrl+F или кнопкой «Найти» на панели). Поиск выполняется по текущей колонке или по всем отображаемым колонкам в зависимости от настроек формы. Также доступен отбор по значению в текущей ячейке — команда «Найти: по текущему значению» в меню «Ещё» или по кнопке на панели.

Пользователи часто не находят строку в списке из-за уже установленного отбора: список показывает только часть данных. Перед поиском проверьте панель отборов и сбросьте лишние условия — это самая частая причина «пропавших» записей.
ПЗ
Практическое замечание

Проверьте результат и избегайте типичных ошибок

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

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

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

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

Результат НайтиСтроки()
Норма

Массив с нужным количеством строк, поля строк доступны

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

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

Результат Найти()
Норма

Строка или Неопределено с корректной обработкой обоих случаев

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

Ошибка выполнения при обращении к полям — значит проверка на Неопределено отсутствует

Результат запроса
Норма

Выборка содержит ожидаемые строки, параметры запроса заполнены

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

Пустая выборка — проверьте условия ГДЕ и значения параметров

Частые вопросы о поиске строк в 1С

Чем НайтиСтроки() отличается от Найти()?

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

Как найти строку по части наименования в таблице значений?

НайтиСтроки() не поддерживает поиск по подстроке. Используйте перебор в цикле с функцией СтрНайти(): если СтрНайти(НРег(Строка.Наименование), НРег("фрагмент")) > 0, строка подходит. Перевод в нижний регистр делает поиск независимым от регистра символов.

Почему НайтиСтроки() не находит строку, которая точно есть?

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

Можно ли искать строки в динамическом списке программно?

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

Что быстрее: НайтиСтроки() или перебор циклом?

Для условий на равенство НайтиСтроки() обычно удобнее и не медленнее. Цикл оправдан, когда условие сложное: неравенства, поиск подстроки, логика «ИЛИ». На небольших таблицах разница в производительности незаметна, выбирайте по читаемости кода.

Как пользователю найти запись в списке без программирования?

Откройте форму списка и воспользуйтесь командой «Найти» (обычно Ctrl+F) или полем поиска на панели. Для отбора по конкретному значению установите курсор в ячейку и выберите «Найти: по текущему значению». Если запись не находится, проверьте, не установлены ли в списке отборы, скрывающие часть данных.

Итог

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

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