Как передать Табличный документ через веб-сервис в 1С без ошибок?

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

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

В этой статье мы подробно разберем, почему возникает данная проблема, проанализируем внутренние механизмы сериализации платформы 1С и рассмотрим три эффективных способа корректной и быстрой передачи табличного документа через веб-сервис.

Выясняем причину: почему падает веб-сервис при прямой передаче документа?

При попытке передать объект типа ТабличныйДокумент напрямую, платформа 1С пытается выполнить его неявную (автоматическую) сериализацию в формат XML, сопоставляя тип со встроенными типами XDTO. В стандартах 1С тип, соответствующий табличному документу, находится в пространстве имен http://v8.1c.ru/8.2/data/spreadsheet и называется SpreadsheetDocument.

Однако автоматическая сериализация часто дает сбой, если в настройках веб-сервиса некорректно импортирован соответствующий пакет схем или нарушена структура сопоставления типов данных в веб-сервисе. В результате сбоя сериализатора платформа завершает выполнение функции без отправки сформированного тела SOAP-ответа. Клиент получает пустой XML, что и вызывает ошибку "Обязательное возвращаемое значение не задано", так как схема веб-сервиса строго требует наличия возвращаемого элемента.

Давайте пошагово рассмотрим способы решения этой проблемы.

Решение 1. Явная сериализация через СериализаторXDTO (передача SpreadsheetDocument)

Для того чтобы обойти ограничение неявного приведения типов, мы можем принудительно сериализовать наш табличный документ в объект XDTO на стороне веб-сервиса, а на стороне клиента выполнить обратную операцию (десериализацию).

Рассмотрим пример кода функции веб-сервиса на стороне сервера:


Функция GetApprovalSheet_BusinessProcess(ID_BusinessProcess)
    
    // Получаем ссылку на бизнес-процесс по переданному GUID
    БП = БизнесПроцессы.Согласование.ПолучитьСсылку(Новый УникальныйИдентификатор(ID_BusinessProcess));
    
    // Формируем табличный документ с помощью экспортного метода
    ТабличныйДокумент = БизнесПроцессы.Согласование.ЛистСогласования(ОбщегоНазначенияСервер.ЗначениеВМассиве(БП), Новый СписокЗначений);
    
    // Принудительно сериализуем объект 1С в тип XDTO
    ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(ТабличныйДокумент);
    
    Возврат ОбъектXDTO;
    
КонецФункции

В настройках веб-сервиса для возвращаемого значения данной операции необходимо указать тип SpreadsheetDocument из пространства имен http://v8.1c.ru/8.2/data/spreadsheet.

Теперь посмотрим, как обработать полученный ответ на стороне клиента-получателя (в другой базе 1С):


// Создаем прокси для обращения к веб-сервису
WSПрокси = ИнтеграцияС1СДокументооборот.СоздатьProxy();

// Вызываем метод веб-сервиса
ОтветXDTO = WSПрокси.GetApprovalSheet_BusinessProcess(ГУИД_БП);

Если ОтветXDTO <> Неопределено Тогда
    // Читаем объект XDTO обратно в тип ТабличныйДокумент
    ТабличныйДокумент = СериализаторXDTO.ПрочитатьXDTO(ОтветXDTO);
    
    // Отображаем документ пользователю или отправляем на печать
    ТабличныйДокумент.Показать("Лист согласования");
КонецЕсли;

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

Решение 2. Передача через ХранилищеЗначения (Оптимально для сценария "1С-в-1С")

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

При использовании этого подхода платформа автоматически сжимает табличный документ алгоритмом ZIP/Deflate и преобразует его в бинарную строку формата Base64. Объем передаваемых данных сокращается в 10–20 раз по сравнению со стандартным XML-описанием XDTO.

Давайте реализуем этот подход. Настроим тип возвращаемого значения операции веб-сервиса как ValueStorage (пространство имен http://v8.1c.ru/8.1/data/core).

Код функции веб-сервиса на стороне сервера:


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

Код получения и распаковки табличного документа на клиенте:


WSПрокси = ИнтеграцияС1СДокументооборот.СоздатьProxy();

// Получаем объект ХранилищеЗначения через веб-сервис
ОтветХранилище = WSПрокси.GetApprovalSheet_ValueStorage(ГУИД_БП);

Если ТипЗнч(ОтветХранилище) = Тип("ХранилищеЗначения") Тогда
    // Извлекаем наш исходный табличный документ
    ТабличныйДокумент = ОтветХранилище.Получить();
    ТабличныйДокумент.Показать("Лист согласования");
КонецЕсли;

Решение 3. Универсальная передача в двоичном формате (для внешних систем)

Что делать, если принимающей стороной выступает мобильное приложение, корпоративный портал или внешняя ERP-система не на платформе 1С? Сторонние приложения не смогут распознать структуру пакетов 1С SpreadsheetDocument или ValueStorage.

В таких случаях рекомендуется сохранять табличный документ на сервере в общепринятый открытый формат (например, PDF или XLSX), считывать его в двоичные данные и возвращать в формате base64Binary (пространство имен http://www.w3.org/2001/XMLSchema).

Проанализируем пример кода на сервере:


Функция GetApprovalSheet_AsPDF(ID_BusinessProcess)
    
    БП = БизнесПроцессы.Согласование.ПолучитьСсылку(Новый УникальныйИдентификатор(ID_BusinessProcess));
    ТабличныйДокумент = БизнесПроцессы.Согласование.ЛистСогласования(ОбщегоНазначенияСервер.ЗначениеВМассиве(БП), Новый СписокЗначений);
    
    // Получаем имя временного файла на сервере
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
    
    // Записываем табличный документ в файл формата PDF
    ТабличныйДокумент.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.PDF);
    
    // Читаем файл в объект ДвоичныеДанные
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    // Удаляем временный файл с диска сервера после прочтения в память
    Попытка
        УдалитьФайлы(ИмяВременногоФайла);
    Исключение
        ЗаписьЖурналаРегистрации("Веб-сервисы", УровеньЖурналаРегистрации.Предупреждение, , , 
            "Не удалось удалить временный файл: " + ИмяВременногоФайла);
    КонецПопытки;
    
    Возврат ДвоичныеДанныеФайла;
    
КонецФункции

На стороне клиента (даже если это веб-сайт на PHP/Python или внешняя система) полученная Base64-строка легко декодируется в стандартный файл PDF, готовый для отображения пользователю на любом устройстве.

Сводная таблица решений

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

  1. Явная сериализация XDTO (SpreadsheetDocument): Идеально подходит для передачи оригинального документа со всей структурой ячеек "как есть". Минус — большой размер XML-пакета, высокая нагрузка на процессор.
  2. ХранилищеЗначения (ValueStorage): Лучший и самый быстрый вариант при обмене данными внутри инфраструктуры 1С. Трафик сжимается, передача происходит мгновенно, исходная структура сохраняется. Не подходит для внешних (не 1С) систем.
  3. Двоичные данные (base64Binary в PDF/XLSX): Универсальный промышленный стандарт. Минус — табличный документ перестает быть редактируемым объектом 1С на принимающей стороне, превращаясь в готовый к просмотру документ.

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

← На главную