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