К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как обновить элемент формы программно и вручную

Как обновить элемент формы в 1С: методы ОбновитьОтображениеДанных, ЭлементыФормы, Обновить. Примеры кода для управляемых и обычных форм, типичные ошибки.

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

В 1С существует несколько способов обновить элемент формы, и выбор зависит от типа формы (обычная или управляемая), от того, что именно изменилось (реквизит объекта, таблица значений, динамический список, оформление), и от того, где выполняется код — на клиенте или на сервере. Неправильно выбранный метод либо не даст эффекта, либо вызовет лишние серверные обращения и замедлит работу.

Ниже разобраны рабочие методы обновления для управляемых и обычных форм, команды для динамических списков и табличных частей, а также типичные ошибки, из-за которых элемент «не обновляется», хотя код вроде бы написан верно.

Как устроено обновление формы в 1С

Форма в 1С — это не «живой» экран, который сам следит за данными. Платформа связывает элементы формы с реквизитами через механизм отображения данных: когда реквизит меняется стандартным образом (пользователь ввёл значение, сработал обработчик), платформа сама перерисовывает связанные элементы. Но если данные изменились программно — в серверной процедуре, в фоновом задании, из другой формы — форма об этом «не знает», и отображение нужно обновить явно.

Отсюда три основных сценария, когда требуется ручное обновление: после программного изменения реквизитов на сервере с последующим возвратом на клиент; после изменения данных объекта вне текущей формы (другая форма, обмен, фоновое задание); после изменения условного оформления, доступности или видимости, когда платформа не пересчитала представление элемента.

Обновление элемента в управляемой форме

Управляемые формы используются в большинстве современных конфигураций (1С:Бухгалтерия 3, УТ 11, ERP и др.). Здесь доступны два основных метода. Первый — Элементы.ИмяЭлемента.Обновить() — обновляет конкретный элемент: поле, таблицу, надпись. Второй — ЭтотОбъект.ОбновитьОтображениеДанных() — заставляет форму перечитать все реквизиты и перерисовать все связанные элементы разом.

Типичный пример: после серверного пересчёта итогов нужно обновить табличную часть и поле суммы.

&НаКлиенте

Процедура ПересчитатьИтоги(Команда)

ПересчитатьИтогиНаСервере();

Элементы.Товары.Обновить();

ЭтотОбъект.ОбновитьОтображениеДанных();

КонецПроцедуры

Метод ОбновитьОтображениеДанных() можно вызывать и с параметром — конкретным реквизитом формы, чтобы не перерисовывать всё подряд. Это полезно на тяжёлых формах с большим числом элементов, где полное обновление заметно «подтормаживает» интерфейс.

Обновление динамического списка и табличной части

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

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

Если нужно не просто перечитать список, а изменить его содержимое (например, применить новый отбор), обновление выполняется через изменение параметров компоновки: Список.Параметры.УстановитьЗначениеПараметра("Период", НоваяДата) — после этого список перезапрашивает данные автоматически, отдельный вызов Обновить() обычно не требуется.

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

Порядок действий при «зависшем» элементе
  1. 1
    Определите, где менялись данные: на клиенте, на сервере или вне формы
  2. 2
    Если меняли на сервере — добавьте на клиенте Элементы.ИмяЭлемента.Обновить()
  3. 3
    Если менялся объект в базе вне формы — вызовите ЭтотОбъект.Прочитать()
  4. 4
    Если изменилась другая форма — используйте ОповеститьОбИзменении() с типом объекта
  5. 5
    Проверьте в отладчике: значение реквизита изменилось, а отображение нет — проблема именно в обновлении
  6. 6
    Проверьте результат в пользовательском режиме под реальной учётной записью

Обновление элемента в обычной форме

Обычные формы встречаются в старых конфигурациях на платформе 8.2 и в решениях, не переведённых на управляемый интерфейс. Синтаксис отличается: коллекция элементов называется ЭлементыФормы, а метод обновления доступен почти у каждого элемента.

ЭлементыФормы.Товары.Обновить();

ЭлементыФормы.НадписьИтог.Заголовок = "Итого: " + Формат(СуммаИтог, "ЧДЦ=2");

ЭлементыФормы.СписокДокументов.ОбновитьСтроки();

Для табличных полей в обычных формах есть метод ОбновитьСтроки() — он перечитывает данные источника (например, табличной части или регистра) и перерисовывает строки. Для полей ввода часто достаточно присвоить новое значение связанному реквизиту — обычная форма обновляет отображение автоматически, в отличие от управляемой.

Сравнение вариантов

Элементы.Имя.Обновить()

Точечное обновление одного элемента. Быстро, экономно. Подходит, когда известно, что именно изменилось.

ОбновитьОтображениеДанных()

Обновляет все элементы формы разом. Проще в использовании, но на тяжёлых формах может вызывать задержки.

ЭтотОбъект.Прочитать()

Перечитывает объект из базы целиком. Нужен, когда данные изменил другой сеанс или фоновое задание. Есть риск потерять несохранённые правки пользователя.

ОповеститьОбИзменении()

Уведомляет все открытые формы об изменении объекта. Правильный способ при изменении данных из другой формы.

