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

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

Как открыть форму из модуля объекта в 1С

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

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

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

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

Почему из модуля объекта нельзя просто вызвать ОткрытьФорму

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

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

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

Открытие формы записанного объекта через ОткрытьЗначение

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

&НаКлиенте

Процедура ПослеЗаписиОбъекта(СсылкаНаОбъект)

ОткрытьЗначение(СсылкаНаОбъект);

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

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

// Модуль объекта

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

ДополнительныеСвойства.Вставить("ОткрытьПослеЗаписи", Истина);

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

// Модуль формы

&НаКлиенте

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

Если Объект.ДополнительныеСвойства.Свойство("ОткрытьПослеЗаписи") Тогда

// действия на клиенте

КонецЕсли;

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

Открытие произвольной формы через ОткрытьФорму на клиенте

Когда нужно открыть не сам объект, а форму выбора, обработку или форму списка с отбором, применяется ОткрытьФорму() с параметрами. Вызов размещается в клиентском контексте — модуле формы или общем модуле с флагом «Клиент».

&НаКлиенте

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

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("Отбор", Новый Структура("Владелец", Объект.Ссылка));

ПараметрыФормы.Вставить("РежимВыбора", Истина);

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, ЭтотОбъект);

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

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

Для получения результата без модальности используйте описание оповещения о закрытии:

&НаКлиенте

Процедура ОткрытьНастройки(Команда)

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

ОткрытьФорму("Обработка.НастройкиОбмена.Форма", , ЭтотОбъект, , , , Оповещение);

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

bsl
&НаКлиенте
Процедура ОткрытьДокумент(Команда)
    ПараметрыФормы = Новый Структура("Ключ", ПолучитьСсылкуНаСервере());
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры

Передача вызова из модуля объекта на клиента через оповещения

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

// Модуль объекта (сервер)

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

// Оповестить() здесь вызвать нельзя — сервер.

// Но можно через параметры записи или дополнительные свойства.

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

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

&НаКлиенте

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

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

ОткрытьЗначение(Параметр);

КонецЕсли;

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

Порядок действий при передаче через оповещение
  1. 1
    В модуле объекта сохраните нужные данные в ДополнительныеСвойства или доведите логику до записи
  2. 2
    В модуле формы объекта в обработчике ПослеЗаписи (клиент) вызовите Оповестить с именем события и ссылкой
  3. 3
    В форме-приёмнике реализуйте ОбработкаОповещения с проверкой имени события
  4. 4
    Внутри обработчика вызовите ОткрытьЗначение или ОткрытьФорму
  5. 5
    Проверьте, что форма-приёмник открыта в момент записи — иначе событие никто не получит

Открытие формы нового объекта с заполнением

Часто из логики объекта требуется открыть форму нового документа, заполненного на основании текущего. Для этого в ОткрытьФорму передаётся параметр Основание или ЗначенияЗаполнения:

&НаКлиенте

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

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("Основание", Объект.Ссылка);

ОткрытьФорму("Документ.СчетФактура.ФормаОбъекта", ПараметрыФормы);

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

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

Альтернатива — ЗначенияЗаполнения: структура с произвольными реквизитами, которая не требует настройки критериев ввода на основании.

Сравнение способов открытия

ОткрытьЗначение(Ссылка)

Быстро открывает форму существующего объекта. Не подходит для новых объектов и форм с параметрами.

ОткрытьФорму с параметрами

Гибкий способ: отборы, основание, владелец, оповещение о закрытии. Требует клиентского контекста.

Оповестить + ОбработкаОповещения

Позволяет инициировать открытие из серверной логики. Работает только если форма-приёмник открыта.

ПоказатьЗначение через навигационную ссылку

Используется для открытия из внешних по отношению к объекту механизмов, например из отчётов.

Типичные ошибки и ограничения

Самая распространённая ошибка — попытка вызвать ОткрытьФорму() или Предупреждение() прямо в модуле объекта. Платформа выдаёт ошибку компиляции или «Интерактивные операции недоступны» в зависимости от режима. Лечится переносом кода в клиентский контекст.

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

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

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

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

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

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

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

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

Контекст кода
Норма

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

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

Вызов в модуле объекта или серверной процедуре — ошибка исполнения

Момент открытия
Норма

Форма открывается в ПослеЗаписи, ссылка на объект заполнена

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

Открытие внутри транзакции записи, ссылка пустая

Модальность
Норма

Используется ОткрытьФорму с ОписаниеОповещения

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

ОткрытьФормуМодально при запрещённой модальности

Передача результата
Норма

Форма-владелец получает ОбработкаВыбора или оповещение о закрытии

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

Форма открыта без владельца, результат теряется

FAQ

Можно ли открыть форму прямо из ОбработкаПроведения?

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

Чем ОткрытьЗначение отличается от ОткрытьФорму?

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

Как открыть форму из модуля объекта внешней обработки?

Модуль объекта внешней обработки тоже серверный. Разместите вызов в модуле формы обработки или в общем клиентском модуле, а из объекта передавайте только данные через параметры или дополнительные свойства.

Почему Оповестить из формы не срабатывает в другой форме?

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

Как открыть форму и дождаться результата без модальности?

Передайте в ОткрытьФорму последним параметром ОписаниеОповещения с именем клиентской процедуры. При закрытии формы платформа вызовет эту процедуру и передаст результат закрытия.

Работает ли ОткрытьФорму в фоновом задании?

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

Итог

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

Модуль объекта — серверный контекст, формы из него не открываются. Решение всегда строится одинаково: объект готовит данные и ссылку, а ОткрытьЗначение или ОткрытьФорму с параметрами вызывается на клиенте — в модуле формы, через ПослеЗаписи или через механизм оповещений. Интерактивные вызовы в транзакции записи запрещены.