К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: что можно передать с клиента на сервер

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

В управляемом приложении 1С код выполняется в двух средах: на клиенте (тонкий, толстый или веб-клиент) и на сервере. При вызове серверной процедуры из клиентского кода параметры физически сериализуются и передаются по сети, поэтому платформа накладывает жёсткие ограничения на типы, которые могут «пересечь» границу клиент–сервер. Непонимание этих правил — причина типовых ошибок вида «Ошибка передачи данных между клиентом и сервером. Недопустимое значение».

Главный принцип: через границу проходят только типы, которые платформа умеет сериализовать и восстановить на другой стороне. Это примитивные типы, коллекции из них, ссылки на объекты базы данных и ряд специальных структур. Не передаются объекты, привязанные к контексту исполнения: элементы формы, объекты типа «ОбработкаОбъект», «ДокументОбъект», COM-объекты, временные таблицы запросов и тому подобное.

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

Какие примитивные типы и коллекции передаются без ограничений

Базовый набор, который всегда безопасно передавать в параметрах серверных процедур и функций: Число, Строка, Дата, Булево, Неопределено, Null, Тип, УникальныйИдентификатор и ДвоичныеДанные. Эти значения копируются при передаче, и на сервере вы работаете с полноценной копией.

Из универсальных коллекций сериализуются Массив, Структура, Соответствие, СписокЗначений, ТаблицаЗначений и ДеревоЗначений. Важное условие: содержимое коллекции тоже должно состоять из сериализуемых типов. Если вложить в структуру, например, элемент управления формы, передача завершится ошибкой, причём текст ошибки не всегда укажет на конкретный проблемный элемент.

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

Передача ссылок и работа с прикладными объектами

Ссылки на объекты базы данных — СправочникСсылка, ДокументСсылка, ПеречислениеСсылка, ПланСчетовСсылка и другие — передаются свободно. Фактически передаётся только идентификатор, а на сервере по ссылке уже можно получить объект через метод ПолучитьОбъект() и изменить его.

Ключевое различие, которое нужно понимать: сама ссылка передаётся, а объект — нет. Типы вида ДокументОбъект, СправочникОбъект, РегистрСведенийНаборЗаписей существуют только в контексте сервера (или толстого клиента в файловом режиме) и не сериализуются. Попытка вернуть такой объект с сервера на клиент или передать его параметром приведёт к ошибке.

Правильный шаблон выглядит так: клиент передаёт на сервер ссылку и набор изменяемых реквизитов в структуре, серверная процедура получает объект, заполняет его, записывает и при необходимости возвращает примитивный результат — например, признак успеха или номер проведённого документа.

bsl
&НаСервере
Функция ЗаписатьДокумент(ДокументСсылка, ДанныеЗаполнения)
	ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
	ЗаполнитьЗначенияСвойств(ДокументОбъект, ДанныеЗаполнения);
	ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
	Возврат ДокументОбъект.Номер;
КонецФункции

Передача больших данных через временное хранилище

Когда объём данных велик — файл, картинка, большая таблица — передавать его параметром неэффективно. Для этого предназначено временное хранилище: данные помещаются в хранилище функцией ПоместитьВоВременноеХранилище(), а между клиентом и сервером передаётся только адрес — строка вида GUID.

Типичный сценарий загрузки файла: на клиенте файл помещается в хранилище (например, через НачатьПомещениеФайла), адрес передаётся в серверную процедуру, там вызывается ПолучитьИзВременногоХранилища(Адрес), и сервер получает двоичные данные для обработки. Аналогично работает обратное направление: сервер формирует табличный документ или файл, помещает в хранилище, клиент забирает по адресу.

Время жизни хранилища ограничено: если адрес создан без привязки к форме, данные удаляются при очистке сеанса. Для надёжности передавайте вторым параметром УникальныйИдентификатор формы — тогда данные живут, пока открыта форма. Не забывайте удалять данные через УдалитьИзВременногоХранилища(), если они больше не нужны: накопление мусора в хранилище увеличивает потребление памяти сервера.

Передача файла с клиента на сервер
  1. 1
    На клиенте вызовите НачатьПомещениеФайла и получите адрес временного хранилища.
  2. 2
    Передайте адрес параметром в серверную процедуру.
  3. 3
    На сервере получите двоичные данные через ПолучитьИзВременногоХранилища(Адрес).
  4. 4
    Обработайте данные (запишите в базу, распарсите, сохраните в реквизит).
  5. 5
    После обработки вызовите УдалитьИзВременногоХранилища, если данные не нужны.

Что передавать нельзя и какими ошибками это грозит

Категорически не сериализуются: элементы форм и сами формы, объекты прикладных типов (ДокументОбъект, СправочникОбъект, ОбработкаОбъект), Запрос с установленными параметрами, ПостроительЗапроса, СхемаКомпоновкиДанных в ряде контекстов, COM-объекты, OLE-объекты, объекты ЧтениеXML/ЗаписьXML, ТекстовыйДокумент в некоторых режимах, Картинка (передавайте двоичные данные вместо неё).

Типичное проявление ошибки — сообщение «Ошибка передачи данных между клиентом и сервером» либо «Ошибка преобразования данных XDTO». Причина почти всегда одна: в параметрах или возвращаемом значении затесался несериализуемый тип, часто глубоко вложенный в структуру или таблицу значений.

