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