Как не модально открыть форму 1с

Обновлено: 07.07.2024

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

Общая информация

В начале рассмотрим общие вопросы связанные с модальными окнами в 1С.

Что не так с модальными окнами?

С модальными окнами все в порядке. Они широко используются в 1С в тех случаях, когда от пользователя требуется ввод информации без которой невозможно дальнейшее выполнение программы. Остальной интерфейс при этом блокируется, а выполнение кода приостанавливается до тех пор, пока модальное окно не будет закрыто.

Когда следует отказаться от модальности?

Разумеется отказ от модальности необходим далеко не всегда.

Во-первых, режим работы интерфейса без использования модальности появился в версии технологической платформы 8.3.3.721 (от 06.09.2013) — следовательно, при использовании предыдущих версий технологической платформы, не нужно задумываться об отказе от модальности.

Режим использования модальности

Режим использования модальности

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

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

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

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

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

Непосредственно при отказе от модальности очень поможет механизм рефакторинга о котором подробно написано в отдельной статье.

Соответствие синхронных методов асинхронным аналогам (на момент написания статьи) можно посмотреть тут.

Практические примеры

В качестве практических примеров рассмотрим основные приемы работы с блокирующими окнами.

Отказ от использования модальных окон

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

Развитие продуктов «1С» и платформы «1С:Предприятие»

Одним из основных векторов развития платформы «1С:Предприятие» является возможность ее успешного использования в среде Интернет.

Эта среда имеет ряд ограничений, которые отсутствуют в среде настольных приложений:

  • Ограничения программ, используемых для работы в Интернете (браузеров),
  • Ограничения, связанные с качеством связи между клиентским приложением и сервером.

Приложения, предназначенные для работы через Интернет, должны быть построены с учетом этих ограничений, поэтому их модель отличается от настольных приложений.

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

Изначально платформа «1С:Предприятие» создавалась для построения настольных бизнес-приложений, использующих синхронную модель. Однако, с развитием SaaS-решений потребовался постепенный переход на асинхронную логику.

Проблемы поддержки модальных окон в среде Интернет

Модальные окна являются элементом синхронной модели. Они блокируют исполнение логики приложения, позволяя выполнять ее участки последовательно, друг за другом, в зависимости от результата, полученного от пользователя.

Такие окна не входят в стандарт веб-разработки, поэтому не поддерживаются всеми браузерами, при помощи которых пользователь получает доступ к приложениям «1С».

Для разработки качественных веб-приложений требуются асинхронные средства обеспечения взаимодействия с пользователем.

Такие средства были добавлены в платформу «1С:Предприятие» в версии 8.3.3.

Несколько терминов и определений

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

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

Общие принципы при переходе на асинхронную модель построения бизнес-логики

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

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

Таким образом, получается, что такой код разбивается на две процедуры:

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

Новые асинхронные средства платформы для взаимодействия с пользователем

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

Для этого в платформу был добавлен новый тип объектов - ОписаниеОповещения .

