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