Разработка и Конфигурация · 11 мин
Как в 1С найти перечисление по синониму
Как найти перечисление по синониму в 1С: поиск по конфигуратору, запрос через Метаданные, обход значений перечисления и проверка результата.
В типовых и самописных конфигурациях 1С разработчик часто помнит, как перечисление называется «по-человечески» — то есть его синоним, — но не знает внутреннее имя объекта метаданных. Синоним «Статусы заказа» и имя СтатусыЗаказовПоставщикам могут существенно отличаться, и простой поиск по дереву конфигурации не помогает.
Задача решается тремя способами: полнотекстовым поиском по конфигуратору, программным обходом коллекции Метаданные.Перечисления с сравнением свойства Синоним и поиском через глобальный поиск по модулям, если синоним встречается в коде. Ниже разобраны все варианты с готовым кодом.
Важно понимать различие: искать можно как само перечисление (объект метаданных), так и конкретное значение перечисления по его синониму. Оба сценария рассмотрены отдельно, потому что код для них разный.
Чем синоним отличается от имени и почему это важно
Имя перечисления — это идентификатор, по которому объект доступен в коде: Перечисления.ВидыОпераций. Имя не может содержать пробелов, кириллица допустима, но на практике имена часто укорочены или сокращены. Синоним — это представление объекта для пользователя: именно его видит бухгалтер в интерфейсе, в заголовках форм и в отчётах.
Из-за этого возникает типичная ситуация: пользователь сообщает «ошибка в перечислении Способ доставки», а в конфигурации объект называется СпособыДоставкиЗаказов или вовсе СпособыДоставки_УТ. Поиск по имени ничего не даст, а по синониму объект находится за секунды.
Дополнительная сложность — многоязычные конфигурации. Свойство Синоним в коде возвращает строку на языке по умолчанию, а если нужен конкретный язык, используется метод ПолучитьСиноним(КодЯзыка) — для значений перечисления доступен аналогичный механизм через объект описания метаданных.
Быстрый поиск через конфигуратор без кода
Если задача разовая — найти объект и открыть его свойства, — проще всего воспользоваться поиском по конфигурации. Откройте конфигуратор, разверните дерево конфигурации и нажмите Ctrl+Shift+F (глобальный поиск). Введите текст синонима, например «Способ доставки», и запустите поиск по всей конфигурации.
Поиск найдёт строку в свойствах объектов метаданных, в модулях, в макетах и в текстах запросов. Двойной клик по результату в окне свойств объекта перенесёт вас к нужному перечислению. Минус способа — много лишних совпадений: синоним встретится и в подсказках, и в заголовках реквизитов.
Альтернатива — окно «Поиск ссылок в объектах» не подходит: оно ищет ссылки на данные, а не метаданные. Для метаданных существует механизм «Поиск ссылок на объект метаданных», но он работает в обратную сторону — от известного объекта к местам использования.
- 1Откройте конфигуратор и дерево конфигурации
- 2Нажмите Ctrl+Shift+F и введите текст синонима
- 3Запустите поиск по всей конфигурации
- 4Отфильтруйте результаты: нужны строки из свойств объектов метаданных
- 5Двойным кликом перейдите к найденному перечислению и сверьте имя
Программный поиск перечисления по синониму
Универсальный способ — функция, которая перебирает коллекцию Метаданные.Перечисления и сравнивает синоним каждого объекта с искомой строкой. Такой код работает и в толстом клиенте, и в тонком, и на сервере.
Функция НайтиПеречислениеПоСинониму(ИскомыйСиноним)
Для Каждого ОбъектМД Из Метаданные.Перечисления Цикл
Если НРег(ОбъектМД.Синоним) = НРег(ИскомыйСиноним) Тогда
Возврат ОбъектМД.Имя;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция возвращает внутреннее имя перечисления или Неопределено, если совпадений нет. Сравнение через НРег() делает поиск нечувствительным к регистру — это почти всегда оправдано, потому что пользовательский ввод редко совпадает по регистру с точным написанием синонима.
Если точное совпадение не требуется, замените сравнение на поиск подстроки: СтрНайти(НРег(ОбъектМД.Синоним), НРег(ИскомыйСиноним)) > 0. Учтите, что нечёткий поиск может вернуть несколько объектов — тогда функцию стоит переделать так, чтобы она возвращала массив имён, а не первое совпадение.
Для Каждого ОбъектМД Из Метаданные.Перечисления Цикл
Если СтрНайти(НРег(ОбъектМД.Синоним), НРег("доставка")) > 0 Тогда
Сообщить(ОбъектМД.Имя + " — " + ОбъектМД.Синоним);
КонецЕсли;
КонецЦикла;Поиск значения перечисления по синониму
Отдельная задача — найти не само перечисление, а конкретное значение внутри него по синониму. Например, пользователь указал «Курьером», а нужно получить ссылку Перечисления.СпособыДоставки.КурьерскаяДоставка.
Значения перечисления хранятся в коллекции ЗначенияПеречисления объекта метаданных. У каждого элемента есть Имя и Синоним. Перебор выглядит так:
Функция НайтиЗначениеПоСинониму(ИмяПеречисления, ИскомыйСиноним)
ОбъектМД = Метаданные.Перечисления[ИмяПеречисления];
Для Каждого ЗначениеМД Из ОбъектМД.ЗначенияПеречисления Цикл
Если НРег(ЗначениеМД.Синоним) = НРег(ИскомыйСиноним) Тогда
Возврат Перечисления[ИмяПеречисления][ЗначениеМД.Имя];
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Обратите внимание на финальную строку: чтобы получить именно ссылку-значение, а не объект метаданных, используется обращение Перечисления[ИмяПеречисления][ИмяЗначения]. Частая ошибка — вернуть ЗначениеМД и попытаться записать его в реквизит документа: объект метаданных не является значением перечисления, и присвоение вызовет ошибку несоответствия типов.
Поиск по всем перечислениям сразу
Когда имя перечисления тоже неизвестно — известен только синоним значения, — приходится обходить всю коллекцию перечислений и внутри каждого перебирать значения. Это двойной цикл, но коллекции метаданных невелики, и на практике такой обход выполняется мгновенно.
Функция НайтиЗначениеПоСинонимуГлобально(ИскомыйСиноним)
Для Каждого ОбъектМД Из Метаданные.Перечисления Цикл
Для Каждого ЗначениеМД Из ОбъектМД.ЗначенияПеречисления Цикл
Если НРег(ЗначениеМД.Синоним) = НРег(ИскомыйСиноним) Тогда
Возврат Перечисления[ОбъектМД.Имя][ЗначениеМД.Имя];
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Неопределено;
КонецФункции
У глобального поиска есть особенность: одинаковые синонимы встречаются в разных перечислениях. «Новый» может быть значением и «СтатусовЗаказа», и «СостоянийДокумента». Функция вернёт первое попавшееся совпадение, которое может оказаться не тем. Для ответственных сценариев собирайте все совпадения в массив и логируйте их, чтобы заметить неоднозначность.
Проверка результата и границы метода
После того как функция вернула результат, обязательно проверьте его на Неопределено перед использованием. Если поиск используется при загрузке данных из файлов или обмене, ненайденное значение — штатная ситуация, и её нужно обрабатывать: записывать в журнал регистрации, а не прерывать обмен исключением.
Проверить корректность найденного значения можно сравнением типа: ТипЗнч(НайденноеЗначение) = Тип("ПеречислениеСсылка." + ИмяПеречисления). Это защитит от ситуации, когда нечёткий поиск вернул значение из другого перечисления с похожим синонимом.
Как проверить результат
Тип ПеречислениеСсылка нужного перечисления
Неопределено или объект описания метаданных
Синоним встречается ровно в одном перечислении
Несколько перечислений содержат одинаковый синоним
У всех значений перечисления синонимы заполнены
Часть значений имеет пустой синоним и не находится поиском
Ограничение метода: поиск по синониму работает только в рамках текущего языка конфигурации по умолчанию. Если конфигурация многоязычная и синоним задан на другом языке, простое сравнение свойства Синоним его не найдёт. Также метод не подходит для поиска по представлению предопределённых данных — там используется другое хранение.
Когда поиск по синониму — плохое решение
Поиск по синониму уместен для разовой диагностики, отладки и обработок загрузки, где источник данных содержит пользовательские названия. Но в продуктивной логике привязываться к синонимам небезопасно: синоним может изменить администратор или разработчик при очередном обновлении, и код молча перестанет находить значение.
Для постоянной логики используйте внутренние имена значений — они стабильнее. Если нужна гибкость при обмене с внешними системами, заведите регистр сведений сопоставления «внешнее название → значение перечисления» вместо поиска по синониму на лету. Это даёт контроль над соответствиями и понятную диагностику ошибок.
Как выбрать подход
FAQ
Можно ли найти перечисление по синониму через запрос?
Нет, запросы работают с данными, а не с метаданными. Коллекция Метаданные.Перечисления доступна только из встроенного языка. Запросом можно искать разве что значения перечисления по представлению в таблицах, но это ненадёжный путь.
Почему поиск не находит значение, хотя синоним совпадает?
Чаще всего причины три: разный регистр букв (используйте НРег с обеих сторон), лишние пробелы в искомой строке (примените СокрЛП) или синоним задан на другом языке многоязычной конфигурации.
Как получить синоним на конкретном языке?
У объектов метаданных есть метод получения представления с указанием кода языка. Для значений перечисления синоним на нужном языке извлекается через объект описания метаданных с передачей кода языка, например «en».
Что вернёт функция, если синоним пустой?
Свойство Синоним вернёт пустую строку, и сравнение с искомым текстом не сработает, даже если в интерфейсе значение отображается именем. Добавьте в условие запасной вариант: сравнение с именем значения, когда синоним пуст.
Быстро ли работает перебор всех перечислений?
Да. Коллекции метаданных загружены в память, и даже в крупной конфигурации с сотнями перечислений двойной цикл выполняется за доли секунды. Проблемы с производительностью возникнут только при вызове поиска внутри массового цикла — тогда результат стоит кэшировать в соответствие.
Можно ли искать по синониму в управляемом приложении на клиенте?
Да, коллекция Метаданные доступна и на тонком клиенте. Но если функция вызывается часто, разумнее выполнить поиск один раз на сервере и передать клиенту готовое соответствие «синоним → значение».
Что важно запомнить
Перечисление по синониму ищут перебором Метаданные.Перечисления со сравнением свойства Синоним через НРег(). Для значений перечисления перебирают ЗначенияПеречисления и преобразуют имя в ссылку через Перечисления[Имя][ИмяЗначения]. В постоянной логике синонимы ненадёжны — используйте внутренние имена или регистр сопоставления.