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

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

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

Как обновить форму в 1С с сервера: методы ОбновитьДанные, Прочитать, ОбновитьИнтерфейс, перечитывание объекта. Примеры кода, ошибки и проверка результата.

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

В 1С нет единственной команды «обновить форму с сервера». Есть несколько механизмов с разной глубиной обновления: перечитывание реквизитов формы, перечитывание всего объекта, обновление динамического списка, обновление интерфейса клиентского приложения и программная обработка оповещений. Выбор зависит от того, что именно изменилось на сервере: сам открытый объект, данные в списке или состав элементов интерфейса.

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

Что именно нужно обновить: определяем сценарий

Прежде чем писать код, определите, какие данные устарели. От этого зависит метод обновления и его «цена» по производительности. Обновление всего объекта — тяжёлая операция с перечитыванием из базы, а обновление строки списка — лёгкая.

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

Маршрут решения

Как выбрать действие

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

Перечитывание объекта формы через Прочитать

Метод Прочитать() управляемой формы заново загружает объект из базы данных на сервере и передаёт актуальные данные в форму. Это самый прямой способ «обновить форму с сервера», когда открыт конкретный объект. Вызов выполняется в серверном контексте формы:

&НаСервере

Процедура ОбновитьДанныеНаСервере()

ЭтаФорма.Прочитать();

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

&НаКлиенте

Процедура ОбновитьДанные(Команда)

ОбновитьДанныеНаСервере();

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

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

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

&НаКлиенте

Процедура ОбновитьДанные(Команда)

Если Модифицированность Тогда

ОписаниеОповещения = Новый ОписаниеОповещения("ОбновитьДанныеЗавершение", ЭтотОбъект);

ПоказатьВопрос(ОписаниеОповещения,

НСтр("ru = 'Несохранённые изменения будут потеряны. Продолжить?'"),

РежимДиалогаВопрос.ДаНет);

Возврат;

КонецЕсли;

ОбновитьДанныеНаСервере();

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

Обновление динамического списка и таблиц формы

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

&НаКлиенте

Процедура ОбновитьСписок(Команда)

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

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

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

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

Обновление интерфейса через ОбновитьИнтерфейс

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

&НаКлиенте

Процедура ПослеЗаписиНастроек()

ОбновитьИнтерфейс();

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

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

Оповещения между формами: Оповестить и ОбработкаОповещения

Когда изменение сделано в одной форме (например, записан документ), а отобразить его нужно в другой открытой форме, используется механизм оповещений. В форме-источнике после записи вызывается Оповестить(), в форме-приёмнике объявляется обработчик ОбработкаОповещения.

&НаКлиенте

Процедура ПослеЗаписи(ПараметрыЗаписи)

Оповестить("ЗаписанДокументРеализация", Объект.Ссылка);

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

// В форме-приёмнике:

&НаКлиенте

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

Если ИмяСобытия = "ЗаписанДокументРеализация" Тогда

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

КонецЕсли;

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

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

Порядок настройки оповещения об изменении объекта
  1. 1
    В форме, где объект записывается, после записи вызовите ОповеститьОбИзменении(Объект.Ссылка)
  2. 2
    В форме, которая должна реагировать, объявите процедуру ОбработкаОповещения с директивой &НаКлиенте
  3. 3
    Внутри обработчика проверьте ИмяСобытия или тип параметра, чтобы не реагировать на чужие оповещения
  4. 4
    Выполните нужное обновление: Элементы.Список.Обновить() или серверный вызов перечитывания
  5. 5
    Проверьте, что обе формы открыты и оповещение доходит: временно добавьте Сообщить() в обработчик

Автоматическое обновление по таймеру и фоновые задания

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

ПодключитьОбработчикОжидания("ПроверитьИзменения", 30, Ложь);

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

&НаКлиенте

Процедура ПроверитьИзменения()

Если ЕстьИзмененияНаСервере() Тогда

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

КонецЕсли;

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

&НаСервере

Функция ЕстьИзмененияНаСервере()

// Запрос к служебной таблице или сравнение версии данных

Возврат Ложь;

КонецФункции

Чтобы не гонять тяжёлые запросы каждые несколько секунд, сравнивайте лёгкий признак изменений: номер версии данных, максимальную дату изменения, служебный флаг. Тяжёлое обновление запускайте только при реальном наличии изменений. При закрытии формы отключайте обработчик через ОтключитьОбработчикОжидания, чтобы не оставлять «висящих» таймеров.

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

Интервал опроса меньше 5–10 секунд редко оправдан и заметно нагружает сервер при большом числе пользователей. На практике для мониторов и рабочих столов достаточно 30–60 секунд, а для критичных данных лучше пересмотреть сценарий в пользу оповещений, а не таймера.
ПЗ
Практическое замечание

Проверка результата и типичные ошибки

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

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

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

Данные объекта после Прочитать()
Норма

На форме отображаются значения, совпадающие с данными в базе

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

Форма показывает старые значения — возможно, перечитан не тот реквизит или объект был в кэше

Позиция в списке после Обновить()
Норма

Текущая строка сохраняется, отборы и сортировка на месте

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

Курсор улетает на первую строку или пропадает отбор

Реакция на оповещение
Норма

ОбработкаОповещения срабатывает один раз на событие

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

Обработчик не вызывается (не совпало имя события) или срабатывает многократно

Нагрузка при таймере
Норма

Серверный вызов выполняется быстро и только при наличии изменений

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

Каждый тик таймера выполняет тяжёлый запрос по всем данным

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

Часто задаваемые вопросы

Может ли сервер сам принудительно обновить открытую форму клиента?

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

Чем Прочитать() отличается от Обновить() у элемента формы?

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

Почему ОбработкаОповещения не срабатывает?

Чаще всего не совпадает имя события: строка в Оповестить() должна точно равняться строке, проверяемой в обработчике, с учётом регистра. Также проверьте, что обработчик объявлен с директивой &НаКлиенте, форма-приёмник открыта в момент оповещения, а само Оповестить() реально выполняется — например, не прерывается ли код раньше из-за исключения при записи.

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

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

Обновит ли форму команда «Обновить» стандартной панели?

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

Что делать, если после обновления сбрасываются настройки списка?

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

Итог

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

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