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