Разработчики при переходе на новые релизы платформы 1С:Предприятие 8.3 часто сталкиваются с ситуацией, когда стабильно работавший ранее код перестает функционировать. Одной из таких проблем является «молчаливое» невыполнение метода ПоказатьВыборИзСписка. Всплывающее окно со списком выбора просто не появляется на экране, при этом система не выдает никаких видимых ошибок.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы работы платформы 1С и рассмотрим надежные способы решения данной задачи.
Проанализируем пример кода, с которым столкнулся автор темы на форуме. На первый взгляд, процедура выглядит абсолютно стандартно:
&НаКлиенте
Процедура СостояниеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ВидыПДР = ЭтаФорма.Элементы.Состояние.СписокВыбора;
ДопПараметры = Новый Структура;
ОписаниеОповещения = Новый ОписаниеОповещения("ОбработкаОповещенияВыбораТипа", ЭтаФорма, ДопПараметры);
ПоказатьВыборИзСписка(ОписаниеОповещения, ВидыПДР);
СостояниеНачалоВыбораНаСервере(); // Контекстный серверный вызов!
КонецПроцедуры
Выясним, почему этот код перестал работать на платформе версии 8.3.13 и выше. Дело в том, что метод ПоказатьВыборИзСписка является асинхронным. Платформа 1С не приостанавливает выполнение кода в ожидании выбора пользователя, а лишь регистрирует в очереди задач интерфейса команду на показ всплывающего окна и мгновенно переходит к следующей строке.
Следующей строкой у нас идет вызов контекстной серверной процедуры СостояниеНачалоВыбораНаСервере(). При выполнении контекстного вызова происходит следующее:
Этот агрессивный процесс обновления контекста на клиенте полностью сбрасывает и отменяет запланированную асинхронную задачу по выводу всплывающего меню. Список выбора просто уничтожается интерфейсным движком платформы еще до того, как успевает отобразиться на экране.
Как решить эту проблему: необходимо полностью исключить любые контекстные серверные вызовы сразу после инициализации асинхронного окна. Если вам требуется получить данные для списка выбора с сервера, делайте это до вызова метода ПоказатьВыборИзСписка, причем строго с использованием внеконтекстных процедур или функций с директивой &НаСервереБезКонтекста.
Рассмотрим правильный вариант реализации:
&НаСервереБезКонтекста
Функция ПолучитьСписокВыбораНаСервере()
СписокЗначений = Новый СписокЗначений;
СписокЗначений.Добавить(Перечисления.асСостоянияЗаказНаряда.ВРаботе);
СписокЗначений.Добавить(Перечисления.асСостоянияЗаказНаряда.Выполнено);
Возврат СписокЗначений;
КонецФункции
&НаКлиенте
Процедура СостояниеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Сначала получаем данные без контекста формы
ВидыПДР = ПолучитьСписокВыбораНаСервере();
ДопПараметры = Новый Структура;
ОписаниеОповещения = Новый ОписаниеОповещения("ОбработкаОповещенияВыбораТипа", ЭтаФорма, ДопПараметры);
// Показываем список выбора, не вызывая сервер после этого
ПоказатьВыборИзСписка(ОписаниеОповещения, ВидыПДР, Элемент);
КонецПроцедуры
Если же серверную логику требуется выполнить уже после того, как пользователь сделает свой выбор, перенесите все серверные вызовы в процедуру-обработчик оповещения (в нашем примере это ОбработкаОповещенияВыбораТипа).
Третий параметр метода ПоказатьВыборИзСписка отвечает за позиционирование выпадающего меню на экране. С ним связаны две частые ошибки разработчиков:
Элементы.ИмяКнопкиПанели приведет к тому, что платформа аварийно завершит выполнение метода или проигнорирует его.Элемент, переданный в обработчик события.Очень простая, но частая ошибка — передача пустого объекта СписокЗначений. Если ваш запрос к базе данных на сервере вернул ноль строк или условие заполнения списка не отработало, платформа 1С не будет выводить пустое серое окно. Метод ПоказатьВыборИзСписка отработает абсолютно беззвучно, не выводя никаких предупреждений в журнал регистрации. Перед вызовом метода обязательно проверяйте количество элементов в списке выбора:
Если ВидыПДР.Количество() > 0 Тогда
ПоказатьВыборИзСписка(ОписаниеОповещения, ВидыПДР, Элемент);
Иначе
ПоказатьПредупреждение(, "Список выбора пуст!");
КонецЕсли;
Даже если само меню успешно отображается, дальнейший алгоритм может прерываться из-за неверно настроенного объекта ОписаниеОповещения. Помните о следующих правилах:
ОбработкаОповещенияВыбораТипа) должна быть объявлена строго на клиенте с директивой &НаКлиенте и обязательно должна иметь ключевое слово Экспорт.Если ваше приложение запускается в браузере (веб-клиент), то отображение всплывающих списков напрямую зависит от настроек безопасности веб-браузера. Некоторые браузеры распознают динамически создаваемые списки как нежелательные всплывающие окна и блокируют их встроенным компонентом Pop-up Blocker. Убедитесь, что для адреса вашей информационной базы в браузере добавлены разрешения на показ всплывающих окон.
Проанализировав все указанные нюансы и следуя правилу разделения контекста интерфейса и серверных вызовов, вы сможете обеспечить стабильную работу метода ПоказатьВыборИзСписка на любых современных версиях платформы 1С:Предприятие 8.3.