Этот объект имеет конструктор со следующими параметрами:

  • ИмяПроцедуры - Указывает имя процедуры-обработчика оповещения, которая будет выполнена после получения ответа пользователя,
  • Модуль -Указывает в каком модуле расположена эта процедура. Этот параметр может иметь следующие типы:
    • УправляемаяФорма - процедура расположена в модуле управляемой формы,
    • ОбщийМодуль - процедура расположена в общем неглобальном клиентском модуле,
    • КомандаКомандногоИнтерфейса - процедура расположена в модуле команды.

    Для получения значения модуля у вышеперечисленных объектов добавлено общее свойство ЭтотОбъект.

    • ДополнительныеПараметры - значение любого типа, которое будет передано в процедуру-обработчик оповещения при ее вызове.

    При вызове указанной процедуры системой ей через параметры передается результат выбора пользователя и значение ДополнительныеПараметры . В некоторых случаях результат выбора может отсутствовать (метод ПоказатьПредупреждение() ) или передаваться несколькими параметрами (метод НачатьПомещениеФайла() ).

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

    Группа этих методов отличается следующим:

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

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

    • Добавлено свойство формы ОписаниеОповещенияОЗакрытии , которое указывает на процедуру модуля, которая будет вызвана при ее закрытии. Также это значение можно установить при помощи нового параметра метода ОткрытьФорму() ,
    • Добавлен вариант режима открытия окна формы - БлокироватьВеcьИнтерфейс , при использовании которого открываемая форма заблокирует все окна, а не только окно родителя.

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

    Особенности реализации асинхронной бизнес-логики

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

    Это подтверждается тем фактом, что все современные веб-приложения построены именно с использованием асинхронной модели и их количество постоянно растет.

    Типовые сценарии при переходе на асинхронную модель

    Вопрос пользователю в команде формы

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

    В рамках асинхронной модели с использованием новых средств этот код будет выглядеть следующим образом:

    Процедура ДобавитьХарактеристику ( Команда )
    //Выберем вид характеристики
    Оповещение = Новый ОписаниеОповещения (
    "ДобавитьХарактеристикуЗавершение" ,
    ЭтотОбъект ) ;
    ОткрытьФорму ( "ПланВидовХарактеристик.ВидыХарактеристик.ФормаВыбора" ,
    , , , , , Оповещение , РежимОткрытияОкнаФормы . БлокироватьВеcьИнтерфейс ) ;
    КонецПроцедуры

    Процедура ДобавитьХарактеристикуЗавершение ( ВидХарактеристики , Параметры ) Экспорт
    Если ВидХарактеристики = Неопределено Тогда
    Возврат ;
    КонецЕсли ;

    //Проверим наличие
    Если ОписаниеХарактеристик . НайтиСтроки (
    Новый Структура ( "ВидХарактеристики" , ВидХарактеристики ) ) . Количество ( ) > 0 Тогда
    ПоказатьПредупреждение ( , НСтр ( "ru = 'Характеристика уже существует!'" , "ru" ) ) ;
    Возврат ;
    КонецЕсли ;


    //Добавим вид характеристики на форму
    ДобавитьХарактеристикуНаСервере ( ВидХарактеристики ) ;
    КонецПроцедуры

    Следует обратить внимание, что процедура-обработчик объявлена экпортируемой. Это связано с тем, что эта процедура будет вызвана не кодом самого модуля, а системным кодом платформы, поэтому модуль должен предоставить к ней доступ.

    Вопрос пользователю при закрытии формы

    Более сложной является ситуация, когда нужно о чем-то спросить пользователя во время обработчика события, например события закрытия формы. В асинхронной модели мы не можем сразу получить результат выбора, чтобы указать дальнейшие действия системе при помощи значения параметра Отказ .

    В таких случаях доступен следующий алгоритм:

    1. Создать в форме переменную, которая будет хранить ответ пользователя при ее закрытии,
    2. Если ответа получено еще не было (переменная содержит Неопределено ), то в обработчике ПередЗакрытием нужно показать окно выбора пользователю, например, при помощи метода ПоказатьВопрос() и прервать закрытие формы, установив Отказ=Истина ,
    3. В процедуре-обработчике выбора следует установить переменной результат выбора и вызвать метод Закрыть() формы,
    4. Если переменная содержит какое-либо значение, то это значит, что идет процесс закрытия, инициированный на предыдущем шаге, результат выбора от пользователя уже получен и обработчик ПередЗакрытием может использовать его значение.

    Ниже приведен пример кода, реализующего этот алгоритм:

    Вопрос пользователю во вложенных процедурах

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

    Предположим, существует общая функция, которая возвращает текст, в зависимости от ответа пользователя:

    В асинхронной модели эту функцию и ее вызовы следует реализовывать следующим образом:

    Таким образом, вызовы процедур можно связывать в цепочки, передавая им результат при помощи метода ВыполнитьОбработкуОповещения().

    Заключение

    В статье были рассмотрены новые средства, позволяющие реализовывать более качественные приложения с использованием асинхронной модели, принятой в среде Интернет.

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

    Открытие форм

    Область применения: управляемое приложение, мобильное приложение.

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

    Рекомендация обусловлена соображениями

    • повышения устойчивости кода, работающего с формой, за счет разделения программного интерфейса для работы с формой и деталей ее внутренней реализации,
    • а также сохранения единой стилистики кода прикладных решений.

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

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

    Параметры формы из этого набора могут быть указаны в вызывающем коде при открытии формы ( ОткрытьФорму ).

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

    следует по той же причине использовать параметры формы:

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

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

    ФормаВопроса = ПолучитьФорму("ОбщаяФорма.ФормаВопроса");
    ФормаВопроса.ОткрытьМодально();
    Если ФормаВопроса.БольшеНеПоказыватьНапоминание Тогда
    // …

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

    Оповещение = Новый ОписаниеОповещения("БольшеНеПоказыватьНапоминаниеЗавершение", ЭтотОбъект);
    ОткрытьФорму("ОбщаяФорма.ФормаВопроса". Оповещение, РежимОткрытияОкнаФормы.БлокироватьВеcьИнтерфейс);
    .

    &НаКлиенте
    Процедура БольшеНеПоказыватьНапоминаниеЗавершение(БольшеНеПоказыватьНапоминание, Параметры) Экспорт

    Если БольшеНеПоказыватьНапоминание = Неопределено Тогда
    Возврат;
    КонецЕсли;

    Если БольшеНеПоказыватьНапоминание Тогда
    // …

    При этом возвращаемое значение формы формируется в коде модуля формы с помощью метода формы Закрыть .

    5. Другие ограничения:

    • Обработчик события формы ПриОткрытии не должен содержать код по открытию какой-либо другой формы, так как это может привести к нарушению порядка отображения окон. В этом случае рекомендуется использовать обработчик ожидания на короткий интервал или открывать другие формы интерактивно, например, по нажатию на кнопку.
    • Не рекомендуется выполнять программное открытие и закрытие формы в одном обработчике. Такие действия должны быть разнесены по времени. Например, закрытие формы можно выполнять в обработчике ожидания.
    • При использовании в конфигурации Библиотека стандартных подсистем и разработке форм (рабочих мест), предназначенных только для внешних пользователей, следует явно блокировать открытие таких форм в сеансах "обычных" пользователей. Для этого следует устанавливать параметр Отказ при создании формы на сервере с помощью функции ЭтоСеансВнешнегоПользователя общего модуля Пользователи или ПользователиКлиент :

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Если Не ПользователиКлиентСервер.ЭтоСеансВнешнегоПользователя() Тогда
    Отказ = Истина;
    Возврат;
    КонецЕсли;

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

    6. Следующие виды форм должны быть всегда доступны пользователю в режиме 1С:Предприятия из меню "Все функции" вне зависимости от того, размещены ли соответствующие объекты в командном интерфейсе приложения или нет:

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

    Управление режимом модальности

    В новых версиях платформы добавилось новое свойство конфигурации "Режим использования модальности". Это свойство может быть установлено: Не использовать, Использовать с предупреждением, Использовать. С помощью данного глобального свойства устанавливается режим использования модальных окон во всей конфигурации.

    Проблемы при открытии модальных форм на веб-клиенте

    Конфигурации созданные на управляемом приложении могут работать через веб-клиент.
    При использовании модальных окон в браузерах могут возникать определенные сложности. Браузеры мобильных устройств не поддерживают работу модальных окон. При использовании персональных компьютеров в браузерах может быть включена блокировка всплывающих окон.

    Имитация модальной формы методом ОткрытьФорму()

    Для решения данных проблем в платформе был разработан новый механизм открытия модальных окон. Если в конфигурации стоит запрет на использование модальных окон, то нельзя использовать методы модального открытия окон. Однако, есть возможность сделать окно модальным с помощью метода ОткрытьФорму(). В этом методе появились новые параметры "РежимОткрытияОкна" и "ОписаниеОповещенияОЗакрытии".

    Парметр "РежимОткрытияОкна" - позволяет установить блокировку всех открытых окон 1С:Предприятия, кроме открываемого.
    Параметр "ОписаниеОповещенияОЗакрытии" - позволяет определить процедуру вызываемую при закрытии формы.

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

    Открытие модальной формы по умолчанию


    В управляемых формах, свойство "РежимОткрытияОкна" также доступно в палитре свойств. Это свойство может иметь одно из следующих значений: Независимый, блокировать окно владельца, Блокировать весь интерфейс. Если установить данное свойство, то при открытии формы "РежимОткрытияОкна" устанавливать не нужно.

    Комментарии (0)

    Старая процедура, открывавшая модальное окно и обрабатывавшая полученные им данные, могла выглядеть так:


    В новом варианте для формы ФормаВводТекста (которая будет открываться в блокирующем окне) нужно установить свойство РежимОткрытияОкна в значение БлокироватьВесьИнтерфейс. Это обеспечит модальность для пользователя:


    А программный код вместо одной процедуры, как раньше, будет содержать уже две процедуры:


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

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

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

    Использовать такие методы в немодальном режиме ещё проще. Для всех таких методов в платформе сделаны методы-дублёры, при вызове которых нужно так же указать местонахождение процедуры, которая будет выполнена после того, как пользователь закроет окно.

    Например, ниже показано использование старого метода ВвестиЗначение() и его нового метода-дублёра ПоказатьВводЗначения():


    В 8.3.5 можно выполнить автоматическое преобразование Модальных вызовов

    Теперь в простых, и в не очень простых, случаях вы можете сделать это автоматически (команда Модальные вызовы - Преобразовать модальный вызов):


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


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


    Однако если вы преобразуете код, который находится, например, в модуле управляемого приложения, то полностью автоматическое преобразование вам выполнить не удастся:


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

    Читайте также: