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