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

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

1С: как обратиться к перечислению на клиенте

Как обратиться к перечислению на клиенте в 1С: предопределённое значение, ПредопределенноеЗначение, передача с сервера, типичные ошибки и примеры кода.

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

Проблема возникает из-за разделения контекстов исполнения в управляемом приложении. Код с директивой &НаКлиенте выполняется на компьютере пользователя, где нет доступа к менеджерам прикладных объектов. Платформа предлагает обходной путь — функцию ПредопределенноеЗначение(), которая получает значение перечисления по строковому имени без обращения к серверу. Это основной и рекомендуемый способ работы с перечислениями в клиентском коде.

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

Почему прямое обращение к перечислению на клиенте не работает

В управляемом приложении 1С код формы делится на клиентскую и серверную части. Директивы &НаКлиенте и &НаСервере определяют, где выполняется процедура. Менеджеры прикладных объектов — Перечисления, Справочники, Документы — доступны только на сервере, потому что именно там выполняется работа с данными информационной базы.

Поэтому строка Ставка = Перечисления.СтавкиНДС.НДС20; в клиентской процедуре вызовет ошибку компиляции модуля или выполнения. В толстом клиенте обычного приложения такой код мог работать, но в управляемых формах он недопустим. Это не ограничение конкретной конфигурации, а архитектурное правило платформы.

Важно понимать, что само значение перечисления (ссылка на значение) свободно передаётся между клиентом и сервером — оно сериализуется без проблем. Недоступен только способ получения этого значения через менеджер. Значит, задача сводится к тому, как получить значение без менеджера перечислений.

Основной способ: функция ПредопределенноеЗначение

Функция ПредопределенноеЗначение(ИмяЗначения) доступна и на клиенте, и на сервере. Она принимает строку с полным путём к предопределённому значению и возвращает само значение. Для перечисления путь строится по шаблону: Перечисление.<ИмяПеречисления>.<ИмяЗначения>.

&НаКлиенте

Процедура ПриОткрытии(Отказ)

Ставка = ПредопределенноеЗначение("Перечисление.СтавкиНДС.НДС20");

ВидОперации = ПредопределенноеЗначение("Перечисление.ВидыОпераций.Продажа");

КонецПроцедуры

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

Функция также работает для предопределённых элементов справочников, планов счетов и других объектов: ПредопределенноеЗначение("Справочник.Валюты.Рубль"). Это делает её универсальным инструментом для клиентского кода.

bsl
&НаКлиенте
Функция ПолучитьСтавкуНДС()
	Ставка = ПредопределенноеЗначение("Перечисление.СтавкиНДС.НДС20");
	Если Ставка = Неопределено Тогда
		Сообщить("Значение перечисления не найдено — проверьте имя");
	КонецЕсли;
	Возврат Ставка;
КонецФункции

Сравнение значений и проверка заполненности на клиенте

Самая частая задача — не получить значение, а сравнить с ним реквизит объекта. Например, в обработчике ПриИзменении нужно проверить, выбрана ли конкретная ставка НДС. Здесь ПредопределенноеЗначение тоже работает напрямую в условии.

&НаКлиенте

Процедура СтавкаНДСПриИзменении(Элемент)

Если Объект.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкиНДС.БезНДС") Тогда

Объект.СуммаНДС = 0;

КонецЕсли;

КонецПроцедуры

Для проверки заполненности реквизита типа «перечисление» используйте ЗначениеЗаполнено() — она корректно работает на клиенте и возвращает Ложь для пустой ссылки перечисления. Сравнение с пустой ссылкой через ПредопределенноеЗначение("Перечисление.Имя.ПустаяСсылка") тоже допустимо, но обычно избыточно.

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

Передача значений перечисления с сервера на клиент

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

&НаСервереБезКонтекста

Функция ПолучитьВидОперацииПоУмолчанию()

// произвольная серверная логика

Возврат Перечисления.ВидыОпераций.Продажа;

КонецФункции

&НаКлиенте

Процедура ПриОткрытии(Отказ)

ВидОперации = ПолучитьВидОперацииПоУмолчанию();

КонецПроцедуры

Если значение нужно на протяжении всей жизни формы, сохраните его в реквизит формы типа «ПеречислениеСсылка» при создании формы на сервере (ПриСозданииНаСервере). Тогда весь клиентский код будет обращаться к реквизиту без повторных серверных вызовов и без строковых литералов.

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

Способы получить значение перечисления на клиенте

ПредопределенноеЗначение

Подходит для известных заранее значений. Работает без сервера. Ограничение: имя зашито строкой, опечатка обнаружится только в выполнении.

Серверная функция

Подходит, когда значение вычисляется по логике или данным. Ограничение: серверный вызов стоит времени, не используйте в циклах.

Реквизит формы

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

Работа со списком значений перечисления на клиенте

Иногда на клиенте нужно предложить пользователю выбор из значений перечисления — например, заполнить список выбора поля ввода. Получить список всех значений перечисления можно только на сервере, перебрав Метаданные.Перечисления.Имя.ЗначенияПеречисления или коллекцию Перечисления.Имя. На клиенте метаданные перечислений недоступны.

Типовой приём: на сервере формируется СписокЗначений (значение + представление), который передаётся на клиент и назначается элементу формы. СписокЗначений сериализуется без проблем.

&НаСервере

Процедура ЗаполнитьСписокСтавок()

СписокСтавок.Очистить();

Для Каждого ЗначениеПеречисления Из Перечисления.СтавкиНДС Цикл

СписокСтавок.Добавить(ЗначениеПеречисления, Строка(ЗначениеПеречисления));

КонецЦикла;

