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

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

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

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

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

Базовый синтаксис выглядит так: Значение = СсылкаНаЭлемент.ИмяРеквизита;. Например, ИНН = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка").ИНН;. Платформа автоматически выполняет запрос к базе данных и возвращает значение реквизита, поэтому дополнительного чтения объекта для чтения не требуется.

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

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

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

// Поиск по наименованию

Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");

// Поиск по коду

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

// Поиск по значению реквизита

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

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

Если ссылка уже есть — например, передана как параметр в процедуру или взята из реквизита документа — искать её заново не нужно. Достаточно сразу обратиться к реквизиту через точку.

Чтение реквизита через точку

Когда ссылка получена, реквизит читается простым обращением по имени, как оно задано в конфигураторе (не по синониму, который видит пользователь):

Ссылка = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");

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

ИНН = Ссылка.ИНН;

КПП = Ссылка.КПП;

Сообщить("ИНН: " + ИНН + ", КПП: " + КПП);

КонецЕсли;

Стандартные реквизиты — Код, Наименование, Владелец, Родитель, ПометкаУдаления — доступны так же, через точку, без дополнительных объявлений.

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

Изменение реквизита через объект

Через ссылку реквизит можно только прочитать. Для изменения нужно получить объект, изменить свойство и записать:

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

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

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

Объект.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;

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

КонецЕсли;

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

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

Обращение к реквизитам табличной части

У элементов справочника могут быть табличные части — например, «Единицы измерения» у номенклатуры. Доступ к ним возможен только через объект:

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

Для Каждого Строка Из Объект.ЕдиницыИзмерения Цикл

Сообщить(Строка.ЕдиницаИзмерения);

КонецЦикла;

Через ссылку табличная часть недоступна напрямую. Если нужно только прочитать данные табличной части без изменения, правильнее использовать запрос к таблице Справочник.ИмяСправочника.ИмяТабличнойЧасти.

Обращение к реквизиту в запросе

В запросах реквизиты справочника выбираются как поля таблицы. Это основной способ массового чтения данных:

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

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

"ВЫБРАТЬ

| Контрагенты.Ссылка,

| Контрагенты.ИНН,

| Контрагенты.КПП

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| НЕ Контрагенты.ПометкаУдаления";

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

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

Сообщить(Выборка.ИНН);

КонецЦикла;

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

Сравнение способов доступа

Через точку от ссылки

Быстро пишется, подходит для чтения 1–2 реквизитов одного элемента. Не годится для изменения и для циклов по большому числу элементов.

Через ПолучитьОбъект()

Единственный способ изменить реквизит и работать с табличными частями. Медленнее, требует Записать() и обработки ошибок.

Запрос

Оптимален для массового чтения и отборов. Не позволяет изменять данные и вызывать обработчики записи.

Обращение к предопределённым элементам

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

Ставка = Справочники.СтавкиНДС.НДС20;

// Чтение реквизита предопределённого элемента

Значение = Справочники.Валюты.Рубль.НаименованиеПолное;

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

Типичные ошибки и как их проверить

Типичные ошибки
01
Обращение к реквизиту пустой ссылки без проверки — вместо ошибки получают пустое значение и долго ищут, почему «данные не читаются».
02
Попытка изменить реквизит через ссылку: Ссылка.ИНН = «123» — платформа выдаст ошибку, изменение возможно только через объект.
03
Использование синонима реквизита вместо имени — ошибка «Поле объекта не обнаружено».
04
Чтение реквизитов через точку внутри большого цикла — тысячи обращений к базе вместо одного запроса, резкое падение производительности.
05
Забытый вызов Записать() после изменения объекта — изменения теряются без сообщений.

Проверить корректность имени реквизита проще всего в конфигураторе: откройте структуру справочника и сверьте колонку «Имя». В пользовательском режиме точные имена можно посмотреть через консоль кода или функционал «Вывести список» с настройкой полей.

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

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

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

Чтение реквизита
Норма

Возвращается ожидаемое значение, тип соответствует типу реквизита

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

Пустое значение при заполненном поле — вероятно, ссылка пустая или имя реквизита неверное

Изменение реквизита
Норма

После Записать() значение видно в форме элемента

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

Значение старое — не вызван Записать() или запись прервана исключением

Поиск элемента
Норма

Найденная ссылка не пустая, Ссылка.Пустая() = Ложь

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

Пустая ссылка — неверные параметры поиска или элемент отсутствует

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

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

Да, если ссылка уже известна: она может храниться в реквизите документа, другого справочника или быть передана в процедуру параметром. Тогда реквизит читается напрямую: РеквизитДокумента.Контрагент.ИНН. Поиск нужен только когда ссылки нет.

Чем отличается Ссылка от Объекта при работе с реквизитами?

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

Почему возникает ошибка «Поле объекта не обнаружено»?

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

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

Через цепочку точек: Ссылка.ОсновнойДоговор.НомерДоговора. Каждый уровень — отдельное обращение к данным, поэтому в массовых обработках такие цепочки лучше переносить в запрос.

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

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

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

Да, через квадратные скобки: Ссылка["ИНН"] или Объект["ИНН"]. Это удобно, когда имя реквизита формируется динамически, например при универсальной обработке разных справочников.

Итог

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

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