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

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

Имя реквизита как переменная в 1С: обращение к реквизитам через строку

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

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

Хорошая новость в том, что платформа поддерживает такое обращение штатно. Объекты 1С (справочники, документы, записи регистров, строки табличных частей, структуры) позволяют обращаться к свойствам через квадратные скобки со строковым именем: Объект[ИмяРеквизита]. Это не ухищрение, а документированный механизм, работающий и на сервере, и на клиенте.

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

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

Основной приём выглядит так: вместо Документ.Номенклатура пишется Документ[ИмяПоля], где ИмяПоля — строковая переменная со значением "Номенклатура". Механизм работает для объектов данных (справочников, документов, планов счетов), записей регистров, строк табличных частей, структур и соответствий, а также для данных формы.

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

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

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

Тот же приём применим к строкам табличных частей: СтрокаТЧ["Количество"]. Для структур квадратные скобки — вообще единственный способ обращения по переменной, поскольку структура по определению хранит произвольные ключи: СтруктураПараметров[ИмяКлюча].

Важно понимать, что запись через строку эквивалентна обычной записи через точку: срабатывают те же проверки типов, подписки на события и обработчики. Никакого «обхода» логики конфигурации не происходит.

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

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

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

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

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

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

ИначеЕсли ИмяРеквизита = "Номер" Или ИмяРеквизита = "Дата" Тогда

// стандартные реквизиты проверяются отдельно

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

КонецЕсли;

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

Отдельный случай — реквизиты формы в управляемом приложении. Там динамическое обращение выполняется через ЭтаФорма[ИмяРеквизита], и список доступных имён можно получить через ПолучитьРеквизиты().

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

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

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

Значение читается и записывается без исключений

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

Ошибка «Поле объекта не обнаружено»

Имя из пользовательской настройки
Норма

Перед обращением выполнена проверка через метаданные

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

Имя подставляется в код без проверки

Структура с произвольными ключами
Норма

Используется Структура.Свойство() с проверкой

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

Прямое обращение Структура[Ключ] без проверки

Обход всех реквизитов объекта по метаданным

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

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

Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл

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

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

// обработка значения

КонецЦикла;

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

Для копирования значений между однотипными объектами есть более простой штатный метод ЗаполнитьЗначенияСвойств(Приёмник, Источник) — он работает со структурами и объектами и сам сопоставляет свойства по именам. Используйте его, когда не нужна специальная логика по отдельным полям.

При загрузке данных из Excel или CSV удобно хранить соответствие «колонка файла → имя реквизита» в Соответствии: тогда заполнение объекта сводится к циклу по соответствию и записи Объект[ИмяРеквизита] = ЗначениеКолонки, а настройку можно менять без правки кода.
ПЗ
Практическое замечание

Динамическое обращение в запросах и СКД

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

ТекстЗапроса = "ВЫБРАТЬ Док." + ИмяПоля + " КАК Значение

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

|ГДЕ Док.Ссылка = &Ссылка";

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

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

Оператор Выполнить и почему его стоит избегать

Оператор Выполнить(СтрокаКода) исполняет произвольный фрагмент кода на встроенном языке, переданный строкой. Теоретически через него можно обратиться и к реквизиту по переменной, и к методу. На практике для доступа к реквизитам он не нужен — квадратные скобки решают задачу проще и быстрее.

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

Если нужно вызвать метод по имени, рассмотрите альтернативы: явное ветвление Если ИмяМетода = "Печать" Тогда Печать(), структуру с описанием обработчиков или механизмы переопределяемых модулей и подписок. Это длиннее, но контролируемо и проверяемо.

Сравнение вариантов

Объект[ИмяРеквизита]

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

ЗаполнитьЗначенияСвойств()

Массовое копирование свойств по совпадающим именам; не подходит, когда нужна логика по отдельным полям

Подстановка в текст запроса

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

Выполнить()

Исполнение произвольного кода; избегать, запрещён в безопасном режиме, сложно отлаживать

Типичные ошибки при работе с именами реквизитов-переменных

Самая частая проблема — несовпадение регистра или опечатка. Имена реквизитов в 1С регистронезависимы при обращении через точку, но при поиске в метаданных методом Найти регистр тоже не учитывается, однако лишние пробелы и невидимые символы из файлов ломают поиск. Перед использованием строку из внешнего источника стоит обработать СокрЛП.

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

Третья типичная ситуация — попытка записать значение несовместимого типа. При динамической записи легко потерять контроль: строка из файла попадает в реквизит типа «Число» или «Дата». Перед записью приводите значение к типу реквизита, который можно получить из метаданных: Реквизит.Тип вернёт описание типов, а метод ПривестиЗначение выполнит безопасное преобразование.

Практический пример: универсальное заполнение объекта

Соберём типовой приём целиком: есть структура с данными (например, прочитанная из файла) и объект, который нужно заполнить по совпадающим именам реквизитов. Код проверяет существование реквизита и приводит тип:

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

Для Каждого КлючЗначение Из ДанныеИзФайла Цикл

ИмяРеквизита = СокрЛП(КлючЗначение.Ключ);

Реквизит = МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита);

Если Реквизит = Неопределено Тогда

Продолжить; // поле не сопоставлено — пропускаем

КонецЕсли;

Объект[ИмяРеквизита] = Реквизит.Тип.ПривестиЗначение(КлючЗначение.Значение);

КонецЦикла;

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

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

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

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

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

Да. Строка табличной части поддерживает квадратные скобки: СтрокаТЧ["Количество"]. Имена колонок для проверки берутся из метаданных табличной части: МетаданныеОбъекта.ТабличныеЧасти["Товары"].Реквизиты.

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

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

Чем отличается Структура.Свойство() от обращения Структура[Ключ]?

Метод Свойство() с двумя параметрами проверяет наличие ключа и возвращает значение через второй параметр, не вызывая ошибки при отсутствии ключа. Прямое обращение Структура[Ключ] к несуществующему ключу приведёт к ошибке, поэтому без предварительной проверки его использовать не стоит.

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

Через метаданные: найдите реквизит методом Найти() в коллекции Реквизиты, затем обратитесь к его свойству Тип — оно содержит объект ОписаниеТипов. Его метод ПривестиЗначение() позволяет безопасно преобразовать значение перед записью.

Почему Выполнить() не работает в расширении конфигурации?

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

Как безопасно подставить имя поля в текст запроса?

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

Итог

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

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