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

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

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

Выясним причину: почему нельзя просто сохранить файл на сервере?

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

Решение 1: Возврат табличного документа на клиент и сохранение

Это самый надежный и универсальный способ. Разберем по шагам логику взаимодействия клиента и сервера:

  1. На клиенте мы определяем путь сохранения (через диалог или программно).
  2. Вызываем серверную функцию, которая компонует результат СКД в ТабличныйДокумент. На этом этапе полезно использовать СКДБилдер: упрощаем программное создание СКД, чтобы значительно сократить объем шаблонного кода.
  3. Возвращаем этот объект на клиент.
  4. Используем метод Записать() на стороне клиента.

Посмотрим на пример кода, который реализует эту схему:


&НаКлиенте
Процедура СформироватьИСохранитьОтчет()
    
    // 1. Определяем путь к рабочему столу через COM-объект (только для Windows-клиентов)
    Попытка
        Shell = Новый COMОбъект("WScript.Shell");
        ПутьККаталогу = Shell.SpecialFolders("Desktop");
    Исключение
        ПутьККаталогу = "C:\Temp"; // Резервный вариант
    КонецПопытки;
    
    ИмяФайла = ПутьККаталогу + "\Отчет_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".xlsx";
    
    // 2. Получаем сформированный табличный документ с сервера
    ТабДок = СформироватьОтчетНаСервере();
    
    // 3. Записываем файл на диск клиента
    Попытка
        ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
        Сообщить("Файл успешно сохранен: " + ИмяФайла);
    Исключение
        Предупреждение("Ошибка при сохранении файла! Проверьте права доступа.");
    КонецПопытки;
    
КонецПроцедуры

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

Решение 2: Использование временного хранилища для больших отчетов

Если отчет очень объемный, передача целого объекта ТабличныйДокумент может вызвать задержки. В этом случае рассмотрим подробнее вариант, где реализуется копирование файлов и каталогов между Клиентом и Сервером через двоичные данные и временное хранилище.

  1. На сервере формируем отчет и сохраняем его во временный файл.
  2. Преобразуем файл в ДвоичныеДанные и помещаем во ВременноеХранилище.
  3. На клиенте получаем эти данные и записываем по нужному адресу.

Пример реализации через временное хранилище:


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

&НаКлиенте
Процедура ВыполнитьЗагрузку()
    
    Адрес = СохранитьОтчетВоХранилище();
    // Используем метод БСП или стандартный ПолучитьФайл
    ОписаниеЗагрузки = Новый ОписаниеПередачиФайла(ИмяВыбранногоФайла, Адрес);
    // Параметр "Ложь" в ПолучитьФайл позволяет сохранить без диалогового окна, если путь известен
    ПолучитьФайл(Адрес, ИмяВыбранногоФайла, Ложь);
    
КонецПроцедуры

Решение 3: Работа с формами и БСП (Библиотека Стандартных Подсистем)

Если вы используете типовую конфигурацию, важно учитывать механизмы БСП.

Чтобы избежать ошибки "Не заданы параметры ФормыНастроек" и сохранить стандартные настройки, можно пойти двумя путями:

Важные рекомендации по автоматизации

Если отчет должен формироваться полностью автоматически по расписанию, используйте фоновые задания для новичков. Помните, что на сервере нет "Рабочего стола", поэтому рассмотрим подробнее следующие стратегии:

  1. Сетевой ресурс: Сохраняйте файл по прямому сетевому пути (UNC), например \\ServerName\Reports\Report.xlsx.
  2. Электронная почта: Используйте встроенный почтовый клиент 1С для отправки файла пользователю.
  3. Регистр сведений: Сохраняйте сформированные отчеты в регистр в виде двоичных данных, чтобы пользователь мог "забрать" их позже.

Подведем итог: Ключ к решению проблемы — четкое разделение полномочий. Клиент спрашивает путь и записывает физический файл, сервер — выполняет тяжелую работу по компоновке данных. Используя ВременноеХранилище и программные методы работы со схемой, вы сможете реализовать сохранение в любой доступный пользователю каталог без лишних трудностей.

← На главную