Как правильно передать массив или список значений с клиента на сервер в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ причины первой ошибки: Недопустимый тип данных

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

Разрешенные для передачи типы (сериализуемые):

Запрещенные типы:

Если вы попытаетесь передать в параметре серверной процедуры ТаблицаЗначений, система выдаст ошибку «Значение недопустимого типа». Для передачи таких данных следует использовать временное хранилище.

Анализ причины второй ошибки: Значение не является значением объектного типа

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

Рассмотрим пример кода, который часто приводит к ошибке:


&НаКлиенте
Процедура КомандаВыполнить(Команда)
    ПеременнаяМассив; // Здесь тип Неопределено
    ОбработатьНаСервере(ПеременнаяМассив);
КонецПроцедуры

&НаСервере
Процедура ОбработатьНаСервере(МассивПараметр)
    МассивПараметр.Добавить(1); // ОШИБКА: МассивПараметр = Неопределено
КонецПроцедуры

Шаг 1: Правильная инициализация и передача массива

Рассмотрим верный способ передачи массива. Чтобы объект «ожил», его необходимо создать с помощью конструктора Новый. Посмотрим на рабочий пример:


&НаКлиенте
Процедура ВыполнитьПередачу()
    // 1. Создаем объект на клиенте
    МойМассив = Новый Массив;
    МойМассив.Добавить("Элемент 1");
    
    // 2. Передаем его в серверную процедуру
    ОбработатьДанныеНаСервере(МойМассив);
    
    // 3. После возврата с сервера массив будет содержать новые данные
    Сообщить("Количество элементов: " + МойМассив.Количество());
КонецПроцедуры

&НаСервере
Процедура ОбработатьДанныеНаСервере(ПереданныйМассив)
    // Массив передается по ссылке, изменения вернутся на клиент
    ПереданныйМассив.Добавить("Элемент, добавленный на сервере");
КонецПроцедуры

Шаг 2: Использование функций для получения данных

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


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

&НаКлиенте
Процедура ОсновноеДействие()
    // ОШИБКА: Просто написать ИмяФункции() недостаточно, 
    // результат нужно присвоить переменной
    РезультатСписка = СформироватьСписок(); 
    
    // Теперь передаем полученную переменную
    ВыполнитьНаСервере(РезультатСписка);
КонецПроцедуры

&НаСервере
Процедура ВыполнитьНаСервере(СписокДляОбработки)
    СписокДляОбработки.Добавить("Добавлено на сервере");
КонецПроцедуры

Шаг 3: Передача сложных типов через временное хранилище

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

Разберем алгоритм работы с временным хранилищем:

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

Пример реализации:


&НаКлиенте
Процедура ПередатьТаблицуНаСервер()
    // Допустим, у нас есть таблица значений на сервере, которую мы хотим обработать
    АдресДанных = ПодготовитьДанныеНаСервере();
    
    // Вызываем другую серверную процедуру, передавая адрес строки
    ОбработатьДанныеПоАдресу(АдресДанных);
КонецПроцедуры

&НаСервере
Функция ПодготовитьДанныеНаСервере()
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Имя");
    // Заполняем ТЗ...
    
    // Помещаем во временное хранилище
    Возврат ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
КонецФункции

&НаСервере
Процедура ОбработатьДанныеПоАдресу(Адрес)
    // Извлекаем данные
    Таблица = ПолучитьИзВременногоХранилища(Адрес);
    // Работаем с таблицей...
КонецПроцедуры

Важные рекомендации при работе на сервере

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

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

← На главную