Обновление при изменении данных из другой формы

Частая ситуация: пользователь открыл форму элемента справочника из формы списка, изменил и записал объект, а в списке осталось старое наименование. Здесь локальное обновление не поможет — нужен механизм оповещений между формами.

Стандартный приём — вызвать ОповеститьОбИзменении(Ссылка) после записи объекта. Все открытые динамические списки, отображающие этот тип данных, получат сигнал и перечитают изменённую строку. Для нестандартных сценариев используют пару Оповестить("ИмяСобытия", Параметры, Источник) на одной форме и обработчик ОбработкаОповещения(ИмяСобытия, Параметр, Источник) на другой.

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ИзмененыЦеныНоменклатуры" Тогда

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

КонецЕсли;

КонецПроцедуры

Типичные ошибки и их признаки

Самая распространённая ошибка — обновление элемента, который не привязан к изменённым данным. Например, программист меняет реквизит СуммаДокумента, а обновляет элемент Элементы.Товары. Элемент честно перерисуется, но покажет то же, что и раньше. Проверяйте свойство ПутьКДанным элемента — оно должно указывать на изменённый реквизит.

Вторая ошибка — вызов Обновить() на сервере. В управляемой форме элементы формы доступны как на клиенте, так и на сервере, но визуальное обновление имеет смысл только на клиенте: серверная процедура завершится, а команда обновления либо не выполнится, либо приведёт к лишнему вызову. Правило простое: сервер меняет данные, клиент обновляет отображение.

Третья ошибка — ожидание, что ОбновитьОтображениеДанных() перечитает данные из базы. Метод работает только с реквизитами формы в памяти. Если объект изменил другой пользователь, без Прочитать() форма покажет старые данные, сколько бы раз вы её ни обновляли.

Типичные ошибки
01
Вызов Обновить() в серверной процедуре — отображение не меняется, впустую тратится серверный вызов
02
Обновление элемента, не связанного с изменённым реквизитом — на экране остаётся старое значение
03
Ожидание, что ОбновитьОтображениеДанных() перечитает базу — метод работает только с данными формы в памяти
04
Прочитать() без проверки модифицированности — теряются несохранённые правки пользователя
05
Обновление списка вместо изменения параметров отбора — список перечитывается, но с прежними условиями

Проверка результата и ограничения

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

Учитывайте ограничения платформы. В тонком и веб-клиенте частые обновления тяжёлых таблиц заметно нагружают канал связи — не вызывайте Обновить() в цикле по строкам, обновляйте один раз после завершения обработки. Фоновые задания не имеют доступа к форме: чтобы показать результат длительной операции, используйте оповещения или периодический опрос состояния задания с последующим обновлением элементов на клиенте.

Контрольные точки

Как проверить результат

Значение реквизита в отладчике
Норма

Реквизит содержит новое значение после изменения

Тревожный признак

Значение старое — ошибка в логике изменения данных, а не в обновлении

Отображение на форме
Норма

Элемент показывает новое значение без перезакрытия формы

Тревожный признак

Значение обновляется только после переоткрытия — не вызван метод обновления

Свойство ПутьКДанным элемента
Норма

Указывает на реквизит, который реально изменяется

Тревожный признак

Привязка к другому реквизиту — обновление не даст эффекта

Поведение при работе других пользователей
Норма

Изменения из других сеансов появляются после Прочитать() или оповещения

Тревожный признак

Форма показывает устаревшие данные до перезакрытия

Итог

Что важно запомнить

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

Частые вопросы

Почему элемент не обновляется, хотя вызван Обновить()?

Чаще всего элемент не привязан к изменённым данным: проверьте свойство ПутьКДанным. Вторая причина — данные изменились в базе, но не в реквизитах формы; тогда сначала вызовите ЭтотОбъект.Прочитать() или перезаполните реквизит программно.

Чем отличается Обновить() от ОбновитьОтображениеДанных()?

Обновить() — метод конкретного элемента (таблицы, списка), он перечитывает источник данных элемента. ОбновитьОтображениеДанных() — метод формы, он перерисовывает все элементы по текущим значениям реквизитов, не обращаясь к базе.

Как обновить форму списка после записи элемента?

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

Можно ли обновить форму из фонового задания?

Напрямую нет: фоновое задание выполняется на сервере и не имеет доступа к клиентской форме. Используйте механизм длительных операций БСП или периодический опрос состояния задания из формы с последующим обновлением элементов на клиенте.

Как обновить условное оформление или видимость элемента?

Условное оформление динамических списков и форм пересчитывается платформой автоматически при изменении данных, от которых оно зависит. Если оформление «застряло», помогает ОбновитьОтображениеДанных(). Для программно установленной видимости достаточно присвоить Элементы.Имя.Видимость новое значение — обновление происходит сразу.

Работает ли Обновить() в мобильном клиенте и веб-клиенте?

Да, методы обновления элементов и формы доступны во всех клиентах. Различия только в производительности: в веб-клиенте каждое обновление — это обмен с сервером, поэтому точечное обновление элементов предпочтительнее полного ОбновитьОтображениеДанных().