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