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