При разработке в управляемом приложении 1С программисты часто сталкиваются с ошибкой передачи данных между контекстами клиента и сервера: «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа». Разберем подробнее, почему возникает эта проблема, какие типы данных нельзя передавать напрямую и как правильно организовать получение и передачу списков документов и табличных данных на форме.
При выполнении контекстного вызова сервера платформа 1С производит XDTO-сериализацию всех параметров, передаваемых между клиентом и сервером. Если среди параметров или в возвращаемом значении функции оказывается объект, который не поддерживает автоматическую сериализацию, платформа генерирует исключение.
Главная причина заключается в попытке передать серверный объект на клиентскую сторону. К объектам, недопустимым для прямой передачи между клиентом и сервером, относятся:
ТаблицаЗначений, ДеревоЗначений, СтрокаТаблицыЗначений, Запрос, РезультатЗапроса.СправочникОбъект, ДокументОбъект и аналогичные типы. На клиенте могут существовать исключительно ссылки, например ДокументСсылка или СправочникСсылка.УправляемаяФорма и ее элементы.Если задача заключается в том, чтобы получить с сервера и передать на клиент список ссылок (например, массив или список документов tertentu), вместо ТаблицаЗначений следует использовать сериализуемые типы: СписокЗначений или Массив.
Рассмотрим пример функции на сервере, которая формирует и возвращает СписокЗначений со ссылками на документы:
&НаСервере
Функция ПолучитьСписокДокументовНаСервере()
СписокДокументов = Новый СписокЗначений;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СборкаЗапасов.Ссылка КАК Ссылка
|ИЗ
| Документ.СборкаЗапасов КАК СборкаЗапасов";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СписокДокументов.Добавить(Выборка.Ссылка);
КонецЦикла;
Возвращать СписокДокументов;
КонецФункции
Поскольку СписокЗначений состоит из ссылок типа ДокументСсылка, он успешно передается на клиент без вызова ошибки.
Если табличные данные необходимо отобразить в интерфейсе управляемой формы, прямое использование типа ТаблицаЗначений на клиенте невозможно. Для этого на форме создается реквизит с типом ТаблицаЗначений, который на клиенте представлен объектом ДанныеФормыКоллекция.
Преобразование выполняется специализированными процедурами платформы:
ЗначениеВДанныеФормы(ТаблицаИсточника, РеквизитФормы) на сервере.ДанныеФормыВЗначение(РеквизитФормы, Тип("ТаблицаЗначений")).Посмотрим на пример заполнения реквизита формы на сервере:
&НаСервере
Процедура ЗаполнитьТаблицуНаФормеСервер()
ВременнаяТЗ = Новый ТаблицаЗначений;
ВременнаяТЗ.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ДокументСсылка.СборкаЗапасов"));
// Заполнение таблицы значений нужными данными
// ...
// Конвертация в реквизит формы
ЗначениеВДанныеФормы(ВременнаяТЗ, Объект.СборкаЗапасовТаблица);
КонецПроцедуры
Когда требуется передать сложную табличную структуру на клиент, но привязывать её к реквизитам формы не нужно, оптимальным решением выступает формирование массива структур. Объекты Массив и Структура свободно передаются между клиентом и сервером, если их элементы содержат базовые типы или ссылки.
&НаСервере
Функция ПолучитьТабличныеДанныеНаСервере()
РезультатМассив = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Т.Ссылка КАК Ссылка,
| Т.Дата КАК Дата
|ИЗ
| Документ.СборкаЗапасов КАК Т";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Стр = Новый Структура;
Стр.Вставить("Ссылка", Выборка.Ссылка);
Стр.Вставить("Дата", Выборка.Дата);
РезультатМассив.Добавить(Стр);
КонецЦикла;
Возвращать РезультатМассив;
КонецФункции
Если ТаблицаЗначений или иной серверный объект формируется в одном серверном контексте и требуется исключительно для последующей обработки в другом серверном вызове без необходимости разбора на клиенте, используйте временное хранилище:
ПоместитьВоВременноеХранилище() и получаем строковый адрес.Строка) на клиент.ПолучитьИзВременногоХранилища().Таким образом, для исключения ошибки «Значение недопустимого типа» всегда контролируйте типы данных, пересекающие границу клиент-серверного взаимодействия, и используйте СписокЗначений, Массив, Структура или реквизиты формы.