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