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

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

Как получить значение константы на клиенте в 1С

Как получить значение константы на клиенте в 1С: КонстантыМенеджер, серверный вызов, кэширование. Примеры кода, ограничения клиентского контекста и типичные ошибки.

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

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

Как устроен доступ к константам в разных клиентах

Константа — это объект метаданных, физически хранящий одно значение в таблице базы данных. Чтение этого значения — обращение к БД, поэтому платформа строго разграничивает, где такой код может выполняться. В управляемом приложении (тонкий клиент, веб-клиент) любое прямое обращение к данным возможно только на сервере.

В клиентском модуле формы с директивой &НаКлиенте обращение Константы.ВалютаУчета.Получить() вызовет ошибку компиляции или выполнения: менеджер констант недоступен в клиентском контексте управляемого приложения. Исключение — толстый клиент обычного приложения, где клиент и сервер фактически совмещены, и прямой вызов работает.

Прямое чтение в толстом клиенте обычного приложения

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

// Чтение значения константы

Валюта = Константы.ВалютаРегламентированногоУчета.Получить();

// Альтернатива через менеджер константы

МенеджерКонстанты = Константы.ВалютаРегламентированногоУчета.СоздатьМенеджерЗначения();

МенеджерКонстанты.Прочитать();

Валюта = МенеджерКонстанты.Значение;

Первый вариант короче и подходит для простого чтения. Второй нужен, когда требуется и прочитать, и изменить значение в рамках одной операции. Учтите, что Получить() каждый раз обращается к базе: в циклах и часто вызываемых обработчиках такое чтение стоит заменить переменной, заполненной один раз.

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

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

// Общий модуль ОбщегоНазначенияСервер

// Флаги: Сервер = Истина, Вызов сервера = Истина

&НаСервере

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

Возврат Константы.ВалютаРегламентированногоУчета.Получить();

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

// Клиентский код формы

&НаКлиенте

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

ВалютаУчета = ОбщегоНазначенияСервер.ПолучитьВалютуУчета();

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

Обязательное условие: у общего модуля должны быть установлены флаги «Сервер» и «Вызов сервера». Без флага «Вызов сервера» обращение из клиентского контекста к серверной функции вызовет ошибку «Процедура или функция с указанным именем не определена».

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

Чтение константы через реквизиты формы и модуль менеджера

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ВалютаУчета = Константы.ВалютаРегламентированногоУчета.Получить();

ИспользоватьХарактеристики = Константы.ИспользоватьХарактеристикиНоменклатуры.Получить();

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

Здесь ВалютаУчета и ИспользоватьХарактеристики — реквизиты формы, созданные в конфигураторе. Такой подход предпочтительнее вызова из ПриОткрытии: чтение происходит один раз при создании формы, а не при каждом её открытии с отдельным серверным вызовом из клиентского обработчика.

Кэширование значений констант для снижения числа серверных вызовов

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

// Клиентский общий модуль

&НаКлиенте

Перем ВалютаУчетаКэш;

&НаКлиенте

Функция ВалютаУчета() Экспорт

Если ВалютаУчетаКэш = Неопределено Тогда

ВалютаУчетаКэш = ОбщегоНазначенияСервер.ПолучитьВалютуУчета();

КонецЕсли;

Возврат ВалютаУчетаКэш;

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

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

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

Прямой вызов Константы.Имя.Получить()

Только толстый клиент обычного приложения. Просто, но не работает в управляемом приложении

Серверная функция общего модуля

Универсально для тонкого и веб-клиента. Требует флага «Вызов сервера», каждый вызов — обращение к серверу

Чтение в ПриСозданииНаСервере

Оптимально для форм: значение попадает в реквизит один раз, дальше клиент работает локально

Кэш в клиентском модуле или параметры сеанса

Для часто используемых редко меняющихся значений. Риск устаревания при изменении константы в том же сеансе

Ограничения и типичные ошибки

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

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

Типичные ошибки
01
Вызов Константы.Имя.Получить() в клиентском коде управляемого приложения — ошибка компиляции или выполнения, так как менеджер констант недоступен на клиенте
02
Отсутствие флага «Вызов сервера» у общего модуля — клиент не видит серверную функцию, возникает ошибка «процедура не определена»
03
Чтение константы в цикле или при каждом обращении — лишние серверные вызовы и заметное замедление интерфейса
04
Попытка вернуть с сервера несериализуемое значение (таблицу значений, COM-объект) — ошибка передачи данных
05
Кэширование константы, которая может измениться в том же сеансе, — код работает с устаревшим значением

Отдельно проверяйте права: если у пользователя нет права чтения на константу, серверная функция завершится ошибкой нарушения прав доступа. Для регламентных чтений, не зависящих от пользователя, используйте привилегированный режим (УстановитьПривилегированныйРежим(Истина)) или общий модуль с флагом «Привилегированный режим» — но только там, где это безопасно, чтобы не раскрыть пользователю данные, которые ему видеть не положено.

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

Простейшая проверка — вывести полученное значение через Сообщить() или в поле формы и сравнить с тем, что видно в интерфейсе настройки констант. В тонком клиенте удобно временно разместить значение в реквизите формы типа «Строка» и убедиться, что оно заполнено.

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

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

Значение в клиентском коде
Норма

Переменная содержит ожидаемое значение нужного типа

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

Неопределено или пустое значение при заполненной константе — проверяйте серверную функцию

Флаги общего модуля
Норма

Установлены «Сервер» и «Вызов сервера»

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

Нет «Вызов сервера» — клиентский вызов невозможен

Права пользователя
Норма

Есть право чтения на константу

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

Ошибка нарушения прав доступа при вызове

Число серверных вызовов
Норма

Чтение происходит один раз за открытие формы или сеанс

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

Вызов на каждое обращение — нужен кэш

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

Итог

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

В управляемом приложении константа читается только на сервере: создайте серверную функцию в общем модуле с флагом «Вызов сервера» или прочитайте значение в ПриСозданииНаСервере и передайте его клиенту через реквизит формы. Часто используемые значения кэшируйте. В обычном приложении доступен прямой вызов Константы.Имя.Получить().

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

Можно ли получить константу на клиенте без серверного вызова?

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

Почему возникает ошибка «Процедура или функция не определена» при вызове серверной функции?

Чаще всего у общего модуля не установлен флаг «Вызов сервера», либо функция не объявлена экспортной. Реже причина в том, что модуль имеет только флаг «Клиент», и его серверный контекст недоступен. Проверьте свойства модуля в конфигураторе.

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

Создайте серверную функцию, которая собирает нужные значения в структуру и возвращает её: Результат = Новый Структура("Валюта, Организация", ...). Структура с примитивными типами и ссылками свободно передаётся на клиент, а вы получаете один серверный вызов вместо нескольких.

Работает ли Константы.Имя.Получить() в мобильном клиенте?

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

Константа изменилась, а клиент видит старое значение. Что делать?

Это признак кэширования: значение было прочитано один раз и сохранено в переменной модуля или реквизите формы. Решение — либо перечитывать константу при каждом обращении, либо сбрасывать кэш при записи константы (например, через оповещение форм ОповеститьОбИзменении), либо использовать обновление повторно используемых значений через ОбновитьПовторноИспользуемыеЗначения().