Как запретить изменение значения константы в 1С: способы и технические нюансы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Использование модуля менеджера значения константы

Разберем базовый механизм, который заложен в платформу. Многие начинающие разработчики пытаются найти модуль у самой константы, как у справочника или документа, но структура этого объекта отличается. У константы существует Модуль менеджера значения. Именно в нем располагается обработчик события ПередЗаписью, который позволяет прервать процесс сохранения данных.

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


Процедура ПередЗаписью(Отказ)
    // Условие, при котором мы запрещаем запись
    Если НЕ РольДоступна("ПолныеПрава") Тогда
        Сообщить("У вас недостаточно прав для изменения этой настройки!");
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

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

Реализация логики через расширения конфигурации

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

Посмотрим на пример использования аннотации &Перед. Это наиболее безопасный способ, так как он выполняется до основного кода (если он там есть) и позволяет сразу «выбросить» отказ:


&Перед("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ)
    // Например, запретим менять константу после определенной даты
    Если ТекущаяДата() > '20231231235959' Тогда
        Отказ = Истина;
        ТекстСообщения = "Редактирование параметров периода 2023 года закрыто.";
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
    КонецЕсли;
КонецПроцедуры

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

Универсальный подход через подписки на события

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

Выясним, как правильно настроить подписку:

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

Пример кода в общем модуле для подписки:


Процедура ЗапретИзмененияКонстантПередЗаписью(Источник, Отказ) Экспорт
    // Источник — это и есть менеджер значения конкретной константы
    ИмяКонстанты = Источник.Метаданные().Имя;
    
    Если ИмяКонстанты = "ИспользоватьВалютныйУчет" Тогда
        Текст = "Запрещено менять валютный учет в текущем сеансе!";
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Текст);
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Различие между Менеджером и Менеджером значения

Проанализируем важный технический момент, на котором часто путаются разработчики. В системе 1С есть два способа обращения к константе через код:

1. Константы.ИмяКонстанты — это объект типа Менеджер константы. Он используется для быстрого получения (Получить()) или установки (Установить()) значения. У него нет своего программного модуля и событий.

2. Константы.ИмяКонстанты.СоздатьМенеджерЗначения() — это объект типа Менеджер значения. Это более «тяжелый» объект, который ведет себя аналогично объектам ссылочных типов. Именно у него есть методы Прочитать(), Записать() и те самые события модуля, о которых мы говорили выше.

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

Альтернатива: ограничение на уровне ролей

Рассмотрим ситуацию, когда писать код вовсе не обязательно. Если запрет должен действовать постоянно для определенных групп пользователей, правильнее использовать механизм прав доступа. У каждой константы в объекте «Роль» есть право «Изменение».

Если снять галочку «Изменение» в роли пользователя, то:

Технические нюансы: Обмен данными и Транзакции

При реализации запрета записи через ПередЗаписью необходимо учитывать два критических фактора:

Во-первых, всегда проверяйте свойство ОбменДанными.Загрузка. Если в базу загружаются данные из другой системы (например, через РИБ), установка Отказ = Истина может привести к остановке всего обмена. Обычно код выглядит так:


Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    // Далее ваша логика запрета
КонецПроцедуры

Во-вторых, помните о транзакционности. Обработчик ПередЗаписью выполняется внутри транзакции. Если константа записывается не сама по себе, а как часть сложного процесса (например, в коде проведения документа обновляется какая-то константа), то ваш Отказ = Истина отменит не только запись константы, но и проведение всего документа. Всегда анализируйте контекст вызова, чтобы не нарушить работу смежных механизмов системы.

← На главную