Как настроить автоматическую выгрузку отчетов из 1С на другой сервер через регламентное задание?

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

В процессе автоматизации периодических задач программисты 1С часто сталкиваются со следующей ситуацией: написанная обработка или процедура выгрузки данных отлично работает при ручном запуске в интерактивном режиме («под собой»), но при переносе в регламентное (фоновое) задание мгновенно завершается с невыясненной ошибкой. Особенную сложность это вызывает в конфигурациях на базе обычных форм (например, Управление торговлей 10.3), где механизмы построения отчетов тесно связаны с интерфейсными общими модулями.

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

---

Почему код работает интерактивно, но падает в регламентном задании?

Для начала проанализируем разницу в средах выполнения. Когда мы запускаем обработку вручную через тонкий, толстый или веб-клиент, код выполняется в контексте текущего пользователя Windows. Этот пользователь имеет свой рабочий стол, сетевое окружение, доступ к смонтированным сетевым дискам и права на запись в сетевые папки.

Регламентные и фоновые задания выполняются исключительно на стороне сервера 1С:Предприятия. Процесс сервера (обычно это rphost.exe) функционирует в неинтерактивной сессии Windows (так называемая «Сессия 0»). У него нет доступа к графическому интерфейсу пользователя, а также к сетевым дискам, которые вы привыкли видеть в проводнике.

Давайте подробно разберем три основные причины, по которым процедура автоматической выгрузки отчета из примера автора завершается аварийно, и пошагово решим каждую из них.

---

Причина 1. Ограничения команды net use и использование сетевых дисков

В представленном коде автора для сохранения файла используется следующий подход:


Результат = "net use t: \\gate.saks.ru\translate\service\1c\_1с.ут.отчёты Amozhetbyttakoyparol7 /user:OFFICE\1cut";
ЗапуститьПриложение(Результат,,Истина);
ПутьКФайлуДискПодключен = "t:\" + ИмяФайла + ".xlsx";

Этот метод обречен на ошибку в фоновом задании по двум причинам:

  1. Изоляция сессий в ОС Windows. Сетевой диск T:, монтируемый через команду net use, привязывается к идентификатору безопасности (SID) сессии Windows, в которой была выполнена команда. Поскольку фоновое задание выполняется в изолированной служебной сессии, созданный диск просто не будет виден серверному процессу 1С при попытке записи файла через метод ТабДок.Записать().
  2. Права системной учетной записи. По умолчанию служба сервера 1С работает под локальной учетной записью (например, usr1cv8). Этот пользователь не является доменным и не имеет прав для выхода в локальную сеть, даже если в скрипте авторизации указаны логин и пароль. Попытка вызова консольных утилит в неинтерактивном режиме часто блокируется операционной системой из соображений безопасности.

Решение проблемы с сетевым доступом

Чтобы сервер 1С мог беспрепятственно сохранять файлы в сетевые папки других серверов, нам необходимо полностью отказаться от монтирования дисков буквами (вроде T:, Z:) и перейти на использование прямых сетевых путей формата UNC (Universal Naming Convention), например: \\gate.saks.ru\translate\service\1c\_1с.ут.отчёты\.

Разберем по шагам, как настроить права операционной системы для сервера 1С:

  1. Выясним, под каким пользователем запущена служба сервера 1С. Для этого на сервере приложений откроем оснастку «Службы» (нажмите Win + R, введите services.msc и нажмите Enter).
  2. Найдите службу Агент сервера 1С:Предприятия 8 (или 1C:Enterprise 8 Server Agent). Откройте ее свойства и перейдите на вкладку Вход в систему (Log On).
  3. Если там выбран переключатель «С системной учетной записью» (Local System) или указан локальный пользователь .\usr1cv8, служба не сможет получить доступ к шаре на другом сервере. Нам необходимо переключить запуск службы на специально созданную доменную учетную запись (например, ту самую OFFICE\1cut, которая использовалась в коде автора).
  4. После смены пользователя обязательно предоставьте этой учетной записи полные права (чтение и запись) на целевую сетевую папку \\gate.saks.ru\translate\service\1c\_1с.ут.отчёты\ на удаленном сервере.
  5. Перезапустите службу сервера 1С, чтобы изменения вступили в силу.

Теперь в коде 1С мы можем напрямую обращаться к сетевому адресу без выполнения внешних команд операционной системы:


ИмяФайла = СтрокаПоиска.НаименованиеОтчета;
ПутьКФайлу = "\\gate.saks.ru\translate\service\1c\_1с.ут.отчёты\" + ИмяФайла + ".xlsx";

// Запись файла выполняется напрямую по сети
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);

---

Причина 2. Клиент-серверные ограничения при формировании «Универсального отчета»

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


УниверсальныйОтчет = Отчеты.УниверсальныйОтчет.Создать();
// ...
УниверсальныеМеханизмы.ПолучитьНастройку(Structure);
// ...
Отчет.ВосстановитьНастройкиИзСтруктуры(СтруктураНастройки.СохраненнаяНастройка);
Отчет.СформироватьОтчет(ТабДок);

