1С Платформа 8.3. Изучаем немодальные окна

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

Всему виной свойство конфигурации «Режим использования модальности»

У этого свойства может быть три значения:
• Использовать – тогда процедуры типа Предупреждение, Вопрос и тп будут работать;
• Использовать с предупреждениями – процедуры типа Предупреждение, Вопрос и тп будут работать, но будет выходить сообщение;
• Не использовать — процедуры типа Предупреждение, Вопрос и тп работать не будут.

Поэтому если возникла такая ошибка, то есть два варианта решения проблемы. Первый вариант – топорный, изменить свойство конфигурации «Режим использования модальности». Этот вариант в некоторых случаях может иметь место. Но имейте в виду, что он не применим, если конфигурация планируется запускаться под web-клиентом.

Второй вариант – переписать все имеющиеся процедуры вызова модальных окон на процедуры, использующие немодальные окна. Процедур, которые потребуется заменить в случае перехода с платформы 8.2 на 8.3, довольно таки много, я приведу только некоторые из них:

• Предупреждение – ПоказатьПредупреждение
• Вопрос – ПоказатьВопрос
• ВвестиЧисло – ПоказатьВводЧисла
• ВвестиСтроку- ПоказатьВводСтроки
• ВвестиДату – ПоказатьВводДаты
• ВвестиЗначение — ПоказатьВвводЗначения

Основное отличие всех вышеперечисленных новых процедуры, то, что ввод-вывод информации осуществляется асинхронно. Что это значит? Пока Вы решаете нажать или не нажать кнопку «ОК», как ответить на вопрос, или какое число ввести, идет выполнение кода программы. Для этого в метод необходимо передать название процедуры, которая будет обработчиком ожидания. И сработает, когда вы нажмете кнопку «ОК».

В тоже время не стоит путать асинхронность с параллельностью. Код, который у Вас сработает в процедуре обработчике ожидания, не будет выполняться параллельно основному коду. Он сработает после выполнения этого кода.
Рассмотрим эту особенность более подробно. Для этого я создал простую обработку, в которой будет выполняться следующий код:


&НаКлиенте
Процедура КомандаПредупреждение(Команда)

Оповещение = Новый ОписаниеОповещения(«ПослеЗакрытияПредупреждения»,ЭтаФорма,Параметры);

