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

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

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

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

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

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

Все примеры приведены для управляемого приложения и обычных форм на актуальных версиях платформы 1С:Предприятие 8.3. Синтаксис одинаков для справочников, документов, планов счетов и других ссылочных типов — отличается только имя менеджера объекта.

Чтение реквизита, когда объект уже открыт

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

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

НомерДокумента = Объект.Номер;

ДатаДокумента = Объект.Дата;

Контрагент = Объект.Контрагент;

Обращение по имени чувствительно к точному написанию: если реквизит называется Организация, то Объект.Организация1 вызовет ошибку «Поле объекта не обнаружено». Имена смотрите в конфигураторе в дереве метаданных, а не по синониму, который видит пользователь.

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

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

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

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

// Разовое чтение — допустимо

ИННКонтрагента = СсылкаНаКонтрагента.ИНН;

// В цикле — плохо: N запросов к базе

Для Каждого Строка Из ТаблицаЗначений Цикл

Сумма = Строка.Документ.СуммаДокумента; // обращение к БД на каждой строке

КонецЦикла;

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

Запрос — основной способ массового чтения реквизитов. Он забирает только нужные поля, не поднимает объект целиком и выполняется одним обращением к СУБД. Это предпочтительный вариант для циклов, отчётов и обработок.

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

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

"ВЫБРАТЬ

| Контрагенты.Наименование КАК Наименование,

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

|ИЗ

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

|ГДЕ

| Контрагенты.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаКонтрагента);

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

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

ИНН = Выборка.ИНН;

КонецЕсли;

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

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

Сравнение способов

Ссылка.Реквизит

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

Запрос

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

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

Нужен, когда кроме чтения планируется изменение и запись объекта. Для простого чтения избыточен: поднимает объект целиком с табличными частями.

ЗначениеРеквизитаОбъекта (БСП)

Готовая функция из Библиотеки стандартных подсистем. Удобна для одного реквизита по ссылке, внутри использует запрос.

Функция ЗначениеРеквизитаОбъекта из БСП

В конфигурациях на базе Библиотеки стандартных подсистем (УТ, ERP, Бухгалтерия, ЗУП и другие типовые) есть готовая функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита). Она безопасно читает один реквизит по ссылке через запрос и возвращает Неопределено, если объект не найден.

ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(КонтрагентСсылка, "ИНН");

// Несколько реквизитов сразу — возвращается структура

Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(

КонтрагентСсылка, "ИНН,КПП,НаименованиеПолное");

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

bsl
ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИНН");

Реквизиты табличных частей и составных типов

Табличная часть — это коллекция строк, поэтому реквизит из неё читается через конкретную строку. Обращение к строке идёт по индексу (начиная с нуля) или в цикле перебора.

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

Если Объект.Товары.Количество() > 0 Тогда

ПерваяНоменклатура = Объект.Товары[0].Номенклатура;

КонецЕсли;

Для Каждого СтрокаТовара Из Объект.Товары Цикл

СуммаСтроки = СтрокаТовара.Сумма;

КонецЦикла;

Если реквизит составного типа (например, «Документ основание» может хранить разные виды документов), перед чтением его собственных реквизитов проверьте тип значения через ТипЗнч(). Иначе обращение к реквизиту, которого нет у конкретного вида документа, завершится ошибкой.

Для реквизитов с типом «ХранилищеЗначения» простое чтение вернёт объект хранилища, а не сами данные — их нужно извлечь методом Получить(). Это частая причина «странных» значений в отладчике.

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

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

Убедиться, что значение получено корректно, проще всего через отладчик: поставьте точку останова после строки чтения и посмотрите значение в табло (Ctrl+F9). Для ссылочных значений в табло видны тип и представление, а развернув значение, можно посмотреть все реквизиты.

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

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

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

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

Виден ожидаемый тип и содержимое

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

Неопределено или пустая ссылка при заполненном реквизите — проверьте имя и источник ссылки

Поведение в цикле
Норма

Один запрос к базе, время выполнения линейное

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

Время растёт непропорционально, в замере производительности тысячи одинаковых запросов

Работа с битой ссылкой
Норма

Код отрабатывает без исключения, возвращает Неопределено

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

Исключение «Объект не найден» прерывает обработку

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

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

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

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

Чаще всего вы смотрите не на тот реквизит: в карточке может отображаться синоним или данные связанного объекта. Проверьте точное имя реквизита в конфигураторе. Вторая причина — битая ссылка: объект физически отсутствует в базе.

Можно ли прочитать реквизит на клиенте без вызова сервера?

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

Как получить реквизиты сразу для списка ссылок?

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

Чем отличается ПолучитьОбъект() от чтения через точку от ссылки?

ПолучитьОбъект() загружает объект целиком в память и позволяет его изменять и записывать. Чтение через точку от ссылки только извлекает значение из базы без возможности модификации. Для чтения одного поля оба варианта избыточны по сравнению с запросом.

Как прочитать реквизит у помеченного на удаление объекта?

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

Итог

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

Открытый объект читается через точку, по ссылке для разового чтения используйте Ссылка.Реквизит или функцию БСП, для массового чтения — только запрос. Всегда проверяйте результат на пустую выборку и битые ссылки, а в циклах избегайте скрытых обращений к базе.