Справочники и Данные · 13 мин
Как получить данные из справочника в 1С
Как получить данные из справочника 1С: поиск по коду и наименованию, запросы, обход элементов, получение реквизитов. Примеры кода на встроенном языке 1С.
Справочники в 1С хранят нормативно-справочную информацию: номенклатуру, контрагентов, сотрудников, склады, договоры. Практически любая доработка — от простой обработки до сложного отчёта — начинается с чтения данных из справочника. Способ получения данных зависит от задачи: иногда достаточно найти один элемент по коду, иногда нужно выбрать тысячи записей с отбором и сортировкой.
Во встроенном языке 1С есть три основных подхода: методы менеджера справочника (НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту), выборка через Выбрать() и язык запросов. Каждый подходит для своих сценариев и отличается по скорости и гибкости.
Ниже разобраны все три способа с готовыми примерами кода, типичные ошибки и рекомендации по выбору. Примеры приведены для обычных и управляемых форм — синтаксис одинаков, различия касаются только контекста выполнения (клиент или сервер).
Как устроено обращение к справочнику
Работа со справочником начинается с менеджера — объекта, который возвращает конструкция Справочники.ИмяСправочника. Например, Справочники.Номенклатура или Справочники.Контрагенты. Через менеджер доступны методы поиска, создания и выборки элементов.
Результатом поиска является ссылка — объект типа СправочникСсылка. Сама по себе ссылка содержит только уникальный идентификатор и минимум данных (код, наименование). Чтобы прочитать произвольный реквизит, нужно либо обратиться к реквизиту через точку (при этом платформа неявно считывает объект из базы), либо получить объект методом ПолучитьОбъект(), либо выбрать данные запросом.
Важно понимать: обращение к реквизиту через ссылку (Элемент.Артикул) выполняет отдельное обращение к базе данных. В цикле по тысяче элементов это даёт тысячу обращений и заметно тормозит код — в таких случаях правильнее использовать запрос.
Поиск элемента по коду, наименованию и реквизиту
Самая частая задача — найти конкретный элемент по известному значению. Менеджер справочника предоставляет три метода поиска:
НайтиПоКоду(Код)— поиск по коду элемента;НайтиПоНаименованию(Наименование, ТочноеСоответствие)— поиск по наименованию;НайтиПоРеквизиту(ИмяРеквизита, Значение)— поиск по любому реквизиту.
Пример поиска контрагента по ИНН (реквизит) и проверки результата:
НайденныйЭлемент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");
Если НайденныйЭлемент.Пустая() Тогда
Сообщить("Контрагент с таким ИНН не найден");
Иначе
Сообщить("Найден: " + НайденныйЭлемент.Наименование);
КонецЕсли;
Если элемент не найден, метод возвращает пустую ссылку. Проверка через Пустая() обязательна — обращение к реквизитам пустой ссылки вернёт значения по умолчанию, и ошибку можно не заметить.
При поиске по наименованию второй параметр отвечает за точное соответствие. По умолчанию он равен Ложь, и поиск идёт по вхождению строки — это может вернуть не тот элемент. Для надёжности передавайте Истина:
Группа = Справочники.Номенклатура.НайтиПоНаименованию("Услуги", Истина);
Обход элементов справочника через Выбрать()
Метод Выбрать() возвращает выборку, которую можно перебрать в цикле. Он принимает параметры: родитель (для иерархических справочников), владелец (для подчинённых), отбор и порядок сортировки.
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.ЭтоГруппа Тогда
Продолжить;
КонецЕсли;
Сообщить(Выборка.Код + " — " + Выборка.Наименование);
КонецЦикла;
Для иерархических справочников выборка включает и группы, и элементы. Признак ЭтоГруппа позволяет их различать. Если нужны только элементы конкретной папки, передайте её ссылку первым параметром: Справочники.Номенклатура.Выбрать(ГруппаТоваров).
У способа есть ограничение: отбор в Выбрать() работает только по реквизитам, для которых в конфигураторе включено индексирование, и набор условий ограничен. Для сложных отборов, соединений с другими таблицами и агрегации используйте запрос.
Получение данных запросом
Язык запросов 1С — основной инструмент чтения данных, когда нужно выбрать много элементов, отфильтровать их по произвольным условиям или получить сразу несколько реквизитов. Запрос выполняется одним обращением к СУБД и работает значительно быстрее цикла с обращением к реквизитам через ссылку.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления
| И НЕ Номенклатура.ЭтоГруппа
|УПОРЯДОЧИТЬ ПО
| Наименование";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Артикул + " — " + Выборка.Наименование);
КонецЦикла;
Обратите внимание на фильтр НЕ ПометкаУдаления: запрос по умолчанию возвращает и помеченные на удаление элементы. Если забыть этот отбор, в обработку попадут «мёртвые» записи, что исказит отчёты и выгрузки.
Для передачи условий используйте параметры, а не конкатенацию строк — это защищает от ошибок синтаксиса и упрощает поддержку:
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ ИНН = &ИНН";
Запрос.УстановитьПараметр("ИНН", "7707083893");
Чтение табличных частей элемента
У элементов справочников могут быть табличные части — например, «Единицы измерения» у номенклатуры или «Контактная информация» у контрагентов. Прочитать их через ссылку напрямую нельзя: нужен объект или запрос.
Через объект это выглядит так:
ОбъектКонтрагента = СсылкаКонтрагент.ПолучитьОбъект();
Для Каждого СтрокаКИ Из ОбъектКонтрагента.КонтактнаяИнформация Цикл
Сообщить(СтрокаКИ.Вид + ": " + СтрокаКИ.Представление);
КонецЦикла;
То же самое запросом — быстрее и без загрузки всего объекта в память:
Запрос.Текст =
"ВЫБРАТЬ
| КИ.Вид КАК Вид,
| КИ.Представление КАК Представление
|ИЗ
| Справочник.Контрагенты.КонтактнаяИнформация КАК КИ
|ГДЕ
| КИ.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаКонтрагент);
В типовых конфигурациях контактная информация часто хранится в отдельных регистрах сведений, а не в табличной части. Перед написанием кода откройте конфигуратор и проверьте, где физически лежат нужные данные у вашей версии конфигурации.
Сравнение способов получения данных
| Способ | Когда применять | Ограничения |
|---|---|---|
| НайтиПоКоду / НайтиПоНаименованию | Поиск одного известного элемента | Возвращает один элемент; наименование не уникально |
| НайтиПоРеквизиту | Поиск по ИНН, артикулу, штрихкоду | Без индекса по реквизиту поиск медленный |
| Выбрать() | Простой обход с фильтром по родителю или владельцу | Ограниченные отборы, по одному обращению на элемент |
| Запрос | Сложные отборы, соединения, большие объёмы, отчёты | Требует знания языка запросов |
| ПолучитьОбъект() | Изменение и запись элемента, чтение табличных частей | Загружает весь объект в память; не для массового чтения |
Как выбрать способ
Частые ошибки и как их избежать
Первая и самая массовая ошибка — обращение к реквизитам через ссылку внутри цикла. Конструкция Выборка.Ссылка.Артикул в цикле по тысяче элементов выполняет тысячу запросов к базе. Решение — выбрать все нужные поля одним запросом.
Вторая ошибка — отсутствие проверки найденного элемента. Если НайтиПоНаименованию вернул пустую ссылку, а код продолжает работать, дальше возникают трудно диагностируемые сбои: пустые значения в документах, обрывы обменов. Всегда проверяйте результат через Пустая() или ЗначениеЗаполнено().
Третья группа ошибок связана с контекстом выполнения. На управляемых формах код с директивой &НаКлиенте не имеет доступа к менеджерам справочников — обращение к Справочники.Номенклатура вызовет ошибку. Чтение данных выполняйте в серверных процедурах (&НаСервере или &НаСервереБезКонтекста).
Как проверить, что данные получены правильно
После написания кода проверьте результат на контрольных примерах. Откройте элемент справочника в режиме предприятия и сравните значения реквизитов с тем, что вывела ваша обработка. Для запроса удобно сначала отладить текст в консоли запросов — это штатная обработка, которую легко найти в поставке или в типовых инструментах разработчика.
Как проверить результат
Пустая() возвращает Ложь, ссылка открывается в режиме предприятия
Пустая() возвращает Истина — значение поиска не совпало с данными
Количество строк совпадает с числом элементов в списке справочника с теми же отборами
Строк больше — попали помеченные на удаление или группы
Совпадают с данными формы элемента
Пустые или устаревшие значения — читается не тот реквизит или кэш
Обработка тысячи элементов занимает секунды
Обработка идёт минутами — в цикле есть обращения к базе через ссылку
Дополнительный приём — замер производительности через ТекущаяУниверсальнаяДатаВМиллисекундах() до и после выборки. Если замена цикла с обращениями через ссылку на один запрос сокращает время в десятки раз, вы на верном пути.
Что важно запомнить
Один элемент ищите методами НайтиПоКоду, НайтиПоНаименованию или НайтиПоРеквизиту и всегда проверяйте результат на пустую ссылку. Массовое чтение реквизитов делайте запросом — это одно обращение к базе. В запросах фильтруйте пометку удаления, а в управляемых формах выполняйте чтение на сервере.
Частые вопросы
Как получить элемент справочника по GUID?
Используйте конструкцию: Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор("строка-guid")). Метод не проверяет существование элемента — чтобы убедиться, что элемент реально есть в базе, выполните запрос по полученной ссылке или проверьте любой реквизит. Это стандартный способ обмена между базами, где коды не синхронизированы.
Как получить все элементы справочника без отбора?
Проще всего запросом: ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Номенклатура. Альтернатива — Выбрать() без параметров с циклом по выборке. Для больших справочников предпочтителен запрос: он быстрее и позволяет сразу исключить помеченные на удаление и группы.
Почему НайтиПоНаименованию ничего не находит, хотя элемент есть?
Частые причины: лишние пробелы или неразрывные пробелы в наименовании, разный регистр букв в некоторых СУБД, элемент помечен на удаление, поиск выполняется с точным соответствием, а строки отличаются. Скопируйте наименование прямо из формы элемента и попробуйте поиск без второго параметра.
Можно ли получить данные справочника без программирования?
Да. Список справочника можно вывести в табличный документ через «Ещё → Вывести список» в типовых конфигурациях. Гибкие выборки с отборами даёт универсальный отчёт или произвольный отчёт на СКД. Этого достаточно для разовой выгрузки в Excel без написания кода.
Как обратиться к предопределённому элементу справочника?
Через менеджер по имени, заданному в конфигураторе: Справочники.Валюты.Рубль — если элемент с таким именем предопределён. Универсальный способ получить имя предопределённого элемента по ссылке — функция ОбщегоНазначения.ПредопределенныйЭлемент() в конфигурациях на БСП или запрос вида ВЫБРАТЬ Ссылка ИЗ Справочник.Валюты ГДЕ Предопределенный.
Чем опасен ПолучитьОбъект() при массовом чтении?
Метод загружает в память весь объект со всеми табличными частями и блокирует его для конкурентного изменения в некоторых сценариях. В цикле по тысячам элементов это даёт огромный расход памяти и времени. Для чтения используйте запрос; ПолучитьОбъект() оправдан только когда элемент нужно изменить и записать.