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