Почему табличный документ 1С не сохраняется в Excel и как это исправить?

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

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

Причина 1. Контекст выполнения: сохранение на сервере вместо клиента

Основная причина, по которой файл не обнаруживается в папке C:\Temp, заключается в выполнении процедуры в серверном контексте с директивой &НаСервере. Проанализируем, что происходит при вызове метода ТабДок.Записать() на сервере в клиент-серверном режиме:

  1. Файловая система: Код обращается к диску того компьютера, на котором физически развернута служба сервера 1С (кластер 1С:Предприятия), а не к локальному диску клиентского ПК. Файл успешно создается на сервере, поэтому на клиенте его не видно.
  2. Права доступа: Запись выполняется от имени системной учетной записи службы (например, usr1cv8). Если у этой службы нет прав на запись в указанную директорию, метод вызовет исключение или завершится сбоем.

Причина 2. Ошибки формирования и сохранения табличного документа

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

  1. Пустой табличный документ: Перед вызовом метода сохранения важно убедиться, что функция формирования печатной формы действительно заполнила макет и вернула непустой ТабличныйДокумент (проверяем свойство ТабДок.ВысотаТаблицы > 0).
  2. Недопустимые символы в имени файла: Номера документов часто содержат символы /, \, пробелы или лидирующие нули. Если не удалить запрещенные символы (\ / : * ? " < > |), путь окажется некорректным.
  3. Формат выгрузки: Указание формата строкой "XLS" является устаревшей практикой. Для точного сохранения необходимо использовать системное перечисление ТипФайлаТабличногоДокумента.XLSX или ТипФайлаТабличногоДокумента.XLS. Формат XLSX предпочтительнее, так как снимает ограничение старого Excel в 65 536 строк и сохраняет полную палитру цветов оформления.

Решение 1. Формирование на сервере и сохранение на стороне клиента

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

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


&НаСервере
Функция СформироватьПечатнуюФормуНаСервере(СсылкаНаДокумент)
    // Формируем и заполняем печатную форму
    ТабДок = Новый ТабличныйДокумент;
    // ... Заполнение макета данными ...
    Возврат ТабДок;
КонецФункции

&НаКлиенте
Процедура СохранитьВExcel()
    ТабДок = СформироватьПечатнуюФормуНаСервере(Объект.АктСверки);
    
    Если ТабДок.ВысотаТаблицы = 0 Тогда
        ПоказатьОшибку(Новый ОписаниеОшибки("Печатная форма пуста."));
        Возврат;
    КонецЕсли;
    
    ПолныйПуть = Объект.КаталогВыгрузки + "\Акт_сверки.xlsx";
    ТабДок.Записать(ПолныйПуть, ТипФайлаТабличногоДокумента.XLSX);
    
    ПоказатьОповещениеПользователя("Успешно", , "Файл сохранен: " + ПолныйПуть);
КонецПроцедуры

Решение 2. Пакетная отправка по почте без сохранения на диск пользователя

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


&НаСервере
Процедура ОтправитьАктыПоПочтеНаСервере()
    Для Каждого Стр Из Объект.ТабДокументов Цикл
        Если Не Стр.ОтправитьПоЕмайл Тогда
            Продолжить;
        КонецЕсли;
        
        Если Не ЗначениеЗаполнено(Стр.АктСверки) Тогда
            ВывестиСообщение("Не выбран Акт сверки в строке!");
            Продолжить;
        КонецЕсли;
        
        ТабДок = ПолучитьПечатнуюФормуАктаСверки(Стр.АктСверки);
        
        Если ТабДок = Неопределено Или ТабДок.ВысотаТаблицы = 0 Тогда
            ВывестиСообщение("Печатная форма для " + Строка(Стр.АктСверки) + " не сформирована.");
            Продолжить;
        КонецЕсли;
        
        // Получаем уникальный временный файл на сервере
        ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
        ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.XLSX);
        
        // Отправляем почтовое сообщение с вложением
        ОтправитьПисьмо(Стр.АктСверки.Контрагент, ИмяВременногоФайла);
        
        // Удаляем временный файл после отправки
        УдалитьФайлы(ИмяВременногоФайла);
    КонецЦикла;
КонецПроцедуры

Рекомендация по выводу сообщений в серверном контексте

Использование классического оператора Сообщить() в серверном коде управляемого приложения считается устаревшей практикой и может некорректно привязываться к элементам формы. Рекомендуется использовать объект СообщениеПользователю:


&НаСервере
Процедура ВывестиСообщение(ТекстСообщения)
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = ТекстСообщения;
    Сообщение.Сообщить();
КонецПроцедуры

Использование такого подхода гарантирует доставку уведомлений пользователю в тонком клиенте и упрощает локализацию ошибок при пакетной обработке данных.

← На главную