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