КонецПроцедуры

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

Как вывести список значений перечисления в поле выбора
  1. 1
    Создайте реквизит формы типа СписокЗначений
  2. 2
    В серверной процедуре переберите значения перечисления и заполните список
  3. 3
    Вызовите серверную процедуру при создании формы или по команде
  4. 4
    Назначьте список свойству СписокВыбора нужного элемента формы
  5. 5
    Проверьте в режиме предприятия: список открывается, значения выбираются и сохраняются

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

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

Вторая частая проблема — опечатка в строковом имени значения. Поскольку имя передаётся строкой, конфигуратор не проверяет её на этапе разработки. Ошибка проявится только в выполнении и только как Неопределено, без сообщения. Чтобы снизить риск, выносите строковые литералы в одну функцию или константную переменную модуля и используйте её везде.

Третья ошибка — лишние серверные вызовы в цикле: например, в обработчике при изменении строки табличной части каждый раз вызывается серверная функция за значением перечисления. При большом числе строк это заметно тормозит форму. Решение — закэшировать значение в реквизит формы или использовать ПредопределенноеЗначение.

Типичные ошибки
01
Вызов Перечисления.Имя.Значение в клиентском коде — ошибка компиляции, форма не открывается
02
Опечатка в строке ПредопределенноеЗначение — функция молча вернёт Неопределено, логика сработает неверно
03
Серверный вызов за значением перечисления внутри цикла — лишняя нагрузка и замедление формы
04
Использование синонима вместо имени метаданных — значение не будет найдено
05
Сравнение значения перечисления со строкой вместо ссылки — условие всегда ложно

Проверка результата и отладка

Чтобы убедиться, что значение получено корректно, выведите его через Сообщить() или проверьте в отладчике. У значения перечисления можно запросить представление через Строка(Значение) — на клиенте это работает, потому что представление передаётся вместе со значением.

Полезные проверки: сравнение результата с Неопределено (значение не найдено), сравнение с ожидаемым значением через = (ссылки перечислений сравниваются корректно), проверка типа через ТипЗнч(). Если ТипЗнч возвращает что-то отличное от ожидаемого типа «ПеречислениеСсылка.Имя», значит, на каком-то этапе значение потерялось или было присвоено неверно.

При отладке управляемых форм помните, что точки останова в клиентском и серверном коде требуют включения отладки соответствующего типа в конфигураторе. Если клиентская процедура не останавливается, проверьте настройки отладки тонкого или веб-клиента.

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

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

Результат ПредопределенноеЗначение
Норма

Возвращено значение, ТипЗнч показывает ПеречислениеСсылка с нужным именем

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

Возвращено Неопределено — имя перечисления или значения указано с ошибкой

Сравнение реквизита со значением
Норма

Условие срабатывает при ожидаемом значении реквизита

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

Условие никогда не срабатывает — сравниваются разные типы или неверное значение

Список выбора поля
Норма

Список содержит все нужные значения с понятными представлениями

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

Список пуст или содержит пустые строки — серверное заполнение не выполнилось

Особенности веб-клиента и мобильного клиента

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

В мобильном клиенте набор доступных возможностей уже: часть функций и типов недоступна. ПредопределенноеЗначение поддерживается, но перед переносом решения на мобильную платформу проверяйте синтакс-помощник по ветке «Мобильный клиент» для каждой используемой конструкции.

Когда какой способ выбирать

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

Если значение вычисляется по данным информационной базы — выносите вычисление на сервер и передавайте результат. Если значение нужно постоянно в течение жизни формы — храните его в реквизите формы. Если нужен список значений для выбора — формируйте СписокЗначений на сервере один раз.

Маршрут решения

Как выбрать способ

Значение известно заранее и фиксированоИспользуйте ПредопределенноеЗначение в клиентском коде
Значение зависит от данных или настроекВычислите в серверной функции и верните на клиент
Значение нужно многократно в течение жизни формыСохраните в реквизит формы при создании на сервере
Нужен список значений для выбораСформируйте СписокЗначений на сервере и назначьте элементу формы

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

Почему Перечисления.Имя.Значение не работает на клиенте?

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

Что вернёт ПредопределенноеЗначение, если имя указано неверно?

Функция вернёт Неопределено без сообщения об ошибке. Поэтому при подозрительном поведении логики проверяйте результат на Неопределено и сверяйте имя с конфигуратором — используется имя метаданных, а не синоним.

Можно ли передать значение перечисления как параметр в клиентскую процедуру?

Да. Значения перечислений сериализуются и свободно передаются между сервером и клиентом — как параметры процедур, возвращаемые значения функций, реквизиты формы. Ограничение касается только способа получения значения через менеджер, а не самого значения.

Как на клиенте проверить, что реквизит типа перечисление не заполнен?

Используйте ЗначениеЗаполнено(Реквизит) — функция работает на клиенте и вернёт Ложь для пустой ссылки. Альтернатива — сравнение с ПредопределенноеЗначение("Перечисление.Имя.ПустаяСсылка"), но обычно оно не требуется.

Работает ли ПредопределенноеЗначение в обычных формах и толстом клиенте?

Да, функция доступна во всех клиентах и на сервере. В толстом клиенте обычного приложения прямое обращение Перечисления.Имя.Значение тоже работает, но ПредопределенноеЗначение делает код переносимым между контекстами и видами клиентов.

Как получить на клиенте представление (синоним) значения перечисления?

Через Строка(Значение) — представление передаётся вместе со значением и доступно на клиенте. Получить синоним через метаданные на клиенте нельзя: объект Метаданные в клиентском контексте недоступен, такие операции выполняются на сервере.

Итог

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

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