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

Справочники и Данные · 10 мин

1С: как выбрать справочник — полное руководство

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

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

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

Как выбрать справочник в интерфейсе 1С

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

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

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

Как программно получить выборку элементов справочника

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

Выборка = Справочники.Номенклатура.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Наименование);

КонецЦикла;

У метода Выбрать() есть параметры: Родитель, Владелец, Отбор и Порядок. Все они необязательны. Вызов без параметров вернёт все элементы справочника, включая помеченные на удаление, — это важно помнить, потому что именно здесь кроется одна из самых частых ошибок.

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

Отбор по родителю, владельцу и произвольным полям

Для иерархических справочников первый параметр Выбрать() ограничивает выборку элементами конкретной группы. Например, Справочники.Номенклатура.Выбрать(ГруппаТоваров) вернёт только элементы, лежащие непосредственно в этой группе, — без вложенных подгрупп. Чтобы получить и подгруппы, нужен либо рекурсивный обход, либо запрос с оператором В ИЕРАРХИИ.

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

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

Выбор справочника через запрос

Язык запросов — основной инструмент, когда нужны условия, соединения с другими таблицами или группировки. Запрос к справочнику строится конструкцией ВЫБРАТЬ ... ИЗ Справочник.ИмяСправочника с необязательным блоком ГДЕ.

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

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

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления

| И Номенклатура.Родитель = &Родитель";

Запрос.УстановитьПараметр("Родитель", ГруппаТоваров);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Наименование);

КонецЦикла;

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

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

Выбрать() или запрос

Метод Выбрать()

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

Запрос

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

НайтиПоНаименованию / НайтиПоКоду

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

Как изменить элементы при обходе и не испортить данные

Выборка даёт доступ к данным элемента, но для изменения нужно получить объект: ЭлементОбъект = Выборка.Ссылка.ПолучитьОбъект(). После изменения реквизитов вызовите Записать(). Вызов ПолучитьОбъект() загружает элемент в память целиком — на больших выборках это главный потребитель времени и памяти.

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

Частые ошибки при выборе справочника

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

Вторая ошибка — игнорирование пометки удаления. Выборка по умолчанию включает помеченные элементы, и они попадают в обработку, отчёты и выгрузки. Добавляйте условие НЕ ПометкаУдаления в запрос или проверку внутри цикла.

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

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

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

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

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

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

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

Количество элементов в выборке
Норма

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

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

Выборка пуста или содержит заметно больше элементов, чем ожидалось

Пометка удаления
Норма

Помеченные элементы исключены условием или проверкой

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

В обработку попадают элементы с пометкой удаления

Состав отбора
Норма

Все элементы принадлежат нужному родителю или владельцу

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

В выборке элементы из других групп или других владельцев

FAQ

Как выбрать элементы справочника вместе с подгруппами?

Метод Выбрать(Родитель) возвращает только прямых «потомков» группы. Чтобы включить вложенные подгруппы, используйте запрос с условием Родитель В ИЕРАРХИИ(&Группа) — оператор В ИЕРАРХИИ учитывает всю вложенность автоматически.

Чем Выбрать() отличается от НайтиПоНаименованию()?

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

Почему отбор в Выбрать() выдаёт ошибку?

Чаще всего потому, что реквизит, по которому строится отбор, не индексирован. Откройте конфигуратор, найдите реквизит справочника и проверьте свойство «Индексировать». Либо перенесите условие в запрос, где индексация не обязательна.

Как исключить помеченные на удаление элементы?

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

Можно ли выбрать справочник, подчинённый другому справочнику, без владельца?

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

Что быстрее: Выбрать() или запрос?

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

Итог

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

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