ПоказатьПредупреждение(Оповещение,НСтр(«ru = ‘Предупрежение'»),,«!!!»);

Для н = 1 по 10 Цикл
Сообщить(«Работает цикл» + н);
КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияПредупреждения(ДопПараметры) Экспорт

Сообщить(«После закрытия предупреждения»);

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

Поясню написанный выше код: мы создали обработчик ожидания с помощью объекта «ОписаниеОповещения», где в качестве первого параметра указали название процедуры, которая должна сработать после нажатия кнопки «ОК» окна предупреждения. В следующей строке мы применили процедуру «ПоказатьПредупреждение», где в качестве первого параметра указали написанный выше обработчик ожидания. Именно после нажатия кнопки «ОК» сработает процедура «ПослеЗакрытияПредупреждения». А в конце мы написали простой цикл.

Обратите внимание на рисунок, цикл сработал до того, как мы нажали на кнопку «ОК» окна предупреждении. Это и есть, по сути, асинхронное выполнение кода.
Теперь попробуем применить вызов предупреждения внутри цикла

&НаКлиенте
Процедура КомандаПредупреждение(Команда)

Оповещение = Новый ОписаниеОповещения(«ПослеЗакрытияПредупреждения»,ЭтаФорма,Параметры);

Для н = 1 по 10 Цикл

Если н = 5 Тогда
ПоказатьПредупреждение(Оповещение,НСтр(«ru = ‘Предупрежение'»),,«!!!»);
КонецЕсли;

Сообщить(«Работает цикл » + н);

КонецЦикла;

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

&НаКлиенте
Процедура ПослеЗакрытияПредупреждения(ДопПараметры) Экспорт

Сообщить(«После закрытия предупреждения»);

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

И всё равно, выполнение цикла произойдет до того как будет нажата кнопка «ОК». Точно так же будет работать метод, если мы уберем оповещение.

&НаКлиенте
Процедура КомандаПредупреждение(Команда)

Для н = 1 по 10 Цикл

Если н = 2 Тогда
ПоказатьПредупреждение(,НСтр(«ru = ‘Предупрежение'»),,«!!!»);
КонецЕсли;

Сообщить(«Работает цикл » + н);

КонецЦикла;

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

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

&НаКлиенте
Процедура КомандаПредупреждение(Команда)

Ответ = Вопрос(НСтр(«ru = ‘Какой будет ответ на вопрос?'»),РежимДиалогаВопрос.ДаНет);

Если Ответ = КодВозвратаДиалога.Да Тогда

Сообщить(«Да»);
иначе
Сообщить(«Нет»);
КонецЕсли;

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

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

&НаКлиенте
Процедура КомандаПредупреждение(Команда)

Оповещение = Новый ОписаниеОповещения(«ПослеЗакрытияЗакрытияВопроса»,ЭтаФорма,Параметры);

ПоказатьВопрос(Оповещение, НСтр(«ru = ‘Какой будет ответ на вопрос?'»),РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте
Процедура ПослеЗакрытияЗакрытияВопроса(Результат, ДопПараметры) Экспорт

Если Результат = КодВозвратаДиалога.Да тогда
Сообщить(«Ответили «»Да»»»);
иначе
Сообщить(«Ответили «»Нет»»»);
КонецЕсли;

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

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

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

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

И при вызове обработчика события, буду рекурсивно прибавлять этот реквизит. Тем самым мы будем знать, для какого по индексу события вызван наш обработчик.

&НаКлиенте
Процедура КомандаПредупреждение(Команда)

СчетчикВызова = 0;

Массив = Новый Массив;
Структура = Новый Структура(«Массив»,Массив);
Оповещение = Новый ОписаниеОповещения(«ПослеЗакрытияЗакрытияВопроса»,ЭтаФорма,Структура);

Для н = 1 по 100 Цикл

Если н = 10  Тогда
Структура.Массив.Добавить(н);
ПоказатьВопрос(Оповещение, НСтр(«ru = ‘Какой будет ответ на вопрос?'»),РежимДиалогаВопрос.ДаНет);
КонецЕсли;

Если н = 50 Тогда
Структура.Массив.Добавить(н);
ПоказатьВопрос(Оповещение, НСтр(«ru = ‘Какой будет ответ на вопрос?'»),РежимДиалогаВопрос.ДаНет);
КонецЕсли;

Сообщить(«Работает цикл, н = » + н);

КонецЦикла;

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

&НаКлиенте
Процедура ПослеЗакрытияЗакрытияВопроса(Результат, ДопПараметры) Экспорт

Если Результат = КодВозвратаДиалога.Да тогда
Сообщить(«Ответили «»Да»», н = » + ДопПараметры.Массив[СчетчикВызова]);
иначе
Сообщить(«Ответили «»Нет»», н = » + ДопПараметры.Массив[СчетчикВызова]);
КонецЕсли;

СчетчикВызова = СчетчикВызова + 1;
КонецПроцедуры

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

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

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

Книга «Программировать в 1С за 9 шагов»

Изучите программирование в 1С с помощью моей книги «Программировать в 1С за 9 шагов»

  1. Без сложных технических терминов.
  2. Более 500 страниц практического материала.
  3. Каждое задание сопровождается рисунком (скриншот).
  4. Сборник задач для домашней проработки.
  5. Книга написана понятным и простым языком — для новичка.
  6. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!

Промо-код на скидку в 16%: vCph8bW3rE

Вступайте в мои группы:

Вконтакте: https://vk.com/1c_prosto
Фейсбуке: https://www.facebook.com/groups/922972144448119/
ОК: http://ok.ru/group/52970839015518
Твиттер: https://twitter.com/signum2009

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

2 × два =