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