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

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

Как получить объект справочника в 1С

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

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

Встроенный язык 1С предоставляет несколько способов получить элемент справочника: поиск по коду, по наименованию, по произвольному реквизиту, а также получение объекта по уже известной ссылке. У каждого способа есть свои условия применения, ограничения и подводные камни, связанные с производительностью и правами доступа.

Ссылка и объект: в чём разница и почему это важно

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

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

Поиск элемента по коду и наименованию

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

// Поиск контрагента по коду

СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоКоду("000000123");

Если СсылкаКонтрагент.Пустая() Тогда

Сообщить("Элемент не найден");

Иначе

ОбъектКонтрагент = СсылкаКонтрагент.ПолучитьОбъект();

КонецЕсли;

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

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

Поиск по реквизиту и получение объекта по ссылке

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

// Поиск контрагента по ИНН

СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");

// Получение объекта по уже известной ссылке

Если Не СсылкаКонтрагент.Пустая() Тогда

ОбъектКонтрагент = СсылкаКонтрагент.ПолучитьОбъект();

ОбъектКонтрагент.Комментарий = "Проверен";

ОбъектКонтрагент.Записать();

КонецЕсли;

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

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

bsl
СсылкаНоменклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", "АРТ-1001");
Если Не СсылкаНоменклатура.Пустая() Тогда
    ОбъектНоменклатура = СсылкаНоменклатура.ПолучитьОбъект();
    ОбъектНоменклатура.Записать();
КонецЕсли;

Выборка элементов и создание нового элемента

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

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

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

Если Не Выборка.ЭтоГруппа Тогда

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

КонецЕсли;

КонецЦикла;

Для создания нового элемента используются методы СоздатьЭлемент() и СоздатьГруппу(). Они сразу возвращают объект, который заполняется реквизитами и записывается. Перед созданием элемента программно рекомендуется проверить, не существует ли уже такой элемент, иначе в справочнике накопятся дубли.

Порядок действий при изменении элемента
  1. 1
    Найдите ссылку элемента через НайтиПоКоду, НайтиПоНаименованию или НайтиПоРеквизиту
  2. 2
    Проверьте результат: ссылка не должна быть пустой
  3. 3
    Вызовите ПолучитьОбъект() у найденной ссылки
  4. 4
    Измените нужные реквизиты объекта
  5. 5
    Вызовите Записать() и убедитесь, что ошибок не возникло

Сравнение способов получения элемента

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

МетодЧто возвращаетКогда применятьОграничение
НайтиПоКоду()СсылкаИзвестен код элементаТребует точного знания кода с учётом длины
НайтиПоНаименованию()СсылкаИзвестно наименованиеНе гарантирует уникальность при дублях
НайтиПоРеквизиту()СсылкаПоиск по ИНН, артикулу и т. п.Медленнее при отсутствии индекса по реквизиту
ПолучитьОбъект()ОбъектНужно изменить и записать элементДорогая операция, не использовать в циклах без нужды
Выбрать()ВыборкаОбход множества элементовТребует проверки ЭтоГруппа в иерархических справочниках

Сравнение вариантов

Ссылка

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

Объект

Нужен для редактирования и записи. Требует больше ресурсов и осторожности в циклах.

Запрос

Оптимален для массового чтения данных по многим элементам без получения объектов.

Типичные ошибки и ограничения

Первая частая ошибка — вызов ПолучитьОбъект() без проверки ссылки на пустоту. Если элемент не найден, платформа выдаст исключение «Элемент не выбран», и выполнение кода прервётся. Вторая ошибка — изменение реквизитов объекта без последующего вызова Записать(): изменения просто не попадут в базу.

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

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

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

Как проверить, что всё сработало правильно

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

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

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

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

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

Ссылка не пустая, реквизиты читаются

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

Пустая ссылка или исключение при обращении

После Записать()
Норма

Метод выполнен без исключений, данные видны в форме элемента

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

Ошибка записи, конфликт блокировок

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

ПометкаУдаления = Ложь для рабочих элементов

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

Найденный элемент помечен на удаление

Часто задаваемые вопросы

Чем отличается НайтиПоНаименованию от поиска запросом?

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

Почему НайтиПоКоду не находит элемент, хотя код верный?

Чаще всего причина в несовпадении формата кода: коды в 1С хранятся с ведущими нулями фиксированной длины, например «000000123». Передача значения «123» без дополнения нулями не даст совпадения. Также проверьте, не указан ли поиск внутри конкретной группы-родителя.

Можно ли изменить элемент, не получая объект?

Нет. Изменение данных справочника возможно только через объект: ссылка предназначена исключительно для чтения и идентификации. Альтернатива — объектная модель через СоздатьЭлемент() для новых записей.

Что делать, если ПолучитьОбъект() вызывает ошибку блокировки?

Ошибка означает, что элемент редактируется другим пользователем или сеансом. Корректное решение — обернуть запись в попытку/исключение, сообщить пользователю о занятости объекта и предложить повторить операцию позже, а не снимать блокировку принудительно.

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

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

Безопасно ли использовать УстановитьПривилегированныйРежим для поиска?

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

Итог

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

Для чтения данных достаточно ссылки, полученной через НайтиПоКоду, НайтиПоНаименованию или НайтиПоРеквизиту. Объект через ПолучитьОбъект() берите только для изменения, всегда проверяйте ссылку на пустоту и завершайте правки вызовом Записать().