Кто программировал в версиях 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С за 11 шагов»
Изучайте программирование в 1С в месте с моей книги «Программировать в 1С за 11 шагов»
- Книга написана понятным и простым языком — для новичка.
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Научитесь понимать архитектуру 1С;
- Станете писать код на языке 1С;
- Освоите основные приемы программирования;
- Закрепите полученные знания при помощи задачника;
Книга «Основы разработки в 1С: Такси»
Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Промо-код на скидку в 15% — 48PVXHeYu
Если Вам помог этот урок решить какую-нибудь проблему, понравился или оказался полезен, то Вы можете поддержать мой проект, перечислив любую сумму:
можно оплатить вручную:
Яндекс.Деньги — 410012882996301
Web Money — R955262494655
Вступайте в мои группы:
Вконтакте: https://vk.com/1c_prosto
Фейсбуке: https://www.facebook.com/groups/922972144448119/
ОК: http://ok.ru/group/52970839015518
Твиттер: https://twitter.com/signum2009