Как исправить ошибку «Отсутствует отображение для типа ДанныеФормыЭлементКоллекции» при вызове сервера в 1С?

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

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

Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка отображения типов: Отсутствует отображение для типа 'ДанныеФормыЭлементКоллекции'.

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

Суть проблемы и причины ошибки

Проанализируем ситуацию на примере вызова процедуры добавления контактной информации. На клиенте выполняется вызов серверной процедуры:


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

На сервере объявлена процедура с необязательным параметром:


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

Выясним причину сбоя. В платформе 1С по умолчанию все параметры процедур и функций передаются по ссылке (значение переменной может быть изменено внутри процедуры и возвращено вызывающему коду). Когда серверная процедура завершает свою работу, платформа пытается передать изменённое значение параметра обратно на клиент.

В процессе выполнения процедуры переменной ДанныеКИ присваивается новая строка таблицы формы, имеющая тип ДанныеФормыЭлементКоллекции. Этот тип предназначен исключительно для работы с коллекциями управляемой формы в контексте сервера и не поддерживает сериализацию для передачи через клиент-серверную границу обратно на клиент. Попытка возврата этого значения вызывает ошибку преобразования XDTO.

Способ 1. Использование ключевого слова Знач

Самое простое и быстрое решение — явно указать платформе, что параметр передаётся по значению и его изменённое внутри процедуры состояние не требуется возвращать на клиент. Для этого в заголовке серверной процедуры перед именем параметра добавляем ключевое слово Знач.

Рассмотрим исправленный заголовок процедуры:


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

Способ 2. Использование локальной переменной

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

Проанализируем пример реализации с отдельной переменной:


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

Поскольку входной параметр ДанныеКИ остался равен Неопределено, платформа благополучно передаст его значение обратно на клиент без ошибок сериализации.

Способ 3. Передача идентификатора вместо объекта строки

Если с клиента на сервер необходимо передать ссылку на уже существующую строку таблицы формы, не следует передавать объект типа ДанныеФормыЭлементКоллекции целиком. Передавайте только его числовой идентификатор.

Разберем данный подход по шагам:

  1. На клиенте получаем идентификатор строки методом ПолучитьИдентификатор() и передаем его на сервер как простое число.
  2. На сервере находим нужную строку в коллекции реквизита формы методом НайтиПоИдентификатору().

// Вызов на клиенте:
ИдентификаторСтроки = Элементы.ДанныеКонтактныхЛиц.ТекущиеДанные.ПолучитьИдентификатор();
ОбработатьСтрокуНаСервере(ИдентификаторСтроки);

// Выполнение на сервере:
&НаСервере
Процедура ОбработатьСтрокуНаСервере(Знач ИдентификаторСтроки)
    СтрокаКИ = ДанныеКонтактныхЛиц.НайтиПоИдентификатору(ИдентификаторСтроки);
    Если СтрокаКИ <> Неопределено Тогда
        // Выполняем необходимые действия со строкой
    КонецЕсли;
КонецПроцедуры

Резюме

Чтобы избежать ошибок типа Отсутствует отображение для типа ДанныеФормыЭлементКоллекции, соблюдайте базовые правила клиент-серверного взаимодействия в управляемом приложении:

← На главную