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

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

Как программно перечитать данные на форме 1С

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

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

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

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

Какие методы перечитывания существуют и когда их применять

В управляемой форме доступно несколько механизмов обновления данных, и они не взаимозаменяемы. Основные варианты:

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

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

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

Прочитать()

Перечитывает объект из базы. Подходит для формы документа или элемента справочника. Затирает несохранённые изменения.

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

Обновляет динамический список на форме списка. Не затрагивает формы объектов.

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

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

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

Только перерисовывает элементы по текущим данным формы. Не читает базу.

Как перечитать объект на форме методом Прочитать()

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

&НаКлиенте

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

Прочитать();

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

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

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

&НаКлиенте

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

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

ПоказатьПредупреждение(, "Есть несохранённые изменения. Сохраните объект перед перечитыванием.");

Возврат;

КонецЕсли;

Прочитать();

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

Как обновить форму списка и динамический список

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

&НаКлиенте

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

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

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

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

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

&НаКлиенте

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

ОповеститьОбИзменении(Тип("ДокументСсылка.РеализацияТоваровУслуг"));

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

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

Как перечитать данные после программной записи объекта

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

&НаСервере

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

ДокОбъект = РеквизитФормыВЗначение("Объект");

ДокОбъект.Статус = Перечисления.СтатусыДокументов.Согласован;

ДокОбъект.Записать();

Прочитать();

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

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

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

Обновление отдельных реквизитов и связанных данных

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

&НаКлиенте

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

Если ИмяСобытия = "Запись_Контрагенты"

И Параметр = Объект.Контрагент Тогда

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

КонецЕсли;

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

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

Типичные ошибки при перечитывании данных

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

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

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

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

Как проверить, что данные действительно перечитаны

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

Для динамических списков проверьте, что новая или изменённая строка появилась в таблице с учётом текущего отбора. Если строка не появилась, чаще всего причина в отборе, который её отсекает, а не в неработающем обновлении.

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

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

Значение контрольного реквизита на форме
Норма

Совпадает со значением в базе (проверено через запрос или другую форму)

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

Форма показывает старое значение после Прочитать()

Новая строка в динамическом списке
Норма

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

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

Строки нет — проверьте отборы и условное оформление списка

Модифицированность после Прочитать()
Норма

Признак сброшен, форма соответствует базе

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

Модифицированность осталась — возможно, код после Прочитать() снова меняет данные

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

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

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

Как перечитать форму другого объекта из своего кода?

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

Почему после Элементы.Список.Обновить() новая запись не появляется?

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

Можно ли перечитать только часть объекта, не затирая всё?

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

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

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

Работает ли Прочитать() для нового, ещё не записанного объекта?

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

Итог

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

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