Открыть форму 1С из кода нужно почти в каждой доработке: кнопка на документе показывает карточку контрагента, обработка вызывает окно настроек, табличная часть просит выбрать номенклатуру. В управляемом приложении 1С:Предприятия 8.3 для этого есть два метода глобального контекста — ОткрытьФорму и ПолучитьФорму. Ниже — полный синтаксис, таблица имён форм и готовые шаблоны для типовых случаев: карточка по ссылке, новый элемент с заполнением, список с отбором, выбор значения и своя форма, которая возвращает результат.
ОткрытьФормуМодально, но в типовых конфигурациях на 8.3 модальность, как правило, отключена.Иногда код не нужен вовсе. В редакторе формы на панели команд есть раздел «Глобальные команды»: оттуда можно перетащить на форму команду открытия списка или создания элемента. Код понадобится, когда форме нужно передать параметры или получить от неё ответ.
Метод работает только на клиенте, поэтому его вызывают из процедур с директивой &НаКлиенте. Полная сигнатура в 8.3:
ОткрытьФорму(ИмяФормы, Параметры, Владелец, Уникальность, Окно, НавигационнаяСсылка, ОписаниеОповещенияОЗакрытии, РежимОткрытияОкна)
| Параметр | Что передавать |
|---|---|
| ИмяФормы | Строка с полным именем формы, например "Справочник.Контрагенты.ФормаОбъекта". Единственный обязательный параметр. |
| Параметры | Структура: ключ — имя параметра формы, значение — то, что передаёте. Стандартные параметры (Ключ, Отбор, ЗначенияЗаполнения и другие) объявлять не нужно, свои — нужно. |
| Владелец | Форма или элемент формы, откуда открываете, обычно ЭтотОбъект. Владельцу приходит событие ОбработкаВыбора, а режим БлокироватьОкноВладельца блокирует именно его окно. |
| Уникальность | Ключ уникальности. Если форма с тем же именем и тем же ключом уже открыта, платформа активирует её вместо открытия второй копии. |
| Окно | Окно клиентского приложения, в котором показать форму. В прикладном коде почти всегда пропускают. |
| НавигационнаяСсылка | Навигационная ссылка, которую получит форма. Обычно не заполняют. |
| ОписаниеОповещенияОЗакрытии | Процедура, которую платформа вызовет после закрытия формы; в неё придёт результат закрытия. |
| РежимОткрытияОкна | Значение РежимОткрытияОкнаФормы: Независимый, БлокироватьОкноВладельца или БлокироватьВесьИнтерфейс. Если не указан, берётся из свойства самой формы. |
Два последних параметра появились вместе с режимом работы без модальных окон (платформа 8.3.3). Функция возвращает открытую форму или Неопределено, если форма не открылась — например, в её ПриСозданииНаСервере установлен Отказ. Главное: вызов не ждёт, пока пользователь закроет окно. Код после ОткрытьФорму выполняется сразу, а ответ пользователя приходит только в процедуру оповещения.
Имя собирается по схеме «вид объекта в единственном числе.имя объекта.стандартная форма». Для произвольной формы объекта перед её именем ставится слово Форма.
| Что открыть | Имя формы |
|---|---|
| Карточку элемента или документ | Справочник.Контрагенты.ФормаОбъекта, Документ.ЗаказКлиента.ФормаОбъекта |
| Группу справочника | Справочник.Номенклатура.ФормаГруппы |
| Список, выбор элемента, выбор группы | …ФормаСписка, …ФормаВыбора, …ФормаВыбораГруппы |
| Запись регистра сведений | РегистрСведений.КурсыВалют.ФормаЗаписи |
| Основную форму обработки или отчёта | Обработка.ЗагрузкаЦен.Форма, Отчет.ОстаткиТоваров.Форма |
| Конкретную форму объекта | Документ.ЗаказКлиента.Форма.ФормаПечати |
| Общую форму | ОбщаяФорма.ВводКомментария |
Стандартные имена вроде ФормаОбъекта и ФормаСписка работают, даже если форма в конфигурации не нарисована: платформа сгенерирует её сама. Имя формы внешней обработки начинается с ВнешняяОбработка., но сначала обработку нужно подключить на сервере — это разобрано в статье о форме внешней обработки.
Все примеры — процедуры модуля управляемой формы. Имена объектов взяты из типовых конфигураций для наглядности, а структура данных в них различается: например, в БП 3.0 договор подчинён контрагенту, а в УТ 11 и ERP — нет. Имена объектов и реквизитов замените на свои.
Создайте команду формы, вынесите её на командную панель и назначьте обработчик:
&НаКлиенте
Процедура ОткрытьЗагрузкуЦен(Команда)
ОткрытьФорму("Обработка.ЗагрузкаЦен.Форма", , ЭтотОбъект);
КонецПроцедуры
Если нужно несколько одинаковых окон, например два экземпляра обработки с разными настройками, передайте новый ключ уникальности. Каждый вызов с Новый УникальныйИдентификатор открывает отдельное окно:
&НаКлиенте
Процедура НовоеОкноЗагрузки(Команда)
// Новый идентификатор при каждом вызове = всегда новое окно
ОткрытьФорму("Обработка.ЗагрузкаЦен.Форма", , , Новый УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ОткрытьКарточкуКонтрагента(Команда)
Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
Возврат;
КонецЕсли;
ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта",
Новый Структура("Ключ", Объект.Контрагент), ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура СоздатьДоговор(Команда)
ЗначенияЗаполнения = Новый Структура;
// Схема БП 3.0: договор подчинён контрагенту. В УТ 11/ERP вместо Владелец - реквизиты Контрагент/Партнер
ЗначенияЗаполнения.Вставить("Владелец", Объект.Контрагент);
// Заполнится автоматически, только если у реквизита включено «Заполнять из данных заполнения»
ЗначенияЗаполнения.Вставить("Организация", Объект.Организация);
ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаОбъекта",
Новый Структура("ЗначенияЗаполнения", ЗначенияЗаполнения), ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура СоздатьРеализацию(Команда)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
ПоказатьПредупреждение(, "Сначала запишите заказ.");
Возврат;
КонецЕсли;
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта",
Новый Структура("Основание", Объект.Ссылка), ЭтотОбъект);
КонецПроцедуры
Разбор параметров:
Ключ — ссылка на существующий объект. Именно Ключ, а не Ссылка: форма объекта читает данные из параметра с этим именем. Для формы записи регистра сведений ключом служит ключ записи.ЗначенияЗаполнения — структура «реквизит — значение» для нового объекта. Платформа сама переносит значения только в реквизиты, у которых в конфигураторе включено свойство «Заполнять из данных заполнения» (у стандартного реквизита Владелец оно обычно включено). Остальные ключи обработайте сами в ОбработкаЗаполнения модуля объекта: структура приходит туда как ДанныеЗаполнения. Если реквизит после открытия формы пустой, первым делом проверьте это свойство.Основание — ввод на основании: у нового документа вызывается ОбработкаЗаполнения, и в неё придёт переданная ссылка.ЗначениеКопирования.Для документа по ссылке есть и короткий путь — ПоказатьЗначение(, Ссылка). Варианты и подводные камни собраны в статье про открытие формы документа по ссылке.
&НаКлиенте
Процедура ЗаказыКонтрагента(Команда)
Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
Возврат;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Новый Структура("Контрагент", Объект.Контрагент));
ПараметрыФормы.Вставить("ТекущаяСтрока", Объект.Ссылка);
// Ключ уникальности - контрагент: одно окно списка на каждого контрагента
ОткрытьФорму("Документ.ЗаказКлиента.ФормаСписка", ПараметрыФормы, ЭтотОбъект, Объект.Контрагент);
КонецПроцедуры
Отбор — структура «поле — значение», её платформа применяет к основному динамическому списку формы. ТекущаяСтрока ставит курсор на переданную ссылку. Ключом уникальности здесь выступает сам контрагент: для разных контрагентов откроются отдельные окна, а повторное нажатие для того же контрагента вернёт пользователя в уже открытое.
&НаКлиенте
Процедура ПодобратьНоменклатуру(Команда)
Оповещение = Новый ОписаниеОповещения("ПодобратьНоменклатуруЗавершение", ЭтотОбъект);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", , ЭтотОбъект, , , ,
Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПодобратьНоменклатуруЗавершение(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
Если ВыбранноеЗначение = Неопределено Тогда
Возврат; // окно закрыли без выбора
КонецЕсли;
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыбранноеЗначение;
Модифицированность = Истина;
КонецПроцедуры
В обработчик оповещения придёт выбранная ссылка, если пользователь выбрал значение, и Неопределено, если он закрыл окно. Раньше этот сценарий решали через событие ОбработкаВыбора формы-владельца. Оно по-прежнему работает, но с оповещением код вызова и код обработки результата лежат рядом, и форме не нужно разбирать ИсточникВыбора, когда она запрашивает несколько разных значений.
Это замена ОткрытьФормуМодально для конфигураций без модальности. Код вызывающей формы:
&НаКлиенте
Процедура ЗаполнитьКомментарий(Команда)
Оповещение = Новый ОписаниеОповещения("ЗаполнитьКомментарийЗавершение", ЭтотОбъект);
ПараметрыФормы = Новый Структура("ТекстПоУмолчанию", Объект.Комментарий);
ОткрытьФорму("ОбщаяФорма.ВводКомментария", ПараметрыФормы, ЭтотОбъект, , , ,
Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьКомментарийЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат; // закрыли крестиком или по Esc
КонецЕсли;
Объект.Комментарий = Результат;
Модифицированность = Истина;
КонецПроцедуры
Модуль вызываемой общей формы. Параметр ТекстПоУмолчанию добавляют на вкладке «Параметры» редактора формы:
// Модуль общей формы ВводКомментария
// Реквизит формы: Текст (Строка). Параметр формы: ТекстПоУмолчанию (Строка).
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Текст = Параметры.ТекстПоУмолчанию;
КонецПроцедуры
&НаКлиенте
Процедура Готово(Команда)
Закрыть(Текст); // значение уйдёт в обработчик оповещения вызывающей формы
КонецПроцедуры
Разбор ключевых строк:
Закрыть(Текст) — значение, переданное в Закрыть, становится результатом закрытия и приходит в первый параметр обработчика. Если окно закрыли крестиком, придёт Неопределено.БлокироватьОкноВладельца — пока диалог открыт, документ не отредактировать, но остальные окна программы доступны. Для вопросов, которые касаются всей программы, подходит БлокироватьВесьИнтерфейс.ОписаниеОповещения — ДополнительныеПараметры. Туда удобно положить, например, идентификатор строки табличной части, которую нужно обновить после ответа.&НаКлиенте и словом Экспорт. Имя процедуры задаётся строкой, поэтому опечатку компилятор не заметит: ошибка появится только при закрытии формы.ПолучитьФорму принимает те же параметры, что и ОткрытьФорму, от имени формы до навигационной ссылки, и возвращает объект формы, не показывая её. На этом шаге форма уже создана: ПриСозданииНаСервере отработал, а ПриОткрытии выполнится только при вызове Открыть(). Порядок событий формы подробно разобран в статье об управляемой форме.
&НаКлиенте
Процедура ОткрытьЗагрузкуСОповещением(Команда)
Форма = ПолучитьФорму("Обработка.ЗагрузкаЦен.Форма", , ЭтотОбъект, Новый УникальныйИдентификатор);
Форма.ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ЗагрузкаЦенЗавершение", ЭтотОбъект);
Форма.Открыть();
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузкаЦенЗавершение(Результат, ДополнительныеПараметры) Экспорт
Элементы.Список.Обновить(); // вызывающая форма здесь - форма списка: перечитать данные
КонецПроцедуры
Метод нужен, когда до показа формы нужно вызвать её экспортную клиентскую процедуру или заполнить клиентские переменные модуля. В остальных случаях передавайте данные через параметры: они приходят в ПриСозданииНаСервере, где доступны запросы и объекты базы. Если форма с таким ключом уникальности уже открыта, ПолучитьФорму вернёт её, и ПриСозданииНаСервере повторно не выполнится.
В обычном приложении (толстый клиент, конфигурации вроде УТ 10.3) формы чаще открывают через менеджеры и методы объектов: ПолучитьФормуНовогоЭлемента, ПолучитьФорму и затем Открыть() или ОткрытьМодально(). Модальность там, как правило, разрешена, и результат возвращает сам ОткрытьМодально().
// Обычное приложение, модуль обычной формы документа (толстый клиент)
Процедура КнопкаКарточкаКонтрагентаНажатие(Элемент)
Если ЗначениеЗаполнено(Контрагент) Тогда
ОткрытьЗначение(Контрагент); // реквизиты документа в модуле обычной формы доступны напрямую
КонецЕсли;
КонецПроцедуры
Процедура КнопкаНовыйКонтрагентНажатие(Элемент)
Форма = Справочники.Контрагенты.ПолучитьФормуНовогоЭлемента();
Форма.Открыть();
КонецПроцедуры
ОткрытьФорму внутри процедуры &НаСервере не компилируется: на сервере нет интерфейса. Модуль не пройдёт проверку с ошибкой вида «Процедура или функция с указанным именем не определена (ОткрытьФорму)». Серверная функция должна вернуть данные на клиент, а форму открывает клиентская процедура.ОткрытьФормуМодально в конфигурации со свойством «Режим использования модальности» = «Не использовать» даёт «Использование модальных окон в данном режиме запрещено!». Замените его на ОткрытьФорму с оповещением и блокирующим режимом окна.ОткрытьФорму читает данные из открытой формы, получит их до того, как пользователь что-то ввёл. Всё, что зависит от ответа, переносите в обработчик оповещения.Справочники.Контрагенты.ФормаОбъекта), пропущенное слово Форма перед именем произвольной формы, старое имя после переименования. Имя — обычная строка, компилятор его не проверяет, ошибка возникнет при выполнении.ТекстПоУмолчанию не добавлен в параметры формы, значение до неё не дойдёт, а обращение Параметры.ТекстПоУмолчанию завершится ошибкой «Поле объекта не обнаружено (ТекстПоУмолчанию)».ПриСозданииНаСервере не выполняется, новые параметры не применяются. Передавайте осмысленный ключ — например, ссылку, для которой открываете форму.Справочники.Контрагенты.ПолучитьФормуНовогоЭлемента() в клиентской процедуре управляемой формы не скомпилируется: менеджеры объектов на тонком клиенте недоступны, будет «Переменная не определена (Справочники)».Передайте ОписаниеОповещенияОЗакрытии и режим БлокироватьОкноВладельца или БлокироватьВесьИнтерфейс. Для пользователя окно ведёт себя как модальное, а код продолжается в обработчике оповещения, а не на следующей строке.
ОткрытьФорму создаёт форму и сразу показывает её. ПолучитьФорму только создаёт объект формы: его можно донастроить и открыть методом Открыть(). В большинстве задач хватает первого варианта с параметрами.
Нет, интерфейс существует только на клиенте. Серверная процедура готовит данные, клиентская открывает форму. Если форму нужно показать после записи документа, делайте это в клиентском событии ПослеЗаписи формы объекта.
Укажите её имя через слово Форма: "Документ.ЗаказКлиента.Форма.ФормаПечати". Стандартные имена ФормаОбъекта и ФормаСписка открывают формы, которые назначены основными в свойствах объекта.
Скорее всего, ссылка ушла в параметре с другим именем. Форма объекта загружает существующий объект только из параметра Ключ, всё остальное без объявления она не видит и открывается как новая.
Сам вызов формы — пара строк. Сложности начинаются, когда диалог нужно встроить в типовую форму через расширение, передать данные между несколькими формами и не сломать поведение после обновления. Такую доработку можно поручить программисту: разместите задачу бесплатно или посмотрите услугу по отчётам и обработкам. Оценка задачи бесплатная, ответ придёт в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.