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

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

Как программно переоткрыть форму в 1С

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

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

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

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

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

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

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

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

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

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

Базовый способ: закрыть и открыть форму заново

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

bsl
&НаКлиенте
Процедура ПереоткрытьФорму(Команда)
	ПараметрыОткрытия = Новый Структура("Ключ", Объект.Ссылка);
	ИмяФормыОбъекта = "Справочник.Номенклатура.Форма.ФормаЭлемента";
	Закрыть();
	ОткрытьФорму(ИмяФормыОбъекта, ПараметрыОткрытия);
КонецПроцедуры

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

Переоткрытие через описание оповещения о закрытии

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

bsl
&НаКлиенте
Процедура ПереоткрытьСОповещением(Команда)
	ПараметрыОткрытия = Новый Структура("Ключ", Объект.Ссылка);
	Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияОткрытьЗаново", ЭтотОбъект, ПараметрыОткрытия);
	Закрыть(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияОткрытьЗаново(Результат, ПараметрыОткрытия) Экспорт
	ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаЭлемента", ПараметрыОткрытия);
КонецПроцедуры

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

Переоткрытие извне: из другой формы или общего модуля

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

bsl
// В форме, которую нужно переоткрывать
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	Если ИмяСобытия = "ТребуетсяПереоткрытие" Тогда
		ПрочитатьНаСервере();
		ОбновитьОтображениеДанных();
	КонецЕсли;
КонецПроцедуры

// В вызывающем коде
Оповестить("ТребуетсяПереоткрытие", , ЭтотОбъект);

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

Альтернативы переоткрытию: обновление без закрытия

В большинстве прикладных задач полное переоткрытие — избыточная мера. Платформа предоставляет несколько методов, которые обновляют содержимое формы без уничтожения её экземпляра.

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

Для форм отчётов на СКД вместо переоткрытия достаточно вызвать СкомпоноватьРезультат() или изменить настройки компоновщика и переформировать отчёт. Для динамических списков изменение параметров запроса через Список.Параметры.УстановитьЗначениеПараметра() обновляет данные автоматически.

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

Закрыть() + ОткрытьФорму()

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

Прочитать() на сервере

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

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

Только обновляет отображение после программных изменений. Самый лёгкий вариант, но не читает данные из базы.

Оповещения (Оповестить)

Обновление других открытых форм без прямого доступа к ним. Требует обработчика ОбработкаОповещения в целевой форме.

Особенности для обычных форм и тонкие моменты

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

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

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

Проверка результата

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

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

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

Количество окон после переоткрытия
Норма

Открыто ровно одно окно формы объекта

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

Два и более окон одного объекта — закрытие не отработало или было отменено

Данные в новой форме
Норма

Отображаются актуальные данные из базы

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

Показаны устаревшие значения — объект не перечитан

Несохранённые изменения
Норма

Перед закрытием задан вопрос или выполнено сохранение

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

Изменения исчезают без предупреждения

Повторное переоткрытие
Норма

Работает стабильно несколько раз подряд

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

Со второго раза ошибки — вероятна утечка контекста или неверный ключ уникальности

Итог

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

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

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

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

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

Почему после ОткрытьФорму() открывается старая форма, а не новая?

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

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

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

Что делать, если форма не закрывается программно?

Проверьте обработчики ПередЗакрытием и ПриЗакрытии — там может стоять Отказ = Истина или задаваться вопрос пользователю. Также закрытие блокируется, если форма открыта модально или в ней идёт длительная серверная операция.

Как сохранить несохранённые данные перед переоткрытием?

Проверьте свойство Модифицированность, затем вызовите серверную процедуру с Записать() или задайте пользователю вопрос через ПоказатьВопрос() с описанием оповещения. Переоткрытие запускайте только после успешной записи или явного отказа пользователя от сохранения.

Работает ли переоткрытие в веб-клиенте?

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