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