Отдельный случай — реквизиты формы. Реквизит формы типа ТаблицаЗначений на клиенте представлен как ДанныеФормыКоллекция, и передавать его напрямую в серверную процедуру нельзя. Используйте методы РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы() в контексте &НаСервере в модуле формы, где эти методы доступны.

Типичные ошибки
01
Передача ДокументОбъект вместо ссылки — ошибка сериализации; передавайте ссылку и получайте объект на сервере.
02
Передача ДанныеФормыКоллекция в серверную процедуру общего модуля — используйте РеквизитФормыВЗначение в модуле формы.
03
Вложение элемента формы или COM-объекта в структуру параметров — передача падает целиком, даже если остальные данные корректны.
04
Передача таблицы значений на десятки тысяч строк параметром — рост трафика и паузы; переносите формирование на сервер или используйте хранилище.
05
Отсутствие очистки временного хранилища — утечка памяти на сервере при массовых операциях.

Как организовать вызовы, чтобы минимизировать передачу данных

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

Используйте директивы компиляции осознанно. Процедуры &НаСервереБезКонтекста выполняются быстрее и не тянут за собой данные формы, но не имеют доступа к реквизитам формы. &НаСервере в модуле формы сериализует данные формы туда и обратно — для тяжёлых форм это заметные накладные расходы, поэтому массовую обработку выносите в серверные общие модули.

Для длительных операций в современных версиях платформы применяйте фоновые задания (ДлительныеОперации из БСП или прямой вызов ФоновыеЗадания.Выполнить): клиент передаёт параметры, задание выполняется асинхронно, результат забирается из временного хранилища по готовности. Это снимает проблему тайм-аутов и блокировки интерфейса.

Маршрут решения

Как выбрать способ передачи

Нужно передать несколько простых значений или небольшой набор данныхПередавайте примитивы и структуру параметрами серверной процедуры
Нужно изменить объект базы данныхПередавайте ссылку и структуру реквизитов, объект создавайте на сервере
Передаётся файл или большой массив данныхИспользуйте временное хранилище и передавайте только адрес
Операция длительная и блокирует интерфейсЗапускайте фоновое задание, результат забирайте из хранилища
Нужно передать таблицу из реквизита формыВ модуле формы преобразуйте через РеквизитФормыВЗначение

Проверка результата и диагностика проблем передачи

Если вызов падает с ошибкой сериализации, локализуйте проблему методом исключения: передавайте параметры по одному или временно заменяйте подозрительные значения на примитивы. Часто виновник — одна колонка таблицы значений или одно поле структуры, заполненное «экзотическим» типом.

Полезный приём — пройтись по структуре или коллекции в отладчике на клиенте перед вызовом и проверить тип каждого значения через ТипЗнч(). Всё, что не входит в «белый список» сериализуемых типов, нужно заменить: картинку — на двоичные данные, объект — на ссылку, данные формы — на таблицу значений.

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

Контрольные точки

Как проверить корректность обмена

Вызов серверной процедуры из тонкого клиента
Норма

Выполняется без ошибок, результат возвращается

Тревожный признак

Ошибка передачи данных или преобразования XDTO

Состав передаваемой структуры
Норма

Только примитивы, ссылки, коллекции из них

Тревожный признак

Есть объекты, элементы формы, COM-объекты

Объём передаваемых данных
Норма

Килобайты — параметры; мегабайты — через хранилище

Тревожный признак

Большие таблицы гоняются параметрами в цикле

Временное хранилище после операции
Норма

Данные удалены после использования

Тревожный признак

Хранилище накапливает данные за сеанс

Частые вопросы

Можно ли передать таблицу значений с клиента на сервер?

Да, ТаблицаЗначений сериализуется и передаётся в обе стороны. Ограничение касается только реквизита формы: его тип на клиенте — ДанныеФормыКоллекция, и сначала нужно преобразовать его в таблицу методом РеквизитФормыВЗначение в серверном контексте модуля формы.

Почему возникает ошибка «Недопустимое значение» при серверном вызове?

Почти всегда причина в несериализуемом типе среди параметров или в возвращаемом значении: объект прикладного типа, элемент формы, COM-объект. Проверьте вложенные структуры и колонки таблиц — проблемное значение часто спрятано глубоко внутри коллекции.

Как передать картинку с клиента на сервер?

Тип Картинка напрямую не передаётся. Получите двоичные данные файла (например, через помещение файла во временное хранилище), передайте адрес или сами двоичные данные, а на сервере при необходимости создайте из них объект Картинка.

Чем отличается &НаСервере от &НаСервереБезКонтекста с точки зрения передачи данных?

При вызове &НаСервере в модуле формы данные формы сериализуются и передаются на сервер вместе с вызовом, что увеличивает трафик. &НаСервереБезКонтекста передаёт только явные параметры — такие вызовы легче, но не имеют доступа к реквизитам формы.

Можно ли вернуть с сервера на клиент результат запроса?

Сам объект Запрос или РезультатЗапроса не передаётся. Выгрузите результат в таблицу значений методом Выгрузить() и возвращайте её — либо, если данных много, поместите таблицу во временное хранилище и верните адрес.

Сколько данных можно безопасно передавать за один вызов?

Жёсткого лимита платформа не задаёт, но практическое правило: параметры — для небольших структур, всё объёмное — через временное хранилище. Большие пакеты увеличивают время сериализации и сетевую задержку, а при нестабильном канале повышают риск обрыва вызова.

Итог

Что важно запомнить

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