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