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

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

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

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

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

Механизм прост: любой объект данных (ссылка, объект документа, запись регистра, строка табличной части) поддерживает синтаксис Объект["ИмяРеквизита"]. Внутри скобок может стоять любое строковое выражение — переменная, конкатенация, результат функции. Это основа универсальных алгоритмов: обработок заполнения, сопоставления полей при обмене, произвольных отчётов.

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

Обращение через квадратные скобки — основной способ

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

ИмяРеквизита = "Организация";

ОрганизацияДокумента = ДокументОбъект[ИмяРеквизита];

// То же самое с литералом

Сумма = ДокументОбъект["СуммаДокумента"];

// Имя можно собирать динамически

Для Ном = 1 По 3 Цикл

Значение = СтрокаДанных["Поле" + Ном];

КонецЦикла;

Запись значения выполняется тем же синтаксисом — присваивание через скобки:

ДокументОбъект[ИмяРеквизита] = НовоеЗначение;

ДокументОбъект["Комментарий"] = "Заполнено обработкой";

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

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

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

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

СтрокаТовары["Цена"] = СтрокаТовары["Сумма"] / СтрокаТовары["Количество"];

КонецЦикла;

Аналогично работают записи регистров. Например, универсальная запись значения в ресурс регистра сведений по имени из настроек:

МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Период = ТекущаяДатаСеанса();

МенеджерЗаписи.Валюта = ВалютаСсылка;

МенеджерЗаписи[ИмяРесурса] = ЗначениеКурса; // например, "Курс" или "Кратность"

МенеджерЗаписи.Записать();

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

Проверка существования реквизита через метаданные

Если обратиться по имени к несуществующему реквизиту, платформа вызовет исключение «Поле объекта не обнаружено». В универсальных алгоритмах, где имя приходит извне (из файла настроек, от пользователя, из другой базы), наличие реквизита нужно проверять заранее.

МетаданныеДокумента = ДокументОбъект.Метаданные();

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

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

Иначе

// Реквизита нет — пропускаем или фиксируем в журнале

КонецЕсли;

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

Безопасное обращение к реквизиту по имени
  1. 1
    Получите метаданные объекта: Объект.Метаданные()
  2. 2
    Проверьте наличие имени в коллекции Реквизиты через Найти()
  3. 3
    При необходимости проверьте СтандартныеРеквизиты и ОбщиеРеквизиты
  4. 4
    Обратитесь к реквизиту: Объект[ИмяРеквизита]
  5. 5
    Проверьте тип полученного значения перед использованием

Защита через Попытка/Исключение

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

Попытка

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

Исключение

ЗаписьЖурналаРегистрации("ЗагрузкаДанных",

УровеньЖурналаРегистрации.Предупреждение, , ,

"Не удалось прочитать реквизит " + ИмяРеквизита + ": " + ОписаниеОшибки());

Значение = Неопределено;

КонецПопытки;

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

Альтернативные способы: структуры, запросы, УстановитьСвойство

Если данные собираются не из объекта базы, а формируются программно, удобнее структура: Структура.Вставить(ИмяРеквизита, Значение) и чтение через Структура.Свойство(ИмяРеквизита, Значение). Метод Свойство() сам проверяет наличие ключа и возвращает Истина или Ложь — это самый безопасный вариант для произвольных наборов полей.

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

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

Способы обращения по имени

Квадратные скобки Объект[Имя]

Универсально для чтения и записи; требует проверки существования реквизита

Структура.Свойство()

Только для структур; сама проверяет наличие ключа, не вызывает исключений

Запрос с динамическим текстом

Лучший вариант для массового чтения реквизитов ссылок; не подходит для записи

Вычислить() / Выполнить()

Выполняет произвольный код; опасно с внешними данными, используйте только при крайней необходимости

Типичные ошибки и ограничения

Самая частая ошибка — опечатка или несовпадение регистра не является проблемой (имена реквизитов регистронезависимы), но лишние пробелы в строке имени приводят к исключению. Строки из внешних источников стоит обрезать через СокрЛП().

Вторая группа ошибок — обращение к реквизиту табличной части через сам объект: ДокументОбъект["Цена"] не сработает, если «Цена» — колонка табличной части «Товары». Нужно сначала получить строку табличной части и обращаться к ней.

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

Типичные ошибки
01
Пробелы в строке имени реквизита из внешнего файла — исключение «Поле не обнаружено»; применяйте СокрЛП()
02
Обращение к колонке табличной части через объект документа вместо строки табличной части
03
Отсутствие проверки существования реквизита в универсальной обработке — падение на конфигурации без этого реквизита
04
Чтение реквизитов ссылок через скобки в цикле по тысячам строк вместо одного запроса — резкое падение производительности
05
Попытка вызвать метод объекта через скобки — скобки работают только со свойствами
Контрольные точки

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

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

Возвращено значение ожидаемого типа

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

Исключение «Поле объекта не обнаружено» или Неопределено там, где ожидались данные

Запись через скобки
Норма

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

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

Значение не сохранилось — объект не был записан или имя реквизита не совпало

Универсальная обработка на другой конфигурации
Норма

Отсутствующие реквизиты пропускаются с записью в журнал

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

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

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

Работает ли обращение через скобки на тонком клиенте?

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

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

Да, через коллекцию данных формы: ЭтаФорма[ИмяРеквизита] работает для реквизитов формы. Для элементов формы используется Элементы.Найти(ИмяЭлемента) или прямое обращение Элементы[ИмяЭлемента].

Как перебрать все реквизиты объекта, не зная их имён?

Пройдите циклом по коллекции метаданных: Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл Значение = Объект[Реквизит.Имя]; КонецЦикла;. Так строят универсальные выгрузки и сравнения объектов.

Чем отличается обращение к структуре через скобки и через точку?

По сути ничем: Структура.Ключ и Структура["Ключ"] эквивалентны, если ключ — допустимый идентификатор. Скобки обязательны, когда имя ключа содержит пробелы или хранится в переменной. Для проверки наличия ключа безопаснее метод Свойство().

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

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

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

Да, составной тип не влияет на механизм обращения. Вернётся то значение, которое фактически хранится в реквизите. Перед использованием проверьте его тип через ТипЗнч(), если алгоритм зависит от конкретного вида данных.

Итог

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

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