Создание HTTP-сервисов для извлечения данных из 1С — это эффективный способ интеграции с внешними CRM, интернет-магазинами или мобильными приложениями. Однако при попытке сформировать стандартный отчет (например, ОСВ) программно, разработчики часто сталкиваются с тем, что результат получается пустым, хотя в интерфейсе программы отчет работает корректно. Рассмотрим подробнее, как правильно инициализировать систему компоновки данных (СКД), передать параметры и вернуть результат в нужном формате.
В типовых конфигурациях (таких как «Бухгалтерия предприятием», «Бухгалтерия для Казахстана» и другие на базе БСП) отчеты зачастую не являются простыми схемами СКД. Процесс их формирования сильно завязан на программный код в модулях объекта и общих модулях, который подготавливает данные, заполняет временные таблицы или управляет настройками в зависимости от учетной политики. Если мы просто создадим объект отчета и вызовем СкомпоноватьРезультат, мы пропустим всю предварительную логику инициализации параметров сеанса и специфических настроек.
Для начала разберем стандартный цикл работы с СКД, который подходит для простых (не типовых) отчетов или внешних схем. Нам необходимо выполнить последовательную инициализацию нескольких объектов платформы. Рассмотрим пример кода:
ОтчетОбъект = Отчеты.ВашОтчет.Создать();
СхемаСКД = ОтчетОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаСКД.НастройкиПоУмолчанию;
// Установка параметров данных
ЗначениеПараметра = Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
ЗначениеПараметра.Значение = ДатаНачала;
ЗначениеПараметра.Использование = Истина;
// Инициализация компоновщика макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки, ДанныеРасшифровки);
// Процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
// Вывод в табличный документ
Результат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
При выполнении этого кода внутри метода HTTP-сервиса следует учитывать важные моменты:
ТекущийПользователь), они могут быть не инициализированы. В этом случае используйте УстановитьПривилегированныйРежим(Истина).БухгалтерскиеОтчетыВызовСервера.СформироватьОтчет. Это позволит системе выполнить всю внутреннюю «кухню» подготовки данных.Разберем пример функции, которая обрабатывает входящий HTTP-запрос, формирует таблицу значений и возвращает её в формате JSON, HTML или Excel. Проанализируем структуру обработки параметров URL:
Функция ПолучениеОтчета(Запрос)
// Парсим параметры из URL (например, ?dateFrom=20230101&type=json)
ИмяОтчета = Запрос.ПараметрыURL["name"];
ТипОтвета = Запрос.ПараметрыЗапроса.Получить("type");
// Формируем таблицу данных (логика формирования СКД внутри)
ТаблицаРезультат = СформироватьТаблицуПоЗапросу(Запрос);
Если ТипОтвета = "html" Тогда
Возврат СформироватьОтветHTML(ТаблицаРезультат);
ИначеЕсли ТипОтвета = "xlsx" Тогда
Возврат СформироватьОтветExcel(ТаблицаРезультат);
КонецЕсли;
// По умолчанию отдаем JSON
Возврат СформироватьОтветJSON(ТаблицаРезультат);
КонецФункции
При выгрузке данных в JSON важно правильно сериализовать типы 1С. Выясним причину возможных сбоев: если в наименовании контрагента или номенклатуры встречается одиночный апостроф или другие спецсимволы, это может нарушить структуру ответа. Проанализируем безопасный метод обхода таблицы значений:
Функция СформироватьJSONизРезультата(Данные)
МассивСтруктур = Новый Массив;
Колонки = Данные.Колонки;
Для Каждого СтрокаТЗ Из Данные Цикл
Структ = Новый Структура;
Для Каждого Колонка Из Колонки Цикл
Значение = СтрокаТЗ[Колонка.Имя];
// Простые типы оставляем как есть, остальное приводим к строке
Если ТипЗнч(Значение) = Тип("Булево") ИЛИ ТипЗнч(Значение) = Тип("Число") Тогда
Структ.Вставить(Колонка.Имя, Значение);
Иначе
Структ.Вставить(Колонка.Имя, Строка(Значение));
КонецЕсли;
КонецЦикла;
МассивСтруктур.Добавить(Структ);
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивСтруктур);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Для передачи файла Excel через HTTP-сервис необходимо сохранить табличный документ во временный файл, прочитать его в двоичные данные и установить правильные заголовки Content-Type и Content-Disposition.
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
УдалитьФайлы(ИмяФайла);
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);
Ответ.Заголовки.Вставить("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Ответ.Заголовки.Вставить("Content-Disposition", "attachment; filename=report.xlsx");
Во-первых, если отчет возвращает пустую таблицу, проверьте параметры НачалоПериода и КонецПериода. Часто в СКД они скрыты, а пользователь взаимодействует с параметром типа СтандартныйПериод. Программная установка только «Периода» не всегда обновляет связанные скрытые границы дат.
Во-вторых, используйте КомпоновщикНастроек.ЗагрузитьНастройки() вместо прямой правки схемы, если вы работаете с вариантами отчета. Это гарантирует, что структура группировок и выбранные поля будут соответствовать выбранному варианту.
В-третьих, учитывайте особенности Linux-серверов. Если 1С развернута на Linux, при записи в HTML или PDF убедитесь, что в системе установлены шрифты (например, MS Core Fonts), иначе сервер может аварийно завершить процесс формирования макета.