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

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

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

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

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

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

Как платформа передаёт данные между клиентом и сервером

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

Ключевое следствие: передаются не сами объекты, а их «копии по значению». Изменение полученной структуры на клиенте никак не затрагивает данные на сервере, и наоборот. Если нужно синхронизировать изменения, их придётся передавать обратно явным вызовом.

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

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

Базовый набор сериализуемых типов покрывает большинство практических задач. К нему относятся примитивные типы: строка, число, булево, дата, а также значение Неопределено и NULL. Они передаются свободно в обе стороны и в любых вложенных структурах.

Универсальные коллекции тоже полностью сериализуемы: массив, структура, соответствие, список значений, таблица значений, дерево значений. При этом вложенность может быть любой — структура внутри массива внутри соответствия передастся корректно, если все элементы внутри сериализуемы.

Из прикладных типов передаются ссылки на объекты базы данных (СправочникСсылка, ДокументСсылка, ПланСчетовСсылка и другие), значения перечислений, точки маршрута бизнес-процессов, уникальный идентификатор, двоичные данные, картинка, хранилище значения и системные перечисления вроде ВидДвиженияНакопления.

Важный нюанс: ссылка передаётся именно как ссылка — лёгкий идентификатор. Реквизиты объекта с ней не едут. Чтобы получить на клиенте наименование или код, либо обратитесь к ним через точку (платформа выполнит неявный серверный вызов), либо заранее соберите нужные поля в структуру на сервере — второй вариант предсказуемее по производительности.

Примитивы и коллекцииПередаются

Строка, число, дата, булево, массив, структура, соответствие, таблица значений

Ссылки и перечисленияПередаются

СправочникСсылка, ДокументСсылка, значения перечислений, УникальныйИдентификатор

Объекты данныхНе передаются

СправочникОбъект, ДокументОбъект, наборы записей — только на сервере

Запросы и типыНе передаются

Запрос, РезультатЗапроса, ПостроительЗапроса, значения типа Тип

Что нельзя передавать и как обойти ограничение

Объектные типы — СправочникОбъект, ДокументОбъект, ПланВидовРасчетаОбъект и подобные — живут только на сервере. Они связаны с механизмами транзакций, блокировок и записи в базу, поэтому сериализации не подлежат. Если нужно передать данные объекта на клиент, сформируйте на сервере структуру с нужными реквизитами.

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

Значения типа Тип и описания типов тоже не передаются. Если клиенту нужно знать тип значения, передайте имя типа строкой, а на клиенте при необходимости сопоставьте его с допустимыми вариантами.

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

bsl
&НаСервере
Функция ПолучитьДанныеДокумента(ДокументСсылка)
    Результат = Новый Структура;
    Запрос = Новый Запрос("ВЫБРАТЬ Номер, Дата, Контрагент, СуммаДокумента ИЗ Документ.РеализацияТоваровУслуг ГДЕ Ссылка = &Ссылка");
    Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Результат.Вставить("Номер", Выборка.Номер);
        Результат.Вставить("Дата", Выборка.Дата);
        Результат.Вставить("Контрагент", Выборка.Контрагент);
        Результат.Вставить("Сумма", Выборка.СуммаДокумента);
    КонецЕсли;
    Возврат Результат;
КонецФункции

Временное хранилище для больших данных

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

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

У временного хранилища есть время жизни. Если адрес создан с указанием уникального идентификатора формы, данные живут, пока открыта форма. Без привязки к форме хранилище очищается по внутренним правилам платформы, и обращение по устаревшему адресу вернёт Неопределено. Поэтому для файлов, которые пользователь может запросить позже, привязка к форме обязательна.

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

Особенности управляемых форм

Реквизиты формы сами по себе являются механизмом передачи данных между клиентом и сервером. При открытии формы сериализуются реквизиты, доступные на клиенте; при серверных вызовах из формы часть контекста передаётся автоматически. Поэтому правила сериализуемости распространяются и на типы реквизитов формы.

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

Директивы компиляции &НаСервере, &НаКлиенте, &НаСервереБезКонтекста определяют, где выполняется код и какой контекст передаётся. Вызов процедуры «без контекста» дешевле, потому что данные формы не сериализуются туда-обратно, — но тогда все нужные значения придётся передать параметрами явно.

Производительность и типичные ошибки

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

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

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

Типичные ошибки при передаче данных
01
Передача результата запроса вместо таблицы значений — ошибка сериализации, нужно вызвать Выгрузить()
02
Обращение к реквизитам ссылки через точку в цикле на клиенте — сотни скрытых серверных вызовов и зависание формы
03
Возврат всей таблицы значений, когда нужны только итоги — лишний трафик и медленная работа на слабых каналах
04
Использование адреса временного хранилища без привязки к форме — данные пропадают до момента обращения
05
Попытка передать СправочникОбъект на клиент — объекты не сериализуются, передавайте структуру с реквизитами

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

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

Для контроля объёма передаваемых данных полезен технологический журнал с событием CALL и его свойствами — он показывает фактические вызовы между клиентом и сервером. На тонком клиенте по локальной сети проблема может быть незаметна, поэтому тестируйте web-клиент или эмуляцию медленного соединения.

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

Как проверить результат

Количество серверных вызовов при открытии формы
Норма

Один-два вызова

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

Десятки вызовов, форма открывается с задержкой

Типы возвращаемых значений
Норма

Структуры, таблицы значений, примитивы

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

Результат запроса, объект, выборка — ошибка передачи

Работа на медленном канале
Норма

Форма отзывчива

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

Заметные паузы при каждом действии

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

Адрес привязан к УникальныйИдентификатор формы

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

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

Итог

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

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

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

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

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

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

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

Как передать на клиент данные документа, если ДокументОбъект не сериализуется?

Сформируйте на сервере структуру с нужными реквизитами шапки и массив или таблицу значений для табличных частей. Альтернатива — открыть форму документа: платформа сама передаст его данные через механизм реквизитов формы.

Что быстрее: вернуть таблицу значений или адрес временного хранилища?

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

Передаётся ли картинка с сервера на клиент?

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

Можно ли вызвать клиентскую процедуру с сервера напрямую?

Нет, сервер не может инициировать вызов клиента в обычном сеансе. Обратная связь реализуется через возвращаемые значения серверных вызовов, а для асинхронных сценариев — через длительные операции и механизм оповещений на клиенте, который периодически проверяет состояние задания.