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