Как передать данные выбранной строки из таблицы формы на сервер для создания документа?

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

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

Выясняем причину ошибки передачи параметров

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

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

Решение №1: Использование идентификатора строки (оптимальный способ)

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

Разберем по шагам, как это выглядит в коде:


&НаКлиенте
Процедура СохранитьЗаказ(Команда)
    // Получаем доступ к текущей строке таблицы
    Заказ = Элементы.ЗаказыНаИМ.ТекущиеДанные;
    
    Если Заказ <> Неопределено Тогда
        // Вместо передачи всего объекта, получаем его внутренний идентификатор
        НомерСтроки = Заказ.ПолучитьИдентификатор();
        
        // Вызываем серверную функцию, передавая только число (ID)
        Если СохранитьЗаказНаСервере(НомерСтроки) Тогда
            Сообщить("Заказ успешно создан!");
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СохранитьЗаказНаСервере(ИдентификаторСтроки)
    // На сервере у нас есть прямой доступ к реквизиту формы (Таблице Значений)
    // Ищем строку по переданному ID
    Заказ = ЗаказыИМ.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    Если Заказ <> Неопределено Тогда
        Попытка
            НовыйЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
            НовыйЗаказ.Дата = ТекущаяДата();
            НовыйЗаказ.Номер = Заказ.НомерЗаказа;
            
            // Заполнение табличной части документа из вложенной коллекции
            Для Каждого Позиция Из Заказ.ПозицииЗаказа Цикл
                НоваяСтрока = НовыйЗаказ.Товары.Добавить();
                НоваяСтрока.Номенклатура = Позиция.Товар;
                НоваяСтрока.Количество = Позиция.Количество;
            КонецЦикла;
            
            НовыйЗаказ.Записать(РежимЗаписиДокумента.Запись);
            Возврат Истина;
        Исключение
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
            Возврат Ложь;
        КонецПопытки;
    КонецЕсли;
    
    Возврат Ложь;
КонецФункции

В данном примере ЗаказыИМ — это реквизит формы с типом ТаблицаЗначений. Метод НайтиПоИдентификатору позволяет мгновенно получить доступ к нужной строке на сервере, не передавая лишние данные по сети.

Решение №2: Массив структур (для сложных иерархических данных)

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

Структуры (Структура) и Массивы (Массив) — это типы данных, которые 1С умеет сериализовать и передавать между клиентом и сервером. Если у нас есть "ТЗ внутри ТЗ" (заказ и его товары), мы можем упаковать их следующим образом:

  1. Создаем структуру для основных реквизитов заказа (Номер, Дата, Контрагент).
  2. Создаем массив для хранения строк товаров.
  3. Каждую строку товара превращаем в отдельную структуру и добавляем в массив.
  4. Вкладываем массив в основную структуру заказа.

Посмотрим на пример реализации такого преобразования:


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

Такой объект "Структура" легко передается в любой серверный метод без ошибок.

Решение №3: Временное хранилище (для больших объемов данных)

Если данных очень много (например, XML содержит сотни заказов по тысячи строк в каждом), передача их через параметры может замедлить работу интерфейса. В таких случаях рекомендуется использовать ПоместитьВоВременноеХранилище.

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

Рекомендации по оптимизации записи документов

При программном создании документов из внешних источников (XML, JSON, API интернет-магазина) следует придерживаться нескольких правил, чтобы система работала стабильно:

Подводя итог, отметим, что ключ к успеху в управляемом приложении — четкое понимание того, какие типы данных являются "транспортабельными". Использование ПолучитьИдентификатор() — самый быстрый способ для интерактивной работы, а связка Массив + Структура — самый гибкий способ для передачи произвольных данных.

← На главную