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