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