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

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

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

Как в 1С получить объект по строке: менеджеры объектов, НайтиПоНаименованию, ПолучитьСсылку, ЗначениеИзСтрокиВнутр и Вычислить. Примеры кода и ошибки.

Задача получить объект по строке возникает в 1С постоянно: имя справочника или документа приходит из внешней системы, из файла обмена, из настроек пользователя или хранится в поле настройки в виде текста. Строка сама по себе не является ни ссылкой, ни объектом — её нужно преобразовать, и способ преобразования зависит от того, что именно содержит строка: имя метаданных, наименование элемента, GUID, уникальный идентификатор или сериализованное представление значения.

Универсальной функции «получить объект из строки» во встроенном языке нет. Вместо неё используется набор механизмов: обращение к менеджерам через коллекции метаданных, поиск по реквизитам, конструктор ссылки по GUID, функции ЗначениеИзСтрокиВнутр и оператор Вычислить. Каждый подходит для своего типа входных данных, и ошибка в выборе приводит либо к пустому результату, либо к исключению в runtime.

Ниже разобраны основные сценарии: получение менеджера объекта по имени, поиск элемента по наименованию или коду, восстановление ссылки из GUID, десериализация значения и безопасное выполнение кода из строки. Для каждого сценария приведены условия применения, примеры и типичные ошибки.

Как получить менеджер объекта метаданных по имени в строке

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

ИмяСправочника = "Номенклатура";

Менеджер = Справочники[ИмяСправочника];

НовыйЭлемент = Менеджер.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Тестовый элемент";

НовыйЭлемент.Записать();

Тот же приём работает и для документов: Документы[ИмяСтрокой].СоздатьДокумент(). Если имени в конфигурации нет, обращение вызовет исключение, поэтому перед обращением полезно проверить существование метаданных.

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

Менеджер = Справочники[ИмяСправочника];

Иначе

ВызватьИсключение "Справочник " + ИмяСправочника + " не найден в конфигурации";

КонецЕсли;

Когда заранее неизвестен даже вид объекта (справочник это или документ), имя проверяют последовательно по коллекциям метаданных либо используют Метаданные.НайтиПоПолномуИмени("Справочник." + ИмяСтрокой). Полное имя с точкой позволяет однозначно определить и вид, и конкретный объект.

Как найти ссылку элемента по строке с наименованием или кодом

Чаще всего строка содержит не имя метаданных, а пользовательское значение — наименование товара, код контрагента, артикул. Для поиска ссылки по таким данным у менеджеров справочников есть методы НайтиПоНаименованию и НайтиПоКоду.

НаименованиеСтрокой = "Кабель ВВГ 3х2.5";

Ссылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеСтрокой, Истина);

Если Ссылка.Пустая() Тогда

Сообщить("Элемент не найден");

Иначе

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

КонецЕсли;

Второй параметр НайтиПоНаименованию определяет режим поиска: Истина — точное соответствие, Ложь — поиск по началу строки. Точный поиск надёжнее, но требует, чтобы строка совпадала с наименованием полностью, включая пробелы и регистр-сохранённое написание. Поиск по коду быстрее, так как код обычно уникален, но работает только если в справочнике включена кодовая нумерация.

Для поиска по произвольному реквизиту (ИНН, артикул, штрихкод) используют НайтиПоРеквизиту, если реквизит проиндексирован, либо запрос — если индекса нет или условий несколько. Поиск по неиндексированному реквизиту через запрос в большой базе заметно производительнее перебора.

Порядок поиска элемента по строке
  1. 1
    Определите, что содержит строка: наименование, код, GUID или реквизит
  2. 2
    Выберите метод: НайтиПоНаименованию, НайтиПоКоду, НайтиПоРеквизиту или ПолучитьСсылку
  3. 3
    Выполните поиск и проверьте результат через Пустая()
  4. 4
    Только для непустой ссылки вызывайте ПолучитьОбъект() для чтения или изменения

Как получить ссылку по строке с GUID

При обмене между базами элементы часто идентифицируются уникальным идентификатором в виде строки вида «a1b2c3d4-e5f6-...». Из такой строки ссылку восстанавливают без запроса к базе — конструированием:

СтрокаGUID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";

УИД = Новый УникальныйИдентификатор(СтрокаGUID);

Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);

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

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка");

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

Если Запрос.Выполнить().Пустой() Тогда

Сообщить("Элемент с таким GUID отсутствует в базе");

КонецЕсли;

Как восстановить значение из внутренней строки через ЗначениеИзСтрокиВнутр

Функции ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр сериализуют и восстанавливают произвольные значения — ссылки, структуры, таблицы значений — в специальное внутреннее строковое представление. Это удобно для хранения настроек и передачи значений между сеансами одной и той же базы.

// Сохранение

Строка = ЗначениеВСтрокуВнутр(СсылкаНаЭлемент);

// Восстановление

