Почему регламентное задание формирует поврежденный файл Excel и как это исправить

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

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

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

Причины некорректного формирования файлов XLSX на сервере

Проанализируем технические особенности работы сервера 1С, которые приводят к сбою форматирования электронных таблиц:

  1. Отсутствие контекста GDI и драйвера принтера в сессии службы. При экспорте табличного документа в форматы электронных таблиц платформа 1С обращается к графической подсистеме Windows (GDI) и драйверу принтера по умолчанию для точного расчета метрик шрифтов, высоты строк и автопереноса текста. Служба сервера 1С (процессы rphost) работает в изолированной нулевой сессии Windows (Session 0) под учетной записью USR1CV8. Если для этого пользователя не настроен принтер по умолчанию или отсутствуют нужные шрифты, расчет геометрии ячеек сбивается.
  2. Утечка дескрипторов GDI и переполнение Desktop Heap. При длительной работе службы без перезапуска рабочие процессы кластера накапливают дескрипторы графических объектов при постоянном рендеринге печатных форм. По исчерпании лимитов процесс перестает корректно рассчитывать разметку XML-структуры OpenXML, из-за чего файлы становятся огромными и визуально «пустыми».
  3. Блокировка временных файлов и ошибки удаления. Если в коде регламентного задания генерируется статическое имя файла или происходит попытка вызова УдалитьФайлы() до того, как объект отправки почты освободил файловый дескриптор, возникает исключение либо попытка перезаписи занятого файла.

Шаг 1. Экстренное восстановление работоспособности

Если сбой уже произошел и клиенты получают искаженные файлы, выполним следующие оперативные действия:

  1. Перезапуск службы сервера 1С и очистка временных файлов. Очистим содержимое папки Temp системной учетной записи USR1CV8 (обычно расположена по пути C:\Users\USR1CV8\AppData\Local\Temp). Затем перезапустим службу 1C:Enterprise 8.3 Server Agent. При наличии возможности выполним полную перезагрузку операционной системы сервера для сброса графических пулов памяти.
  2. Проверка прав учетной записи службы. Убедимся, что учетная запись USR1CV8 обладает полными правами на чтение и запись в рабочий каталог кластера и системную временную папку.

Шаг 2. Настройка виртуального принтера для пользователя USR1CV8

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

  1. Выполним вход в Windows под служебной учетной записью USR1CV8.
  2. Перейдем в настройки устройств и принтеров операционной системы.
  3. Установим и назначим принтером по умолчанию виртуальный принтер, например Microsoft Print to PDF или Microsoft XPS Document Writer.
  4. Проверим наличие в операционной системе стандартных шрифтов (Arial, Calibri, Tahoma), которые используются в макетах выгружаемых прайс-листов.

Шаг 3. Настройка параметров кластера 1С

Чтобы избежать постепенного накопления утечек памяти и дескрипторов GDI в процессах rphost, настроим регулярный автоматический перезапуск рабочих процессов:

  1. Откроем консоль администрирования кластера серверов 1С.
  2. В свойствах рабочего сервера установим параметр Интервал перезапуска рабочих процессов, например 86400 секунд (один раз в сутки).
  3. При необходимости ограничим допустимый объем памяти на процесс и настроим время отключения неактивных сеансов.

Шаг 4. Доработка программного кода выгрузки

Разберем правильный алгоритм формирования и сохранения файлов на стороне сервера. Перед вызовом метода Записать() явно укажем параметры отображения документа, обеспечим уникальность имени временного файла и корректное освобождение ресурсов.

Посмотрим на пример правильной организации кода:


// Формируем уникальное имя файла во временном каталоге
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");

// Настраиваем свойства табличного документа перед записью
ТабДокумент.ОтображатьСетку = Истина;
ТабДокумент.АвтоМасштаб = Истина;

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

// Освобождаем ссылку на табличный документ для экономии памяти
ТабДокумент = Неопределено;

// Отправляем сформированный файл по почте
Попытка
    ОтправитьПрайсЛистПоПочте(ИмяФайла, Получатель);
Исключение
    ЗаписьЖурналаРегистрации("РассылкаПрайса", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

// Корректно удаляем временный файл
Попытка
    УдалитьФайлы(ИмяФайла);
Исключение
    // Файл может временно удерживаться почтовым клиентом или антивирусом
    ЗаписьЖурналаРегистрации("УдалениеВременногоФайла", УровеньЖурналаРегистрации.Предупреждение,,, 
        "Не удалось удалить временный файл: " + ИмяФайла);
КонецПопытки;

Использование метода ПолучитьИмяВременногоФайла() гарантирует изоляцию потоков разных клиентов при параллельной рассылке и исключает конфликты перезаписи файлов со схожими именами.

← На главную