Как сформировать отчет через Web-сервис в 1С и решить проблему отсутствующих методов

Программист Управленческий учет IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: Контекст исполнения и препроцессор

Рассмотрим ситуацию: у нас есть Web-сервис, который должен принять параметры (код пользователя, имя отчета, настройки), сформировать отчет и вернуть путь к файлу или сами данные. Типичная ошибка заключается в попытке вызвать стандартные процедуры инициализации отчета, такие как УстановитьНачальныеНастройки(), непосредственно из модуля Web-сервиса.

Проанализируем причину сбоя. В конфигурациях, использующих "Универсальный отчет" (например, УПП 1.3, УТП 1.2 или УТ 10.3), многие процедуры в модулях объектов отчетов обернуты в инструкции препроцессора:


#Если Клиент Тогда
Процедура УстановитьНачальныеНастройки() Экспорт
    // Код инициализации построителя или настроек
КонецПроцедуры
#КонецЕсли

Когда мы вызываем эту функцию через Web-сервис, код выполняется на сервере (в контексте Server или External Connection). Для сервера методов, находящихся внутри блока #Если Клиент, просто не существует. Именно поэтому система выдает ошибку, несмотря на то что в конфигураторе мы видим эту процедуру как экспортную.

Решение 1: Адаптация модуля отчета под серверный вызов

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

Рассмотрим правильный алгоритм адаптации:

  1. Проанализируем содержимое процедуры в модуле отчета. Если она только инициализирует параметры (даты, отборы), вынесем эту логику в отдельную процедуру или разрешим её выполнение на сервере, заменив #Если Клиент Тогда на #Если Клиент Или Сервер Или ВнешнееСоединение Тогда.
  2. Проверим все связанные общие модули. Если отчет использует функции из модулей с галочкой только "Клиент", их придется перенести в серверные модули.

Решение 2: Программное формирование через СКД (Систему компоновки данных)

Если отчет построен на базе СКД, мы можем полностью обойтись без вызова клиентских методов модуля объекта. Это наиболее надежный и современный способ для работы через Web-сервисы. Разберем этот процесс по шагам:

Во-первых, нам необходимо инициализировать схему и настройки без обращения к экранным формам. Посмотрим на пример кода, который можно разместить непосредственно в функции Web-сервиса или в серверном общем модуле:


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

Этот подход гарантирует работу кода в любом контексте, так как объекты ПроцессорКомпоновкиДанных и СхемаКомпоновкиДанных являются серверными.

Решение 3: Восстановление сохраненных настроек пользователя

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

Проанализируем, как это реализовано в БСП (Библиотеке стандартных подсистем). Вместо обращения к УниверсальныеМеханизмы.ПолучитьНастройку(), которые могут дергать клиентский код, лучше использовать прямое чтение из ХранилищеОбщихНастроек или ХранилищеВариантовОтчетов.


// Пример получения настроек СКД из хранилища
КлючОбъекта = "ОтчетОбъект." + ИмяОтчета;
НастройкиПользователя = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, ИмяНастройки, , ИмяПользователя);

Если НастройкиПользователя <> Неопределено Тогда
    ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиПользователя);
КонецЕсли;

Важные нюансы передачи данных через Web-сервис

Когда мы формируем отчет на сервере, возникает вопрос: как передать результат клиенту? В исходном сообщении автор возвращает ИмяВременногоФайла. Рассмотрим, почему это плохое решение для Web-сервиса:

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

Правильный подход: Возвращать двоичные данные файла. Посмотрим, как это реализовать:


// Внутри функции Web-сервиса
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

ДанныеФайла = Новый ДвоичныеДанные(ИмяФайла);
// Удаляем временный файл после чтения в память
УдалитьФайлы(ИмяФайла);

// Возвращаем данные (тип возвращаемого значения в WS должен быть base64Binary)
Возврат ДанныеФайла;

Итоги и рекомендации

Подведем итоги нашего разбора. Для успешного формирования отчетов через Web-соединение необходимо:

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

← На главную