При настройке автоматической отправки отчетов по расписанию разработчики часто сталкиваются с техническим ограничением платформы 1С:Предприятие в старых конфигурациях (таких как «Управление торговлей 10.3», «Управление производственным предприятием 1.3» или «Комплексная автоматизация 1.1»). Попытка вызвать стандартный механизм «Универсального отчета» в фоновом или регламентном задании на сервере приводит к ошибке: «Метод УстановитьНачальныеНастройки не обнаружен».
Выясним причину этой проблемы. Архитектура старых конфигураций проектировалась под обычное приложение, где вся логика построения отчетов была завязана на клиентский контекст. В модулях отчетов (например, отчета Продажи) первая строчка кода часто начинается с директивы #Если Клиент Тогда, а последняя заканчивается #КонецЕсли. Из-за этого серверный код регламентного задания физически «не видит» процедуры инициализации и формирования отчета.
Рассмотрим подробнее эффективные практические способы решения этой задачи без глобального изменения типовой конфигурации.
Если вам запрещено изменять типовую конфигурацию (база находится на поддержке), это самый быстрый и безопасный способ. Мы создадим внешний отчет, который будет использоваться исключительно сервером для регламентной выгрузки.
Разберем этот процесс по шагам:
Продажи)..erf).#Если Клиент Тогда в самом начале модуля и #КонецЕсли в самом конце.ЭтаФорма, ЭлементыФормы и элементы интерфейса (например, индикаторы прогресса). Если в процедуре СформироватьОтчет присутствуют такие вызовы, закомментируйте их или вынесите в отдельный блок.Теперь в коде регламентного задания мы можем программно обращаться к этому отчету на сервере следующим образом:
// Получаем объект внешнего отчета из файла на сервере
ПутьКФайлу = "C:\Exchange\Reports\SalesReport.erf";
ВнешнийОтчет = ВнешниеОтчеты.Создать(ПутьКФайлу);
// Вызываем метод инициализации настроек, который теперь доступен на сервере
ВнешнийОтчет.УстановитьНачальныеНастройки();
// Задаем необходимые параметры и отборы программно
// (настройки структуры Универсального отчета)
НастройкиКомпоновки = ВнешнийОтчет.УниверсальныйОтчет.ПостроительОтчета.Настройки;
// Добавление отборов, параметров...
ТабДок = Новый ТабличныйДокумент;
ВнешнийОтчет.СформироватьОтчет(ТабДок);
Механизм «Универсальный отчет» в обычных формах — это надстройка над стандартным объектом платформы ПостроительОтчета. Если вам нужно просто получить данные на сервере, не обязательно использовать весь громоздкий интерфейсный функционал. Мы можем инициализировать построитель напрямую в серверном коде.
Посмотрим на пример реализации этого подхода:
// Инициализируем построитель отчета напрямую на сервере
Построитель = Новый ПостроительОтчета;
// Извлекаем текст запроса из схемы или пишем собственный
Построитель.Текст =
"ВЫБРАТЬ
| ПродажиОбороты.Контрагент КАК Контрагент,
| ПродажиОбороты.Номенклатура КАК Номенклатура,
| ПродажиОбороты.КоличествоОборот КАК Количество,
| ПродажиОбороты.СтоимостьОборот КАК Сумма
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты";
// Заполняем параметры запроса
Построитель.Параметры.Вставить("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Построитель.Параметры.Вставить("КонецПериода", КонецМесяца(ТекущаяДата()));
// Настраиваем отборы построителя программно
ОтборКонтрагент = Построитель.Отбор.Добавить("Контрагент");
ОтборКонтрагент.Использование = Истина;
ОтборКонтрагент.ВидСравнения = ВидСравнения.Равно;
ОтборКонтрагент.Значение = Справочники.Контрагенты.НайтиПоКоду("00001");
// Выполняем построение и выводим в Табличный документ
ТабДок = Новый ТабличныйДокумент;
Построитель.Выполнить();
Построитель.Вывести(ТабДок);
Этот способ гарантирует максимальное быстродействие на сервере, так как полностью исключает накладные расходы на инициализацию клиентских модулей Универсального отчета.
В типовых конфигурациях предусмотрен механизм хранения настроек отчетов пользователей. Вы можете настроить все отборы, показатели и группировки под учетной записью администратора в режиме «1С:Предприятие», сохранить эту настройку, а затем программно применить ее на сервере через общий модуль ТиповыеОтчеты.
Проанализируем пример кода для загрузки сохраненных настроек:
// Создаем объект отчета
ОтчетОбъект = Отчеты.Продажи.Создать();
// Используем типовую функцию для загрузки настроек на сервере
СтруктураНастроек = Новый Структура;
СтруктураНастроек.Вставить("Пользователь", ПараметрыСеанса.ТекущийПользователь);
СтруктураНастроек.Вставить("ИмяОтчета", "Продажи");
// Загружаем сохраненную настройку по ее наименованию
ТиповыеОтчеты.ПолучитьНастройкиОтчета(СтруктураНастроек, "ВыгрузкаДляКонтрагентов");
// Назначаем настройки построителю отчета
ТиповыеОтчеты.НазначитьПараметрыПостроителю(ОтчетОбъект.УниверсальныйОтчет.ПостроительОтчета, СтруктураНастроек);
Если архитектура отчета настолько сложна, что переписать ее под серверный контекст не представляется возможным, можно организовать запуск обработки в режиме обычного клиента по расписанию операционной системы.
Для этого выполняются следующие шаги:
ПриОткрытии() выполняет всю логику формирования отчета и отправки его по почте, после чего вызывает команду ЗавершитьРаботуСистемы(Ложь).
"C:\Program Files\1cv8\8.3.XX.XXX\bin\1cv8.exe" ENTERPRISE /F"C:\PathToBAse" /N"RobotEmail" /P"Password" /Execute"C:\Exchange\SendReports.epf"
Данный подход позволяет полностью обойти любые серверные ограничения, так как отчет физически формируется в контексте запущенного клиентского приложения.
При генерации отчетов на сервере и их последующей отправке по электронной почте важно соблюдать правила работы с файловой системой:
Показать() для объекта ТабличныйДокумент на сервере вызовет критическую ошибку. Вместо этого используйте экспорт в файл.Записать с указанием соответствующего типа файла:
ИмяФайла = КаталогВременныхФайлов() + "Sales_Report.xlsx";
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Важный нюанс: убедитесь, что у пользователя операционной системы, под которым запущена служба hi-1C:Enterprise Server (обычно это USR1CV8), есть права на запись в каталог, куда вы планируете сохранять временные файлы Excel перед их отправкой клиентам.