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