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

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

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

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

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

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

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

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

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

Наименование = КонтрагентОбъект.Наименование;

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

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

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

Структура = Новый Структура("Сумма, Ставка", 100, 20);

Значение = Структура.Сумма; // через точку

Значение = Структура["Ставка"]; // через скобки

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

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

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

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

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

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

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

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

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

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

КонецЕсли;

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

Получение значений в цикле и выборке

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

// Так делать нельзя: запрос к базе на каждой итерации

Для Каждого Элемент Из СписокСсылок Цикл

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

Сообщить(Объект.Наименование);

КонецЦикла;

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

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

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

"ВЫБРАТЬ

| Док.Номер КАК Номер,

| Док.Дата КАК Дата,

| Док.СуммаДокумента КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Док

|ГДЕ

| Док.Ссылка В (&СписокСсылок)";

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

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

Сообщить(Строка(Выборка.Номер) + " — " + Выборка.Сумма);

КонецЦикла;

В выборке обращение к полю идёт через точку по псевдониму (Выборка.Сумма). Если псевдоним не задан, имя поля совпадает с именем реквизита. Для полей через точку из связанных таблиц (например, Док.Контрагент.ИНН) задавайте явный псевдоним — обращение к нему будет простым именем.

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

Чтение свойства, имени которого нет в коде: обращение по строке

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

ИмяРеквизита = "ИНН";

Значение = КонтрагентОбъект[ИмяРеквизита];

Перед обращением полезно проверить, что реквизит существует в метаданных, иначе получите ошибку «Поле объекта не обнаружено»:

МетаданныеОбъекта = СсылкаНаКонтрагента.Метаданные();

Если МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита) <> Неопределено Тогда

Значение = КонтрагентОбъект[ИмяРеквизита];

КонецЕсли;

Для структур проверка проще — методом Свойство(): Если Структура.Свойство("Сумма", Значение) Тогда ... КонецЕсли;. Метод вернёт Ложь, если ключа нет, и не вызовет исключения.

Свойства табличных частей и движений

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

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

СуммаСтроки = СтрокаТовара.Количество * СтрокаТовара.Цена;

КонецЦикла;

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

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

Проверка результата и обработка особых случаев

После чтения свойства проверьте, что получили осмысленное значение. Типичные контрольные точки:

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

Дополнительная ловушка — права доступа. При чтении реквизита запросом под пользователем без прав на объект вы получите пустой результат без явной ошибки. В отладке под полными правами код работает, у пользователя — молча возвращает пустоту. Учитывайте это при диагностике.

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

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

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

Ожидаемый тип и заполненное значение

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

Неопределено или пустая ссылка без явной причины

Скорость обработки списка объектов
Норма

Один запрос на всю выборку

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

Запрос к базе на каждой итерации цикла

Поведение под пользователем без полных прав
Норма

Код возвращает данные или контролируемое пустое значение

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

Молчаливый пустой результат или ошибка доступа

Выбор способа в зависимости от задачи

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

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

Объект уже загружен и будет изменятьсяОбращайтесь к свойствам через точку: Объект.Реквизит
Есть только ссылка, нужен один-два реквизитаИспользуйте запрос или ОбщегоНазначения.ЗначениеРеквизитаОбъекта
Нужно прочитать данные сотен объектовОдин запрос с выборкой, никаких ПолучитьОбъект() в цикле
Имя реквизита известно только в runtimeОбращение через квадратные скобки с предварительной проверкой метаданных
Работаете со структурой с произвольными ключамиМетод Свойство() и обращение через квадратные скобки

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

Итог

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

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

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

Чем отличается Ссылка.Наименование от Ссылка.ПолучитьОбъект().Наименование?

Результат одинаков, но механизм разный: обращение к реквизиту ссылки выполняет точечный запрос только за нужным полем, а ПолучитьОбъект() загружает весь объект целиком. Для чтения первый вариант предпочтительнее.

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

Используйте квадратные скобки: Объект[ИмяРеквизита]. Перед обращением проверьте наличие реквизита через метаданные, чтобы избежать ошибки «Поле объекта не обнаружено».

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

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

Можно ли прочитать табличную часть документа по ссылке без ПолучитьОбъект()?

Да, запросом к таблице табличной части, например Документ.РеализацияТоваровУслуг.Товары с отбором по ссылке. Это быстрее и не требует загрузки объекта.

Что вернёт обращение к реквизиту битой ссылки?

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

Как узнать все свойства объекта в отладчике?

Добавьте переменную в табло (Ctrl+Shift+F9) и разверните её — отладчик покажет реквизиты и их значения. Состав реквизитов также виден в конфигураторе через метаданные объекта.