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