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