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