Универсальный отчет в конфигурациях уровня УТ 10.3 / УПП 1.3 очень сильно завязан на общие модули клиентского приложения. Например, общий модуль УниверсальныеМеханизмы может иметь флаг «Клиент» и отсутствовать на сервере, либо функции внутри него могут обращаться к интерактивным методам (вызывать окна предупреждений, открывать формы ввода дат, обращаться к глобальным переменным сессии типа глТекущийПользователь).

При выполнении фонового задания на сервере попытка вызвать процедуру, содержащую элементы GUI, приводит к немедленному падению потока с ошибкой «Интерактивное получение формы не разрешено» или «Переменная не определена».

Решение проблемы с контекстом отчетов

Рассмотрим подробнее, как адаптировать формирование отчета для выполнения в фоновом режиме:

  1. Проверка свойств общих модулей. Откроем конфигуратор, найдем модуль УниверсальныеМеханизмы и проверим его свойства. У него обязательно должен стоять флаг Сервер. Если в модуле присутствуют вызовы клиентских процедур (например, Предупреждение() или ОткрытьФорму()), их необходимо обернуть в инструкции препроцессора:

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

Проанализируем пример того, как можно программно выполнить СКД на сервере без привлечения интерфейсных механизмов:


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

---

Причина 3. Отсутствие логирования ошибок («хрен пойми, что за ошибка»)

Самая большая трудность при работе с регламентными заданиями — это их «молчаливое» падение. Если в обычном сеансе при возникновении ошибки система выдает понятное окно с описанием проблемы и указанием строки кода, то в фоновом задании выполнение просто прерывается. В консоли заданий статус меняется на «Ошибка», но деталей там практически нет.

Как настроить детальную диагностику

Разберем два эффективных метода локализации ошибок в регламентных заданиях.

Способ 1. Безопасное исполнение с логированием в Журнал регистрации

Обязательно оборачивайте весь исполняемый код регламентного задания в блок Попытка ... Исключение. Это позволит перехватить критическую ошибку, не даст заданию аварийно завершить работу всей службы и запишет подробную информацию (включая имя модуля и номер строки) в системный лог 1С.

Модернизируем процедуру автора, добавив в нее обработчик ошибок:


Процедура ВыгрузитьОтчеты() Экспорт
    
    Попытка
        ПараметрыПоиска = ПолучитьСписокОтчетов();
        Для каждого СтрокаПоиска из ПараметрыПоиска цикл
            
            // Проверка периодичности
            Если СтрокаПоиска.Неделя Тогда
                Если ДеньНедели(ТекущаяДата()) <> 1 Тогда
                    Продолжить;
                КонецЕсли;
            КонецЕсли;
            
            Период = ПолучитьПериод(СтрокаПоиска.PeriodStart, СтрокаПоиска.PeriodEnd);
            
            // Логика формирования отчета
            ТабДок = СформироватьТабличныйДокумент(СтрокаПоиска, Период);
            
            // Определение пути и сохранение
            ИмяФайла = СтрокаПоиска.НаименованиеОтчета;
            ПутьКФайлу = "\\gate.saks.ru\translate\service\1c\_1с.ут.отчёты\" + ИмяФайла + ".xlsx";
            
            ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
            
            // Фиксируем успешное выполнение в журнале
            ЗаписьЖурналаРегистрации("ВыгрузкаОтчетов",
                УровеньЖурналаРегистрации.Информация,
                ,
                ,
                "Успешно выгружен отчет: " + ИмяФайла);
        КонецЦикла;
        
    Исключение
        // Перехватываем ошибку и пишем подробный стек в журнал регистрации
        ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
        ЗаписьЖурналаРегистрации("ВыгрузкаОтчетов",
            УровеньЖурналаРегистрации.Ошибка,
            ,
            ,
            "Ошибка при выгрузке отчетов: " + ТекстОшибки);
    КонецПопытки;
    
КонецПроцедуры

Теперь в случае любого сбоя достаточно открыть в режиме предприятия меню Сервис -> Журнал регистрации, установить отбор по событию «ВыгрузкаОтчетов» и прочитать понятное техническое описание ошибки со ссылкой на строку кода.

Способ 2. Отладка фонового задания на сервере 1С

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

Для этого выполним следующие действия:

  1. Включим отладку на сервере 1С. По умолчанию отладка на сервере выключена. Чтобы ее включить, откройте редактор реестра на сервере 1С, перейдите в ветку службы ragent и добавьте параметр -debug в строку запуска службы. После этого перезапустите службу сервера 1С.
  2. В конфигураторе откройте меню Отладка -> Подключение...
  3. В открывшемся окне в списке доступных предметов отладки найдите пункт Фоновые задания на вашем сервере и нажмите кнопку Подключить.
  4. Поставьте точку останова в коде (например, на первой строчке процедуры ВыгрузитьОтчеты()).
  5. Запустите выполнение регламентного задания принудительно (это можно сделать через стандартную обработку «Консоль регламентных заданий»). В этот момент управление передастся в ваш конфигуратор, сработает точка останова, и вы сможете пошагово пройтись по коду серверной процедуры, проанализировать значения переменных и локализовать ошибку.

---

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

Для создания надежных механизмов автоматического экспорта данных из 1С придерживайтесь следующих архитектурных правил:

← На главную