При работе в веб-клиенте «1С:Предприятие 8.3» разработчики часто сталкиваются с ситуацией, когда код, успешно работающий в тонком клиенте, вызывает критическую ошибку «ошибка отображения типов: отсутствует отображение для типа». Особенно остро эта проблема проявляется при попытке программного подключения расширения работы с файлами или при выгрузке печатных форм. Проанализируем причины этой ошибки и разберем по шагам, как привести код в соответствие с требованиями современной платформы.
Разберем ситуацию: начиная с версии 8.3.15 и выше, платформа активно переходит на асинхронную модель работы. Старые методы, такие как УстановитьРасширениеРаботыСФайлами(), были модальными. Они останавливали выполнение кода до тех пор, пока пользователь не нажмет кнопку или расширение не установится. В веб-клиенте (браузере) такая остановка потока невозможна по соображениям безопасности и архитектуры браузеров.
Рассмотрим ошибку в коде автора темы. Он использует метод НачатьУстановкуРасширенияРаботыСФайлами() и пытается присвоить результат его выполнения переменной. Это в корне неверно. Все функции, начинающиеся с префикса Начать..., возвращают Неопределено. Их результат «возвращается» не в ту же строку, а в специальную процедуру обратного вызова (callback), которую нужно описать через объект ОписаниеОповещения.
Когда платформа в веб-клиенте видит попытку присвоить результат асинхронной системной функции переменной или использовать её в условии Если..., возникает конфликт сериализации, который и выдает «ошибку отображения типов».
Проанализируем вторую критическую ошибку в представленном коде. Посмотрим на строку:
АдресХранилища = ПоместитьДокументВоВременноеХранилищеНаСервере(Расширение, Команда);
Здесь в серверную функцию вторым параметром передается объект Команда (тип КомандаФормы). Важно помнить: объекты интерфейса (команды, элементы формы, сами формы) существуют только на клиенте. Их невозможно «упаковать» (сериализовать) и отправить на сервер, так как на сервере нет контекста отображения. Веб-клиент особенно чувствителен к таким операциям. При попытке передать Команда на сервер, браузер не понимает, как преобразовать этот сложный объект в строку или JSON, и выдает ту самую ошибку отображения типов.
Начиная с версии 8.3.15, в 1С появился более элегантный способ написания асинхронного кода, который выглядит как линейный. Рассмотрим, как должен выглядеть исправленный код с использованием ключевых слов Асинх и Ждать. Этот подход избавляет нас от громоздких «Описаний Оповещений».
&НаКлиенте
Асинх Процедура КомандаПечать(Команда)
// 1. Проверяем расширение асинхронно
РасширениеПодключено = Ждать ПодключитьРасширениеРаботыСФайламиАсинх();
Если Не РасширениеПодключено Тогда
Попытка
Ждать УстановитьРасширениеРаботыСФайламиАсинх();
РасширениеПодключено = Ждать ПодключитьРасширениеРаботыСФайламиАсинх();
Исключение
Сообщить("Не удалось установить расширение.");
Возврат;
КонецПопытки;
КонецЕсли;
Если Не РасширениеПодключено Тогда
Возврат;
КонецЕсли;
// 2. Подготавливаем данные для сервера (только простые типы!)
ИмяКоманды = Команда.Имя;
РасширениеФайла = ".pdf"; // или определяем программно
// Передаем на сервер ИмяКоманды (Строка), а не саму Команду (Объект)
АдресХранилища = Ждать ПоместитьДокументВоВременноеХранилищеНаСервереАсинх(РасширениеФайла, ИмяКоманды);
// 3. Получаем файл
Если ЗначениеЗаполнено(АдресХранилища) Тогда
ИмяФайла = "ПечатнаяФорма" + РасширениеФайла;
ПараметрыПолучения = Новый ПараметрыПолученияФайлов(Истина); // Истина - выбор пути пользователем
Ждать ПолучитьФайлАсинх(АдресХранилища, ИмяФайла, ПараметрыПолучения);
КонецЕсли;
КонецПроцедуры
Если ваша конфигурация должна поддерживать более старые версии платформы или вы не хотите использовать Асинх, необходимо использовать классические callback-процедуры. Разберем этот алгоритм по шагам:
ОписаниеОповещения.НачатьПодключениеРасширенияРаботыСФайлами(), передавая туда оповещение.Рассмотрим пример кода:
&НаКлиенте
Процедура ПодключитьРасширениеИНачатьПечать()
Оповещение = Новый ОписаниеОповещения("ПослеПодключенияРасширения", ЭтотОбъект);
НачатьПодключениеРасширенияРаботыСФайлами(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
Если Подключено Тогда
// Здесь продолжаем логику формирования файла
СформироватьФайлНаСервере();
Иначе
// Просим установить расширение
ОповещениеУстановка = Новый ОписаниеОповещения("ПослеУстановкиРасширения", ЭтотОбъект);
НачатьУстановкуРасширенияРаботыСФайлами(ОповещениеУстановка);
КонецЕсли;
КонецПроцедуры
Выясним причину, почему даже при исправном коде файлы могут не скачиваться в веб-клиенте. Браузеры (Chrome, Firefox, Safari) имеют встроенные системы защиты. Проверьте следующие моменты:
"C:\Temp". Метод ПолучитьФайл в браузере всегда будет предлагать пользователю выбрать место сохранения или автоматически поместит файл в папку «Загрузки».Для устранения ошибки отображения типов в 1С 8.3 при работе с веб-клиентом необходимо выполнить два главных правила:
1. Никогда не передавайте объекты формы или команд на сервер. Используйте только строки, числа, даты, массивы или структуры с простыми типами данных. Если вам нужно передать контекст команды, передайте её имя Команда.Имя как строку.
2. Используйте асинхронность. На платформе 8.3.16 и выше самым надежным способом является использование методов с суффиксом ...Асинх и оператора Ждать. Это сделает ваш код читаемым и избавит от ошибок сериализации типов, которые возникают при попытке «смешать» синхронный и асинхронный стили программирования.