В процессе разработки или поддержки типовых конфигураций «1С:Предприятие 8» программисты часто сталкиваются с системной ошибкой: «Ошибка отображения типов: Отсутствует отображение для типа 'ДинамическийСписок'». Эта проблема возникает в момент выполнения серверного вызова из клиентского контекста. Особенно часто она проявляется в современных версиях ERP, УТ 11 или КА при попытке изменить порядок строк в списке (использование стрелок «Вверх» или «Вниз»).
В данной статье мы подробно проанализируем, почему возникает эта ситуация с точки зрения теории платформы, разберем конкретные примеры ошибочного кода и предложим варианты исправления.
Для начала проанализируем архитектуру взаимодействия слоев «Клиент — Сервер». В платформе 1С существует понятие сериализации — это процесс преобразования объекта в поток данных, который можно передать по сети между клиентским приложением и сервером. Однако не все объекты 1С являются сериализуемыми.
Объект ДинамическийСписок относится к категории интерфейсных объектов. Он неразрывно связан с формой и её контекстом. Платформа 1С спроектирована таким образом, что сам объект списка как программная сущность не имеет «отображения» (mapping) для передачи в качестве параметра процедуры или функции. Когда вы пытаетесь написать МойСерверныйМетод(Список), платформа пытается превратить весь объект списка в байты, не находит соответствующего правила и выдает ошибку.
Важно понимать различие:
ДинамическийСписок доступен на сервере автоматически через контекст формы (ЭтаФорма.Список).ДинамическийСписок при вызове серверной функции из клиентского модуля.Рассмотрим ситуацию, описанную в практике. Ошибка часто возникает в процедурах, отвечающих за перемещение элементов (команды «Переместить вверх», «Переместить вниз»). В коде клиентского модуля это может выглядеть следующим образом:
// Ошибочный фрагмент кода в модуле формы
ТекстОшибки = НастройкаПорядкаЭлементовСлужебныйВызовСервера.ИзменитьПорядокЭлементов(
СписокЭлемент.ТекущиеДанные.Ссылка,
СписокРеквизит, // Здесь передается сам объект списка — это и вызывает ошибку
ОтображениеСписком,
Направление
);
В данном примере переменная СписокРеквизит содержит объект типа ДинамическийСписок. При попытке передать его в общий модуль с признаком «Вызов сервера» платформа блокирует операцию. Проанализируем, как это исправить.
В большинстве случаев серверному методу не нужен сам объект списка. Ему достаточно знать имя реквизита или путь к данным, чтобы программно обратиться к нему в контексте сервера или выполнить запрос к базе данных. Если вы столкнулись с ошибкой в типовом коде БСП (Библиотеки стандартных подсистем), скорее всего, вместо объекта нужно передать строку.
Рассмотрим пример исправления:
// Исправленный фрагмент кода
ИмяСпискаДляСервера = "Список"; // Указываем имя реквизита формы как строку
ТекстОшибки = НастройкаПорядкаЭлементовСлужебныйВызовСервера.ИзменитьПорядокЭлементов(
Элементы.Список.ТекущиеДанные.Ссылка,
ИмяСпискаДляСервера, // Передаем строку, а не объект!
ОтображениеСписком,
Направление
);
Такой подход позволяет серверу идентифицировать, с какими данными ведется работа, не нарушая правил передачи типов между уровнями приложения.
Если ваша задача на сервере требует анализа отборов, группировок или порядка, установленного пользователем в списке, помните: передавать ДинамическийСписок нельзя, но его КомпоновщикНастроек — можно! Объект КомпоновщикНастроекКомпоновкиДанных является сериализуемым и успешно проходит границу «Клиент — Сервер».
Проанализируем ситуацию, когда нам нужно передать настройки на сервер:
// На клиенте
НастройкиСписка = Список.КомпоновщикНастроек.ПолучитьНастройки();
Результат = МойСерверныйМодуль.ОбработатьДанныеСписка(НастройкиСписка);
// На сервере в общем модуле
Функция ОбработатьДанныеСписка(Настройки) Экспорт
// Здесь мы можем использовать полученные настройки для построения запроса
// или анализа пользовательских фильтров
КонецФункции
Часто программисты пытаются передать список на сервер только для того, чтобы получить из него данные текущей строки. Это в корне неверно. Вместо передачи всего объекта ДинамическийСписок, следует передавать только необходимые поля через свойство ТекущиеДанные элемента формы.
Посмотрим на пример правильной передачи ссылки:
&НаКлиенте
Процедура ОбработатьВыбраннуюСтроку()
// Получаем ссылку на текущий элемент
ТекущаяСсылка = Элементы.Список.ТекущиеДанные.Ссылка;
// Передаем на сервер только Ссылку (это ссылочный тип, он отлично сериализуется)
ВыполнитьДействиеНаСервере(ТекущаяСсылка);
КонецПроцедуры
Если вы обнаружили данную ошибку в «чистой» типовой конфигурации (без ваших доработок), выполните следующие шаги:
Резюме: Главная причина ошибки кроется в попытке передать сложный интерфейсный объект туда, где разрешены только простые типы или структуры данных. Всегда помните, что ДинамическийСписок живет в форме, а для работы на сервере вне формы нам нужны либо Ссылка, либо КомпоновщикНастроек, либо просто ИмяРеквизита.