Как исправить ошибку «Отсутствует отображение для типа 'ЭлементСпискаЗначений'» при использовании метода ПоказатьВыборИзСписка

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на асинхронные методы работы в управляемом приложении 1С:Предприятие 8.3 разработчики часто сталкиваются с ошибкой «Отсутствует отображение для типа 'ЭлементСпискаЗначений'». Эта проблема возникает в момент завершения выбора значения из списка, когда система пытается передать результат в процедуру обработки. Разберем подробно, почему это происходит и как правильно организовать код, чтобы избежать подобных ошибок и обеспечить корректное обновление данных на форме.

Почему возникает ошибка отображения типа

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

Основная причина ошибки заключается в том, что процедура обратного вызова для интерактивных методов должна располагаться строго на клиенте (директива &НаКлиенте). Когда вы указываете в качестве обработчика серверную процедуру или функцию, платформа пытается передать выбранный объект (тип ЭлементСпискаЗначений) с клиента на сервер. Однако данный тип не является сериализуемым для передачи между контекстами в рамках обработки оповещения. Система «не знает», как отобразить (передать) этот объект на сервер, и выбрасывает исключение.

Правильная структура кода для выбора из списка

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

Шаг 1. Инициирование выбора на клиенте

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


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    Если Поле.Имя = "Статус" Тогда
        СтандартнаяОбработка = Ложь;
        
        // Получаем список значений (можно реализовать получение с сервера)
        СписокСтатусов = ПолучитьСписокСтатусовНаСервере();
        
        // Извлекаем необходимые данные из текущей строки
        ТекущиеДанные = Элемент.ТекущиеДанные;
        Если ТекущиеДанные = Неопределено Тогда
            Возврат;
        КонецЕсли;
        
        УИД = ТекущиеДанные.УникальныйИдентификаторУслуги;
    
        // Создаем описание оповещения, указывая КЛИЕНТСКУЮ процедуру
        Оповещение = Новый ОписаниеОповещения("ВыполнитьПослеВыбора", ЭтотОбъект, УИД);
        
        // Открываем список выбора
        ПоказатьВыборИзСписка(Оповещение, СписокСтатусов, Элемент);
    КонецЕсли;
КонецПроцедуры

Шаг 2. Обработка выбора в клиентской процедуре

Проанализируем клиентскую процедуру ВыполнитьПослеВыбора. Именно здесь система вернет нам выбранный элемент. Обратите внимание, что параметр Результат будет содержать объект типа ЭлементСпискаЗначений, если выбор сделан, или Неопределено, если пользователь закрыл список без выбора.


&НаКлиенте
Процедура ВыполнитьПослеВыбора(Результат, ДополнительныеПараметры) Экспорт
    
    // Проверяем, что пользователь не отменил выбор
    Если Результат = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Извлекаем само значение из элемента списка (например, ссылку на перечисление)
    ВыбранноеЗначение = Результат.Значение;
    ИдентификаторЗаписи = ДополнительныеПараметры;
    
    // Передаем чистые данные на сервер для обработки
    ЗаписатьСтатусНаСервере(ВыбранноеЗначение, ИдентификаторЗаписи);
    
    // Обновляем данные формы
    Элементы.Список.Обновить(); 
КонецПроцедуры

Шаг 3. Работа с данными на сервере

Для записи данных в базу (например, в регистр сведений) используем серверную процедуру. Рекомендуется использовать директиву &НаСервереБезКонтекста, если вам не требуются данные всей формы. Это значительно ускоряет выполнение кода, так как контекст формы не передается туда-обратно.


&НаСервереБезКонтекста
Процедура ЗаписатьСтатусНаСервере(НовыйСтатус, УИД)
    
    МенеджерЗаписи = РегистрыСведений.СтатусыУслуг.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.УникальныйИдентификаторУслуги = УИД;
    МенеджерЗаписи.Прочитать();
    
    МенеджерЗаписи.Статус = НовыйСтатус;
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСписокСтатусовНаСервере()
    Список = Новый СписокЗначений;
    Для Каждого ЗначениеИзМетаданных Из Перечисления.Статусы Цикл
        Список.Добавить(ЗначениеИзМетаданных);
    КонецЦикла;
    Возврат Список;
КонецФункции

Обновление данных в динамическом списке

Разберем ситуацию, когда после изменения статуса данные в списке на форме не обновляются. Часто разработчики пытаются использовать метод ЭтаФорма.ОбновитьОтображениеДанных(). Однако выясним причину, почему это не помогает: данный метод отвечает только за визуальную «перерисовку» элементов интерфейса (например, условное оформление или доступность кнопок), но он не перечитывает данные из базы данных.

Для динамического списка (объект ДинамическийСписок) необходимо использовать метод элемента формы:

Элементы.ИмяВашегоСписка.Обновить();

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

Важные рекомендации

  1. Ключевое слово Экспорт: Процедуру обратного вызова в модуле формы рекомендуется помечать словом Экспорт. В некоторых версиях платформы и режимах работы это критично для корректного вызова процедуры оповещения.
  2. Параметры ОписанияОповещения: Всегда передавайте необходимые для идентификации строки данные (например, УИД или Ссылку) через третий параметр конструктора Новый ОписаниеОповещения(..., ..., ДополнительныеПараметры). Это гарантирует, что к моменту завершения выбора вы будете знать, для какой именно строки базы данных выполняется действие, даже если пользователь успел переключиться на другую строку.
  3. Тип результата: Помните, что ПоказатьВыборИзСписка возвращает ЭлементСпискаЗначений. Чтобы получить саму ссылку или значение, всегда обращайтесь к свойству .Значение полученного объекта.

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

← На главную