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