Как обновить данные формы и табличной части после их программного изменения в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Рассмотрим довольно распространенную ситуацию при разработке в 1С:Предприятие. У нас есть форма документа, внутри которой расположена табличная часть с перечнем других документов. Из первого (основного) документа вызывается внешняя обработка, которая программно модифицирует данные документов в этой табличной части. Однако после завершения обработки изменения не отображаются. Проанализируем эту ситуацию и разберем по шагам, как заставить форму показывать актуальные данные. Для реализации аналогичного сценария на практике можно использовать готовую обработку для обновления формы документа после работы внешней печатной формы.

Почему данные не обновляются даже при переоткрытии документа?

Многие разработчики сталкиваются с тем, что даже если сохранить текущий документ, закрыть форму и открыть ее заново, данные в табличной части остаются старыми. Обновление происходит только после полного перезапуска клиентского приложения. Выясним причину такого поведения.

Такое поведение напрямую связано с механизмами кэширования платформы 1С:Предприятие. Для того чтобы ускорить работу пользовательского интерфейса и снизить количество обращений к серверу баз данных, платформа агрессивно кэширует данные ссылочных объектов. В кэш попадают представления ссылок и те реквизиты, которые мы получаем "через точку".

Когда внешняя обработка программно изменяет документы из табличной части и записывает их, кэш текущего клиентского сеанса ничего об этом не знает. При закрытии и повторном открытии формы платформа решает сэкономить ресурсы: она не выполняет запрос к базе данных, а просто берет уже имеющиеся (но устаревшие) значения из локального кэша сеанса. Именно поэтому кажется, что изменения не применились.

Решение проблемы с помощью метода ОповеститьОбИзменении

Чтобы платформа "забыла" старые данные и запросила новые с сервера, мы должны инвалидировать (сбросить) кэш для конкретных ссылок. Для этих целей в 1С предусмотрен специальный метод ОповеститьОбИзменении. Посмотрим на примеры его правильного и неправильного использования.

Разберем частую ошибку. Разработчик пытается обновить данные, написав следующий код:

ОповеститьОбИзменении(Объект.Ссылка);

Этот код оповещает систему об изменении самого открытого документа, но не тех документов, которые лежат в его табличной части. Поэтому данные в таблице не меняются. Также ошибкой будет передача типа текущего документа с помощью ТипЗнч(Объект.Ссылка).

Рассмотрим два правильных варианта использования этого метода для нашей задачи:

  1. Обход в цикле: Если мы точно знаем, какие ссылки были изменены, мы можем перебрать табличную часть и оповестить платформу по каждой строке отдельно.
    
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        ОповеститьОбИзменении(СтрокаТЧ.ДокументПартии);
    КонецЦикла;
    
  2. Передача типа документа: Если в табличной части лежат документы одного типа (например, реализация товаров), мы можем сбросить кэш сразу для всех ссылок данного типа. Это гораздо эффективнее, чем вызывать метод в цикле. ОповеститьОбИзменении(Тип("ДокументСсылка.РеализацияТоваровУслуг"));

При использовании второго варианта платформа поймет, что кэш для указанного типа документов устарел, и при следующем обращении к форме заново вытянет актуальные данные с сервера.

Дополнительные способы программного обновления данных на форме

Помимо сброса кэша ссылок, в арсенале разработчика 1С есть и другие методы для принудительного обновления отображения данных непосредственно в открытом окне без его переоткрытия. Проанализируем их подробнее.

1. Метод Прочитать()

Метод ЭтаФорма.Прочитать() заставляет текущую форму заново считать данные основного объекта из базы данных. Это полезно в случаях, когда обработка меняет не только подчиненные документы, но и сам текущий документ (например, пересчитывает итоги). При вызове этого метода форма полностью обновляется из БД.

2. Обновление отображения данных

Метод ЭтаФорма.ОбновитьОтображениеДанных() принудительно перерисовывает элементы формы. Важно понимать, что он не читает данные из базы заново, а лишь обновляет элементы интерфейса на основе уже имеющихся в памяти данных. Эффективен при изменении видимости или доступности элементов.

3. Точечное обновление табличной части

Если мы хотим обновить только конкретную таблицу на форме, следует использовать метод Обновить() для элемента управления: Элементы.ИмяТабличнойЧасти.Обновить(). Это заставит платформу перерисовать список.

4. Использование глобального оповещения

Чтобы форма автоматически обновилась сразу после того, как внешняя обработка закончит свою работу, мы можем использовать связку методов Оповестить() и события ОбработкаОповещения.

В модуле внешней обработки после записи документов вызываем:

Оповестить("ДанныеТабличнойЧастиИзменены");

А в модуле формы нашего основного документа размещаем обработчик:


&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ДанныеТабличнойЧастиИзменены" Тогда
        // Сбрасываем кэш
        ОповеститьОбИзменении(Тип("ДокументСсылка.ИмяДокументаИзТабличнойЧасти"));
        // Обновляем саму таблицу на форме
        Элементы.ИмяТабличнойЧасти.Обновить();
    КонецЕсли;
КонецПроцедуры

Комбинируя эти подходы, мы можем гарантировать, что пользователи всегда будут видеть актуальные данные на формах 1С, избегая неприятных сюрпризов с кэшированием платформы.

← На главную