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

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

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

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

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

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

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

Через точку от ссылки — самый простой способ

Когда в переменной уже хранится ссылка на элемент справочника (тип СправочникСсылка), платформа позволяет обратиться к реквизиту напрямую через точку. При первом обращении 1С автоматически выполняет обращение к базе данных и кэширует данные объекта.

Контрагент = Документ.Контрагент; // СправочникСсылка.Контрагенты

ИНН = Контрагент.ИНН;

Наименование = Контрагент.Наименование;

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

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

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

Метод ПолучитьОбъект() превращает ссылку в полноценный объект СправочникОбъект, который можно не только читать, но и модифицировать. Это единственный корректный путь, когда задача — не просто узнать значение, а записать новое.

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

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

ЭлементОбъект.Записать();

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

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

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

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

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

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

"ВЫБРАТЬ

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

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

| Номенклатура.ЕдиницаИзмерения КАК Единица

|ИЗ

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

|ГДЕ

| Номенклатура.Код = &Код";

Запрос.УстановитьПараметр("Код", "00-000123");

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

Если Выборка.Следующий() Тогда

Артикул = Выборка.Артикул;

КонецЕсли;

Обратите внимание на проверку Выборка.Следующий(): если элемент с указанным кодом не найден, выборка будет пустой, и обращение к полям без проверки даст ошибку или пустое значение в зависимости от способа получения данных. Это стандартный приём защитного программирования в 1С.

Для поиска самой ссылки по реквизиту можно также использовать метод НайтиПоРеквизиту, НайтиПоКоду или НайтиПоНаименованию менеджера справочника, а уже от найденной ссылки читать остальные поля. Это удобно, когда нужен один элемент.

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

Какой способ выбрать в разных ситуациях

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

Маршрут решения

Как выбрать действие

Есть ссылка и нужно прочитать 1–2 реквизита один разОбратитесь к реквизиту через точку от ссылки
Нужно изменить значение реквизита элементаИспользуйте ПолучитьОбъект(), измените свойство и вызовите Записать()
Нужно прочитать реквизиты у множества элементов или в циклеИспользуйте запрос с выборкой — это быстрее обращений через точку
Есть только код, наименование или значение другого реквизитаСначала найдите ссылку через НайтиПоКоду, НайтиПоНаименованию или НайтиПоРеквизиту
Нужны данные предопределённого элементаОбратитесь через Справочники.ИмяСправочника.ИмяПредопределенного

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

Особые случаи: предопределённые элементы и дополнительные реквизиты

Предопределённые элементы

Предопределённые элементы создаются в конфигураторе и доступны по имени напрямую, без поиска. Это надёжный способ привязки логики к конкретным элементам, который не зависит от кода или наименования, которые пользователь может изменить.

ВалютаРуб = Справочники.Валюты.Рубли;

КодВалюты = ВалютаРуб.Код;

Дополнительные реквизиты и сведения

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

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

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

Проверка результата и отладка

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

Для проверки существования элемента по ссылке используйте сравнение с пустой ссылкой: Ссылка.Пустая() или Ссылка = Справочники.Номенклатура.ПустаяСсылка(). Для проверки «битости» ссылки в типовых конфигурациях есть функция ОбщегоНазначения.СсылкаСуществует.

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

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

Значение реквизита в отладчике
Норма

Переменная содержит ожидаемое значение нужного типа

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

Неопределено или пустое значение при существующем элементе

Ссылка перед чтением
Норма

Ссылка не пустая, элемент открывается в интерфейсе

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

Пустая ссылка или ошибка открытия элемента

Результат ПолучитьОбъект()
Норма

Возвращён объект, доступны свойства

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

Возвращено Неопределено

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

Значение видно в карточке элемента после записи

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

В карточке старое значение — запись не выполнялась

При работе в пользовательском режиме без программирования значение реквизита можно посмотреть прямо в форме элемента справочника, а также вывести нужную колонку в список справочника через настройку списка (Ещё → Изменить форму или настройка списка в типовых конфигурациях).

Итог

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

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

Частые вопросы

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

Сначала найдите ссылку: Справочники.ИмяСправочника.НайтиПоКоду("000001"). Если возвращённая ссылка не пустая, обратитесь к реквизиту через точку. Учтите, что для справочников с неуникальными кодами в пределах подчинения поиск может вернуть не тот элемент.

Почему обращение через точку возвращает пустое значение, хотя в карточке поле заполнено?

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

Можно ли получить реквизит без обращения к базе данных?

Да, если данные объекта уже получены: например, в форме элемента реквизиты доступны через Объект.ИмяРеквизита, а в обработке табличной части документа — через данные строки. Платформа также кэширует данные при первом обращении через точку, поэтому повторные обращения к той же ссылке уже не идут в базу.

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

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

Чем отличается НайтиПоНаименованию от НайтиПоРеквизиту("Наименование", ...)?

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

Как получить значение реквизита в запросе динамически, если имя реквизита хранится в переменной?

Текст запроса — это строка, поэтому имя реквизита можно подставить через конкатенацию: "ВЫБРАТЬ Т." + ИмяРеквизита + " ИЗ Справочник.Номенклатура КАК Т". Проверяйте, что имя реквизита существует в метаданных (через Метаданные.Справочники), иначе запрос завершится с ошибкой.