Почему возникает ошибка "Отсутствует отображение для типа" при передаче клиентских объектов внешних компонент в серверные процедуры 1С?

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

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

Разберем ситуацию: клиентский объект на сервере

Представим типовой сценарий, описанный вами: у нас есть внешний компонент, например, драйвер ККТ (как ATOL_KKT_1C_V10) или специализированная внешняя компонента SignotecPad для работы с дисплеями подписи, который работает на стороне клиента. Мы инициализируем этот компонент в клиентском общем модуле (например, ПодключаемоеОборудованиеДрайверСинхронноКлиент) и получаем от него некоторые данные или ссылки на объекты, такие как ОбъектДрайвера или переменную ПараметрыККТ. Аналогичная ситуация может возникнуть, когда выполняется подключение Bluetooth сканера через NativeApi в мобильном клиенте.

Суть проблемы: После получения этих данных на клиенте, мы пытаемся передать переменную ПараметрыККТ в серверную процедуру, например, ДанныеККМ.ЗаписатьДанныеКассыВРегистр(ПараметрыККТ). В этот момент платформа 1С выдает ошибку, указывая, что для типа, связанного с внешним компонентом (например, AddIn.С2acc436546435442ac7fdb42e47acbf.ATOL_KKT_1C_V10), отсутствует отображение на сервере. Сама серверная процедура при этом даже не начинает свое выполнение.

Посмотрим на пример кода, где возникла проблема:

Клиентская часть (фрагмент общего модуля ПодключаемоеОборудованиеДрайверСинхронноКлиент с галкой "Клиент"):


Процедура ОткрытьСмену(ОбъектДрайвера, ПараметрыПодключения, ДанныеОперации, РезультатВыполнения)
	
	// ...
	ИначеЕсли ПараметрыПодключения.ТипОборудования = "ККТ" Тогда
		
		Попытка
			ПараметрыККТ = "";
			// Здесь ОбъектДрайвера - это клиентский объект внешней компоненты
			Результат = ОбъектДрайвера.ПолучитьПараметрыККТ(ПараметрыПодключения.ИДУстройства, ПараметрыККТ);
		Исключение
			// ... обработка ошибки
			Возврат;
		КонецПопытки;
		
		// Далее следует попытка передать ПараметрыККТ на сервер
		// ...
		// Вызов серверной процедуры:
		// ДанныеККМ.ЗаписатьДанныеКассыВРегистр(ПараметрыККТ);
		// ...
	КонецЕсли;
	
КонецПроцедуры

Серверная часть (фрагмент общего модуля ДанныеККМ с галкой "Вызов сервера" или "Сервер"):


Процедура ЗаписатьДанныеКассыВРегистр(Знач ПараметрыККТ) Экспорт 
   // Сюда выполнение даже не доходит, ошибка возникает раньше
   А=1; // Эта строка не выполняется
			
КонецПроцедуры

Выясним причину ошибки

Причина этой ошибки кроется в архитектуре платформы 1С:Предприятие, которая является клиент-серверной. Клиентское приложение и сервер 1С — это два отдельных процесса. Для своевременного выявления подобных проблем на этапе разработки рекомендуется использовать статический анализатор кода проектов, который помогает отследить некорректную передачу типов.

  1. Контекст выполнения: Объекты, созданные на клиенте (например, экземпляры внешних компонент, элементы управляемых форм), существуют только в контексте клиентского приложения. Сервер 1С не имеет доступа к ним напрямую.
  2. Сериализация данных: При вызове серверной процедуры из клиентского кода, платформа пытается сериализовать все параметры, передаваемые на сервер.
  3. Отсутствие отображения типов: Если в параметрах передается объект, специфичный для клиента, платформа на сервере не может найти соответствующее "отображение". Эта проблема актуальна не только для NativeApi, но и когда вы используете, например, Com объект на Python для 1С в клиентском окружении. Сервер просто не "знает", что это за объект.

Важный момент: Мы не можем передавать сами объекты внешних компонент с клиента на сервер, поскольку сервер не сможет их инициализировать.

Как решить проблему: Передача сериализуемых данных

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

Рассмотрим подробнее шаги, которые мы предпримем для исправления ситуации:

  1. Получение данных на клиенте: Мы по-прежнему взаимодействуем с внешней компонентой на стороне клиента.
  2. Преобразование данных в структуру: Вместо того чтобы передавать сам объект, мы извлекаем из него только необходимые значения и помещаем их в структуру 1С.
  3. Передача структуры на сервер: Мы передаем эту "очищенную" структуру на сервер.
  4. Обработка данных на сервере: Серверная процедура получает структуру и использует содержащиеся в ней данные.

Пример кода реализации

Давайте посмотрим, как это выглядит на практике. Мы модифицируем клиентскую часть, чтобы подготовить данные.

1. Клиентская часть: извлечение и упаковка данных


// Создаем структуру для передачи на сервер
ПередаваемыеПараметрыККТ = Новый Структура();

// Пример извлечения данных из ПараметрыККТ (если это структура, полученная от ВК)
Если ТипЗнч(ПараметрыККТ) = Тип("Структура") Тогда
    Для Каждого КлючЗначение Из ПараметрыККТ Цикл
        // Проверяем, что значение сериализуемо
        Если ТипЗнч(КлючЗначение.Значение) = Тип("Строка") ИЛИ
           ТипЗнч(КлючЗначение.Значение) = Тип("Число") ИЛИ
           ТипЗнч(КлючЗначение.Значение) = Тип("Булево") ИЛИ
           ТипЗнч(КлючЗначение.Значение) = Тип("Дата") Тогда
            ПередаваемыеПараметрыККТ.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

// Теперь вызываем серверную процедуру
ДанныеККМ.ЗаписатьДанныеКассыВРегистр(ПередаваемыеПараметрыККТ);

2. Серверная часть: прием и обработка структуры


Процедура ЗаписатьДанныеКассыВРегистр(Знач ПараметрыККТСтруктура) Экспорт 
	
	// Теперь мы успешно получаем структуру на сервере
	Попытка
		ВерсияФН        = ПараметрыККТСтруктура.ВерсияФН;
		ЗаводскойНомер  = ПараметрыККТСтруктура.ЗаводскойНомер;
		// ... заполняем и записываем данные в регистр
	Исключение
		// Обработка ошибок
	КонецПопытки;
	
КонецПроцедуры

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

Дополнительные рекомендации

Мы надеемся, что это подробное объяснение поможет вам строить более надежные и эффективные решения на платформе 1С:Предприятие!

← На главную