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