При разработке в среде 1С:Предприятие 8.3, особенно при работе с расширениями конфигурации в таких решениях, как УНФ 1.6 или БП 3.0, программисты часто сталкиваются с загадочной ошибкой: Ошибка отображения типов: Отсутствует отображение для типа '{ValueTable}'. Эта ситуация часто ставит в тупик, так как на первый взгляд кажется, что мы передаем между процедурами обычную строку или простое число. Давайте подробно разберем эту ситуацию, проанализируем причины возникновения ошибки и найдем способы её решения.
Рассмотрим стандартную ситуацию: в расширении формы документа или справочника создается процедура, которая вызывает серверный метод для получения данных о контрагенте по его ИНН. Программист уверен, что передает строку (ИНН) и получает результат на сервере. Однако при попытке завершить серверный вызов и вернуть управление на клиентскую сторону платформа выбрасывает исключение Ошибка преобразования данных XDTO.
Проанализируем, почему это происходит. В управляемом приложении 1С существует жесткое разделение между объектами, которые могут существовать на клиенте и на сервере. ТаблицаЗначений (ValueTable) — это чисто серверный тип данных. Он не может быть передан на клиент напрямую. Для отображения таблиц на форме используются специальные типы, такие как ДанныеФормыКоллекция. Ошибка возникает в тот момент, когда платформа пытается «сериализовать» (преобразовать в поток данных) состояние формы для отправки его с сервера на клиент, но натыкается на объект, который не умеет «путешествовать» через границу между сервером и клиентом. При необходимости можно изучить руководство по основам работы с таблицами и деревьями значений в управляемой форме.
Одной из самых коварных причин возникновения этой ошибки является совпадение имени локальной переменной внутри серверной процедуры с именем реквизита формы. Давайте посмотрим на пример кода, который вызывает проблему:
&НаСервере
Процедура ОбновитьДанныеКонтрагента(Знач ИНН)
// РеквизитыКонтрагента — это и имя реквизита формы, и локальная переменная
РеквизитыКонтрагента = РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН);
КонецПроцедуры
В данном примере функция РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН) возвращает Структуру. Казалось бы, структура допустима для передачи. Но внутри этой структуры, в зависимости от версии БСП и ответа сервиса «1С:Контрагент», могут содержаться вложенные Таблицы значений (например, список лицензий или филиалов).
Когда вы присваиваете значение переменной РеквизитыКонтрагента, платформа 1С считает, что вы обращаетесь к реквизиту формы с тем же именем. Даже если в коде это выглядит как создание новой переменной, контекст формы имеет приоритет. В итоге, в реквизит формы записывается тип ТаблицаЗначений. Как только процедура заканчивается, платформа пытается синхронизировать данные формы с клиентом и «падает», так как не может передать таблицу значений. Разобраться в тонкостях разграничения контекста поможет руководство по исполнению кода в модуле формы.
Самый простой и правильный способ решения — всегда давать локальным переменным имена, которые гарантированно не совпадают с реквизитами формы. В стандартах разработки 1С рекомендуется использовать префиксы или осмысленные названия.
Разберем исправленный вариант кода:
&НаСервере
Процедура ОбновитьДанныеКонтрагента(Знач ИНН)
// Используем уникальное имя переменной, например, мДанныеИзСервиса
ДанныеИзСервиса = РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН);
// Теперь мы можем безопасно перенести только нужные нам данные в реквизиты формы
Если ТипЗнч(ДанныеИзСервиса) = Тип("Структура") Тогда
Объект.КПП = ДанныеИзСервиса.КПП;
Объект.НаименованиеПолное = ДанныеИзСервиса.НаименованиеПолное;
КонецЕсли;
КонецПроцедуры
В этом случае ДанныеИзСервиса является локальной переменной. После завершения серверной процедуры она просто уничтожается в памяти сервера и не пытается передаться на клиент. Проблема исчезает.
Иногда ошибка Отсутствует отображение для типа может возникать не из-за кода программиста, а из-за некорректной работы кэша платформы при взаимодействии с веб-сервисами. Функция СведенияОЮридическомЛицеПоИНН обращается к внешнему сервису 1С.
Если вы уверены, что с именами переменных все в порядке, попробуйте выполнить следующие действия:
api.orgregister.1c.ru.Это заставит платформу заново инициализировать описание типов XDTO и может устранить проблему с «невидимыми» для системы типами данных.
Если вам нужно получить данные и вы не хотите плодить лишние переменные, проанализируем ситуацию, когда данные разбираются сразу в месте вызова. Важно понимать, что возвращает функция общего модуля. Если это структура, содержащая ValueTable, вы не должны пытаться вернуть эту структуру на клиент целиком.
Рассмотрим правильный подход к обработке результата:
&НаСервере
Функция ПолучитьКраткиеСведения(ИНН)
РезультатФункции = РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН);
// Создаем «чистую» структуру для передачи на клиент
ДанныеДляКлиента = Новый Структура;
ДанныеДляКлиента.Вставить("Наименование", РезультатФункции.Наименование);
ДанныеДляКлиента.Вставить("Адрес", РезультатФункции.АдресРФ);
// Мы сознательно НЕ передаем таблицы значений, которые могли быть в РезультатФункции
Возврат ДанныеДляКлиента;
КонецФункции
Такой подход гарантирует, что между сервером и клиентом будут перемещаться только простые типы данных (строки, числа, даты) или коллекции, состоящие из простых типов.
Проанализировав данную проблему, мы можем сформулировать несколько правил, которые помогут избежать подобных ошибок в будущем:
Таблицы значений — «красный флаг» для передачи на клиент.Соблюдение этих правил и понимание того, как данные циркулируют между клиентом и сервером, позволит вам писать стабильный код и быстро локализовать ошибки преобразования типов.