Как исправить ошибку «Отсутствует отображение для типа ValueTable» при передаче данных между сервером и клиентом в 1С

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

При разработке в среде 1С:Предприятие 8.3, особенно при работе с расширениями конфигурации в таких решениях, как УНФ 1.6 или БП 3.0, программисты часто сталкиваются с загадочной ошибкой: Ошибка отображения типов: Отсутствует отображение для типа '{ValueTable}'. Эта ситуация часто ставит в тупик, так как на первый взгляд кажется, что мы передаем между процедурами обычную строку или простое число. Давайте подробно разберем эту ситуацию, проанализируем причины возникновения ошибки и найдем способы её решения.

Суть проблемы и механизм возникновения ошибки

Рассмотрим стандартную ситуацию: в расширении формы документа или справочника создается процедура, которая вызывает серверный метод для получения данных о контрагенте по его ИНН. Программист уверен, что передает строку (ИНН) и получает результат на сервере. Однако при попытке завершить серверный вызов и вернуть управление на клиентскую сторону платформа выбрасывает исключение Ошибка преобразования данных XDTO.

Проанализируем, почему это происходит. В управляемом приложении 1С существует жесткое разделение между объектами, которые могут существовать на клиенте и на сервере. ТаблицаЗначений (ValueTable) — это чисто серверный тип данных. Он не может быть передан на клиент напрямую. Для отображения таблиц на форме используются специальные типы, такие как ДанныеФормыКоллекция. Ошибка возникает в тот момент, когда платформа пытается «сериализовать» (преобразовать в поток данных) состояние формы для отправки его с сервера на клиент, но натыкается на объект, который не умеет «путешествовать» через границу между сервером и клиентом. При необходимости можно изучить руководство по основам работы с таблицами и деревьями значений в управляемой форме.

Выясняем причину: конфликт имен (Shadowing)

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


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

В данном примере функция РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН) возвращает Структуру. Казалось бы, структура допустима для передачи. Но внутри этой структуры, в зависимости от версии БСП и ответа сервиса «1С:Контрагент», могут содержаться вложенные Таблицы значений (например, список лицензий или филиалов).

Когда вы присваиваете значение переменной РеквизитыКонтрагента, платформа 1С считает, что вы обращаетесь к реквизиту формы с тем же именем. Даже если в коде это выглядит как создание новой переменной, контекст формы имеет приоритет. В итоге, в реквизит формы записывается тип ТаблицаЗначений. Как только процедура заканчивается, платформа пытается синхронизировать данные формы с клиентом и «падает», так как не может передать таблицу значений. Разобраться в тонкостях разграничения контекста поможет руководство по исполнению кода в модуле формы.

Решение №1: Использование уникальных имен переменных

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

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


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

В этом случае ДанныеИзСервиса является локальной переменной. После завершения серверной процедуры она просто уничтожается в памяти сервера и не пытается передаться на клиент. Проблема исчезает.

Решение №2: Очистка кэша программных интерфейсов

Иногда ошибка Отсутствует отображение для типа может возникать не из-за кода программиста, а из-за некорректной работы кэша платформы при взаимодействии с веб-сервисами. Функция СведенияОЮридическомЛицеПоИНН обращается к внешнему сервису 1С.

Если вы уверены, что с именами переменных все в порядке, попробуйте выполнить следующие действия:

  1. Перейдите в раздел Администрирование — Обслуживание.
  2. Найдите пункт, связанный с очисткой кэша (в некоторых конфигурациях это «Кэш программных интерфейсов» в регистре сведений).
  3. Очистите записи, связанные с сервисом api.orgregister.1c.ru.

Это заставит платформу заново инициализировать описание типов XDTO и может устранить проблему с «невидимыми» для системы типами данных.

Решение №3: Разбор возвращаемого значения «на месте»

Если вам нужно получить данные и вы не хотите плодить лишние переменные, проанализируем ситуацию, когда данные разбираются сразу в месте вызова. Важно понимать, что возвращает функция общего модуля. Если это структура, содержащая ValueTable, вы не должны пытаться вернуть эту структуру на клиент целиком.

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


&НаСервере
Функция ПолучитьКраткиеСведения(ИНН)
    РезультатФункции = РаботаСКонтрагентами.СведенияОЮридическомЛицеПоИНН(ИНН);
    
    // Создаем «чистую» структуру для передачи на клиент
    ДанныеДляКлиента = Новый Структура;
    ДанныеДляКлиента.Вставить("Наименование", РезультатФункции.Наименование);
    ДанныеДляКлиента.Вставить("Адрес", РезультатФункции.АдресРФ);
    
    // Мы сознательно НЕ передаем таблицы значений, которые могли быть в РезультатФункции
    Возврат ДанныеДляКлиента; 
КонецФункции

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

Важные выводы для разработчика

Проанализировав данную проблему, мы можем сформулировать несколько правил, которые помогут избежать подобных ошибок в будущем:

  1. Внимательно следите за областью видимости: В серверных процедурах формы все реквизиты формы доступны напрямую по именам. Не создавайте локальные переменные с такими же именами.
  2. Тип имеет значение: Всегда проверяйте, что именно возвращает функция общего модуля. Если в описании функции указано, что она возвращает структуру, не поленитесь зайти в неё отладчиком и посмотреть состав этой структуры. Наличие там Таблицы значений — «красный флаг» для передачи на клиент.
  3. Сериализация XDTO: Если вы видите упоминание XDTO в ошибке, значит, 1С пытается превратить объект в XML/JSON для передачи, и этот объект «слишком сложный» для текущего контекста.
  4. Особенности расширений: В расширениях конфигурации механизмы проверки имен могут работать специфично. Будьте вдвойне внимательны при написании кода в модулях расширений форм.

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

← На главную