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