ВосстановленноеЗначение = ЗначениеИзСтрокиВнутр(Строка);

Ключевое ограничение: внутреннее представление привязано к конкретной информационной базе. Строка, сохранённая в одной базе, не гарантированно раскодируется в другой даже с идентичной конфигурацией. Для межбазовых обменов используют GUID или XML-сериализацию (XMLСтрока / XMLЗначение).

Если строка повреждена или имеет неверный формат, ЗначениеИзСтрокиВнутр вызовет исключение. Оборачивайте вызов в Попытка ... Исключение, если строка приходит извне — из файла, настройки или пользовательского ввода.

Как выполнить произвольный код из строки через Вычислить

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

СтрокаВыражения = "Справочники." + ИмяСправочника + ".НайтиПоКоду(""" + КодСтрокой + """)";

Результат = Вычислить(СтрокаВыражения);

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

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

Сравнение способов и критерии выбора

Выбор метода определяется содержимым строки и требованиями к скорости и безопасности. Таблица ниже помогает быстро сориентироваться.

СпособЧто в строкеОграничения
Справочники[Имя]Имя объекта метаданныхИсключение, если имя не найдено
НайтиПоНаименованиюНаименование элементаНе гарантирует уникальность
НайтиПоКодуКод элементаТребует кодовой нумерации
ПолучитьСсылку(GUID)GUID в виде строкиНе проверяет существование
ЗначениеИзСтрокиВнутрСериализованное значениеРаботает только в той же базе
ВычислитьПроизвольное выражениеРиски безопасности, нет контроля синтаксиса
Маршрут решения

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

Строка — имя справочника или документа из метаданныхИспользуйте Справочники[Имя] или Документы[Имя] с предварительной проверкой через Метаданные.Найти
Строка — наименование или код элементаИспользуйте НайтиПоНаименованию или НайтиПоКоду и проверяйте результат через Пустая()
Строка — GUID из другой базы или обменаСоздайте УникальныйИдентификатор, получите ссылку и проверьте существование запросом
Строка — результат ЗначениеВСтрокуВнутрВосстановите через ЗначениеИзСтрокиВнутр в блоке Попытка
Нужно динамическое выражениеИспользуйте Вычислить только со строкой из проверенных фрагментов

Типичные ошибки и как их избежать

Самая частая ошибка — вызов ПолучитьОбъект() у пустой или несуществующей ссылки. Для пустой ссылки метод вернёт объект с незаполненными данными или вызовет ошибку, для «битой» ссылки — исключение «Объект не найден». Всегда проверяйте Пустая() и, при работе с GUID, существование элемента.

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

Типичные ошибки
01
Вызов ПолучитьОбъект() без проверки Пустая() — исключение или ложная логика
02
ПолучитьСсылку(GUID) принимается за гарантию существования элемента — запись создаст дубликат с чужим GUID
03
Поиск по наименованию без учёта дублей — находится не тот элемент
04
Пользовательский ввод в Вычислить — выполнение произвольного кода
05
ЗначениеИзСтрокиВнутр для переноса данных между базами — строка не раскодируется
Контрольные точки

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

Тип полученного значения
Норма

ТипЗнч возвращает ожидаемый тип ссылки или объекта

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

Неопределено или неожиданный тип — строка обработана неверным способом

Заполненность ссылки
Норма

Ссылка.Пустая() = Ложь

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

Пустая ссылка — элемент не найден

Существование элемента по GUID
Норма

Запрос по ссылке возвращает строку

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

Пустой результат запроса — элемента нет в базе

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

Можно ли получить объект сразу по строке без поиска ссылки?

Нет, промежуточное получение ссылки обязательно. Объект создаётся методом ПолучитьОбъект() именно у ссылки. Сначала находится ссылка (по коду, наименованию, GUID), затем при необходимости модификации из неё получают объект.

Что вернёт НайтиПоНаименованию, если подходящих элементов несколько?

Метод вернёт первый найденный элемент, порядок не гарантирован. Если наименования могут дублироваться, используйте запрос с дополнительными условиями или ищите по уникальному реквизиту — коду, ИНН, артикулу.

Чем отличается Вычислить от Выполнить?

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

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

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

Работает ли ЗначениеИзСтрокиВнутр в файловой и клиент-серверной базе одинаково?

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

Как безопасно обработать строку, пришедшую из внешнего файла?

Определите формат (GUID, код, наименование), проверьте строку регулярным выражением или функциями СтрДлина/СтрНайти, выполните поиск в блоке Попытка и обязательно проверьте результат через Пустая() перед дальнейшей работой.

Итог

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

Строка преобразуется в объект через менеджеры: Справочники[Имя], НайтиПоНаименованию, НайтиПоКоду или ПолучитьСсылку по GUID. Всегда проверяйте результат через Пустая() и существование элемента, а Вычислить используйте только с полностью контролируемыми строками.