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

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

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

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

В управляемом приложении 1С 8.3 код, выполняемый на клиенте, не имеет прямого доступа к базе данных. Попытка написать в клиентской процедуре конструкцию вида Константы.ОсновнаяВалюта.Получить() приведёт к ошибке компиляции или выполнения, потому что менеджер констант доступен только в серверном контексте. Это архитектурное ограничение тонкого и веб-клиента, а не ошибка конфигурации.

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

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

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

Если в модуле формы с директивой &НаКлиенте написать Значение = Константы.ИмяКонстанты.Получить();, конфигуратор при проверке модуля выдаст ошибку «Переменная не определена (Константы)». В толстом клиенте в режиме обычного приложения такой код мог работать, но в управляемом приложении это недопустимо.

Способ 1: серверная функция в общем модуле

Базовый и самый универсальный вариант — создать общий модуль с включённым свойством «Сервер» и разместить в нём функцию, возвращающую значение константы. Клиентский код вызывает эту функцию, платформа выполняет серверный вызов и возвращает результат.

Порядок действий: в конфигураторе создайте общий модуль, например РаботаСКонстантами. В свойствах модуля установите флажки «Сервер» и «Вызов сервера». Флажок «Клиент (управляемое приложение)» устанавливать не нужно. Добавьте функцию и экспортируйте её:

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

Возврат Константы.ОсновнаяВалюта.Получить();

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

Теперь из любого клиентского кода значение получается одной строкой:

&НаКлиенте

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

Валюта = РаботаСКонстантами.ПолучитьОсновнуюВалюту();

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

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

Способ 2: кэширование через модуль с повторным использованием

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

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

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

Способ 3: получение значения при открытии формы

Когда константа нужна только в конкретной форме, удобно прочитать её один раз при создании формы на сервере и сохранить в реквизит формы. Это исключает повторные серверные вызовы и делает логику прозрачной.

Добавьте в форму реквизит, например ОсновнаяВалюта с типом «СправочникСсылка.Валюты». В обработчике ПриСозданииНаСервере присвойте ему значение константы:

&НаСервере

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

ОсновнаяВалюта = Константы.ОсновнаяВалюта.Получить();

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

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

Способ 4: функциональные опции и параметры сеанса

Если константа является функциональной опцией (логического типа, включающей или отключающей возможность), её значение можно получить на клиенте через метод ПолучитьФункциональнуюОпциюИнтерфейса() — он доступен в клиентском контексте и возвращает значение, влияющее на интерфейс текущего пользователя.

&НаКлиенте

Процедура Команда1(Команда)

Если ПолучитьФункциональнуюОпциюИнтерфейса("ВестиУчетПоСкладам") Тогда

// логика при включённой опции

КонецЕсли;

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

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

Сравнение способов

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

Универсально, но каждый вызов — обращение к серверу. Подходит для разовых обращений.

Кэш на время сеанса

Быстро при многократных обращениях, но значение может устареть внутри сеанса.

Реквизит формы при создании

Один серверный вызов на форму; работает только внутри этой формы.

Функциональная опция интерфейса

Доступна прямо на клиенте, но только для опций логического типа.

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

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

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

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

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

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

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

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

Компиляция модуля
Норма

Ошибок нет, функция видна из клиентского кода

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

«Переменная не определена» или «Метод объекта не обнаружен»

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

Совпадает со значением константы в базе

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

Пустое или устаревшее значение

Количество серверных вызовов
Норма

Один вызов на открытие формы или сеанс

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

Вызов на каждой итерации цикла

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

Итог

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

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

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

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

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

Почему клиент не видит функцию общего модуля?

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

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

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

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

Если используется кэш «На время сеанса», значение обновится только после перезахода пользователя. Либо откажитесь от кэширования для этой константы, либо получайте её свежим серверным вызовом в момент использования.

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

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

Как передать константу в форму, открываемую из другой формы?

Передайте значение через параметры открытия формы: сформируйте структуру параметров с нужным значением и укажите её при вызове ОткрытьФорму(). В открываемой форме значение будет доступно через объект Параметры в обработчике ПриСозданииНаСервере.