Архитектура современных приложений на платформе 1С:Предприятие 8 построена на жестком разделении клиентского и серверного пространства. Для разработчика критически важно понимать, какие именно объекты и структуры данных могут пересекать эту границу, а какие остаются исключительно в памяти сервера. Непонимание механизмов сериализации и контекстов выполнения часто приводит к трудноуловимым ошибкам или, что хуже, к падению производительности всей системы при работе множества пользователей.

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

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

Примитивные типы и простые значения

Фундаментом любого обмена данными служат простейшие типы. Числа, строки, даты и булевы значения передаются без каких-либо ограничений и накладных расходов. Платформа 1С эффективно кодирует эти значения, обеспечивая минимальный размер пакета данных.

Вы можете смело возвращать из серверного кода результат вычислений или текстовые сообщения. Например, при расчете сложной себестоимости сервер может вернуть итоговое Число или строку с описанием ошибки. Эти типы не хранят состояния, зависящего от контекста, поэтому их сериализация тривиальна.

Однако стоит быть внимательным с типом Неопределено (Undefined). Хотя он успешно передается, его использование для обозначения ошибок часто является дурным тоном. Лучше использовать явные структуры или возвращать специальные коды. Также

💡

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

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

Ссылки на объекты базы данных

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

Когда вы возвращаете ссылку на Документ.РеализацияТоваровУслуг, клиент получает "указатель". Для того чтобы прочитать реквизиты этого документа (например, дату или контрагента), клиентскому приложению придется выполнить дополнительный запрос к серверу. Это поведение называется "ленивой загрузкой" (lazy loading).

  • 🔗 Ссылка весит очень мало и передается мгновенно, независимо от размера объекта.
  • 📦 Сам объект данных (табличная часть, реквизиты) на клиент не пересылается автоматически.
  • ⚡ Попытка обратиться к реквизиту переданной ссылки вызовет скрытый сетевой запрос к серверу.

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

⚠️ Внимание: Не передавайте ссылки на объекты, удаленные помечением на удаление, если на клиенте не предусмотрена обработка такой ситуации. Попытка работы с битой ссылкой может вызвать исключение.
📊 Как вы обычно получаете данные для формы?
Загружаю весь объект целиком
Выбираю только нужные поля
Использую ссылки и читаю реквизиты по мере нужды
Не задумывался об этом

Структуры и Соответствия

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

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

Тип Соответствие ведет себя аналогично, но позволяет использовать в качестве ключей не только строки, но и другие типы (например, ссылки). Однако при передаче Соответствия на клиент ключи-ссылки также передаются как ссылки, что возвращает нас к проблеме ленивой загрузки. Если ключи вам не важны или могут быть строками, Structure предпочтительнее из-за читаемости кода.


// Пример возврата структуры с сервера

Функция ПолучитьДанныеКлиенту() Экспорт

Результат = Новый Структура;

Результат.Вставить("Сумма", 1000);

Результат.Вставить("Статус", "Успешно");

Возврат Результат;

КонецФункции

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

Таблицы значений и списки значений

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

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

Параметр Таблица Значений Массив Структур Дерево Значений
Производительность Высокая Средняя Низкая (при больших объемах)
Иерархия Нет (плоская) Нет (плоская) Поддерживается
Сортировка на клиенте Поддерживается Требует кода Поддерживается
Фильтрация на клиенте Встроенная Требует кода Встроенная

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

Секрет оптимизации Таблицы Значений

Если вы передаете таблицу с большим количеством колонок, но клиенту нужны только 3 из них, создайте новую таблицу на сервере и скопируйте туда только нужные колонки. Это уменьшит трафик в разы.

Помните, что колонки типа ХранилищеЗначения внутри Таблицы Значений также сериализуются. Это мощный инструмент, позволяющий передавать в одной ячейке таблицы целые вложенные объекты, но злоупотребление этим может усложнить отладку.

Массивы и их ограничения

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

Главная проблема массивов — отсутствие типизации. Клиентский код не знает заранее, что лежит в ячейке массива, пока не проверит тип значения. Это делает код более громоздким и подверженным ошибкам времени выполнения. В отличие от Таблицы Значений, где типы колонок фиксированы.

Массивы удобно использовать для передачи списка идентификаторов (например, массив ссылок) или простых списков строк. Если же вы планируете отображать данные в табличном документе или списке формы, конвертация массива в Таблицу Значений на клиенте станет лишней операцией, потребляющей ресурсы процессора.

⚠️ Внимание: Избегайте передачи массивов, содержащих объекты бизнес-логики (например, объекты документов в режиме предприятия). Передавайте только ссылки или выгруженные данные.

Хранилище значения и двоичные данные

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

Часто возникает необходимость передать файлы или картинки. Для этого используются типы ДвоичныеДанные, Картинка или Макет. Они полностью поддерживают передачу. Однако размер таких объектов может быть значительным. Передача больших изображений или файлов в 10-20 Мб через тонкий клиент может привести к зависанию интерфейса.

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

☑️ Проверка передаваемых данных

Выполнено: 0 / 4

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

Что нельзя передать: Несериализуемые объекты

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

К таким объектам относятся Запрос, КонструкторЗапроса, ПостроительЗапроса. Логика работы запроса выполняется на сервере СУБД, и сам объект запроса не имеет смысла на клиенте. Клиент может получить только РезультатЗапроса или Выборку (которая при передаче превращается в Таблицу Значений).

Также нельзя передавать объекты файловой системы сервера, соединения с внешними базами данных (ODBC, ADO) и потоки ввода-вывода, открытые на сервере. Эти ресурсы существуют только в процессе сервера 1С и не могут быть перенесены в процесс клиента.

Объекты метаданных в режиме предприятия также ведут себя специфично. Ссылки на метаданные (например, СправочникСсылка.Номенклатура) передаются, но объекты описания метаданных (ОбъектМетаданных) — нет.

💡

Золотое правило: Если объект предназначен для выполнения действия на сервере (Запрос, Коннектор), его нельзя передать. Если объект предназначен для хранения данных (Структура, Таблица), его передать можно.

Частые вопросы (FAQ)

Можно ли передать объект "Запрос" на клиент для выполнения там?

Нет, объект типа Запрос не поддерживает сериализацию. Логика выполнения запроса привязана к серверу 1С и серверу СУБД. Вы можете передать только текст запроса (строку) и параметры, но выполнять его придется на сервере через специальную процедуру.

Что произойдет, если передать ссылку на удаленный объект?

Ссылка передастся успешно, так как это просто набор байт (UUID). Однако при первой попытке клиента прочитать свойство этой ссылки или открыть объект в форме, система выдаст ошибку "Объект не найден" или "Объект удален".

Как передать на клиент данные из внешнего источника (например, из HTTP-сервиса)?

Данные, полученные на сервере (например, в формате JSON или XML), нужно преобразовать в сериализуемые типы 1С: Структура, Массив или ТаблицаЗначений. После этого эта структура может быть спокойно возвращена клиенту.

Влияет ли режим совместимости на передачу данных?

Да, в очень старых версиях платформы (до 8.2) список сериализуемых типов был уже. В современных версиях (8.3.20+) различия минимальны, но стоит проверять документацию для специфических новых типов, таких как UUID или УникальныйИдентификатор в старых конфигурациях.

Можно ли передать функцию или процедуру как параметр?

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