В процессе разработки на платформе 1С:Предприятие часто возникает задача: сформировать отчет или документ, сохранить его во временный файл формата xlsx и сразу открыть его для пользователя в Microsoft Excel. Казалось бы, алгоритм прост: создаем файл, записываем данные и вызываем запуск приложения. Однако здесь программист сталкивается с технической дилеммой. Если вызвать команду удаления файла сразу после открытия, Excel выдаст ошибку "Файл не найден", так как он еще не успел считать данные. Если же файл не удалять, папка временных файлов (Temp) быстро превращается в свалку, что может привести к дефициту дискового пространства.
В этой статье мы подробно разберем, как работает механизм временных файлов в 1С, выясним, когда платформа берет на себя заботу об их удалении, и разработаем надежные алгоритмы для принудительной очистки после завершения работы пользователя с внешним приложением.
Разберем ситуацию, описанную в исходном вопросе. Программист использует метод ЗапуститьПриложение(). Эта функция отправляет операционной системе команду на открытие файла программой, ассоциированной с расширением .xlsx. Важно понимать, что 1С не ждет, пока Excel загрузится или пока пользователь закроет окно. Код 1С продолжает выполняться немедленно.
Посмотрим на пример кода, который вызывает ошибку:
ВременныйФайл = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанные.Записать(ВременныйФайл);
ЗапуститьПриложение(ВременныйФайл);
// Файл еще не открыт в Excel, а мы уже пытаемся его стереть
УдалитьФайлы(ВременныйФайл);
Проанализируем причину сбоя: операционная система Windows работает асинхронно. Процесс Excel инициализируется, ищет файл по переданному пути, но в этот момент интерпретатор 1С уже выполнил следующую строку — УдалитьФайлы(). В итоге Excel обращается к пустому месту. Нам необходимо решение, которое позволит удалить файл только тогда, когда он больше не нужен приложению Excel.
Существует распространенное мнение, что временные файлы удаляются сами. Выясним, так ли это на самом деле. Согласно официальной документации и материалам ИТС, платформа 1С действительно отслеживает файлы, созданные через функцию ПолучитьИмяВременногоФайла().
Как это работает:
ПолучитьИмяВременногоФайла() система генерирует уникальный путь в локальном каталоге временных файлов текущего пользователя.v8_).Однако есть критически важный нюанс: если в момент закрытия 1С файл все еще открыт в Excel, операционная система заблокирует попытку удаления со стороны 1С. Файл останется "висеть" до следующего запуска платформы, когда Excel будет гарантированно закрыт. Таким образом, полагаться на автоматику можно только при работе с небольшими объемами данных. Если ваша обработка генерирует сотни тяжелых отчетов в день, автоматическая очистка может не справляться.
Проанализируем ситуацию: нам нужно периодически проверять, освободил ли Excel файл, и если да — удалить его. Для этого идеально подходит механизм ПодключитьОбработчикОжидания(). Это позволяет не блокировать интерфейс пользователя и выполнить очистку в фоновом режиме на клиенте.
Рассмотрим по шагам реализацию этого метода:
Шаг 1. Подготовка структуры данных. Нам нужно передать имя файла в процедуру, которая будет его удалять.
&НаКлиенте
Процедура ОткрытьФайлИЗапланироватьУдаление()
ВременныйФайл = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанные.Записать(ВременныйФайл);
ЗапуститьПриложение(ВременныйФайл);
// Сохраняем имя файла в переменную модуля или параметры
ПараметрыУдаления = Новый Структура("ИмяФайла", ВременныйФайл);
// Подключаем обработчик, который сработает через 60 секунд
ПодключитьОбработчикОжидания("ВыполнитьОчисткуВременногоФайла", 60, Истина);
КонецПроцедуры
Шаг 2. Описание процедуры очистки. В этой процедуре мы попытаемся удалить файл. Если он все еще открыт в Excel, попытка вызовет исключение, которое мы просто проигнорируем до следующего раза или оставим файл на совесть платформы.
&НаКлиенте
Процедура ВыполнитьОчисткуВременногоФайла() Экспорт
// ИмяФайла должно быть доступно (например, через переменную модуля или хранилище)
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Сообщить("Временный файл успешно удален.");
Исключение
// Если файл занят Excel, ничего не делаем.
// Платформа попробует удалить его позже при закрытии.
КонецПопытки;
КонецПроцедуры
Если требуется гарантированное удаление сразу после того, как пользователь закрыл Excel, можно отказаться от ЗапуститьПриложение() в пользу прямого управления через COM-соединение. Этот метод сложнее в реализации, но дает программисту "рычаги управления" жизненным циклом внешнего процесса.
Рассмотрим пример алгоритма:
Новый COMОбъект("Excel.Application").Workbooks.Count.УдалитьФайлы().Важное ограничение: данный метод работает только на Windows и требует установленного Microsoft Excel непосредственно на рабочем месте пользователя (Тонкий или Толстый клиент). На веб-клиенте данный подход работать не будет.
Если ваша задача — поддерживать чистоту в каталоге временных файлов системно, можно внедрить процедуру очистки "хвостов" при запуске основной обработки или системы в целом. Проанализируем безопасный способ массового удаления.
Платформа генерирует имена файлов по определенному шаблону. Мы можем воспользоваться этим и вызвать удаление всех файлов, подходящих под маску, созданных ранее текущего момента.
&НаКлиенте
Процедура ОчиститьСтарыеВременныеФайлы()
КаталогВременных = КаталогВременныхФайлов();
// Удаляем все файлы, в имени которых есть v8 (стандартный префикс платформы)
// Будьте осторожны с масками, чтобы не удалить лишнего!
Попытка
УдалитьФайлы(КаталогВременных, "v8*.*");
Исключение
// Некоторые файлы будут заняты другими процессами, это нормально
КонецПопытки;
КонецПроцедуры
Подведем итог и выделим наиболее эффективную стратегию работы с временными файлами при открытии их во внешних редакторах:
ПолучитьИмяВременногоФайла(). Это гарантирует, что файл попадет в "поле зрения" механизмов самоочистки 1С.НачатьЗапускПриложения(). Хотя он не решает проблему удаления напрямую, он позволяет лучше обрабатывать завершение процесса.УдалитьФайлы() внутри блока Попытка...Исключение.Таким образом, мы выяснили, что наиболее корректным и простым способом решения проблемы является использование обработчика ожидания или делегирование очистки штатным механизмам платформы, при условии соблюдения правил именования файлов. Выбор конкретного метода зависит от критичности дискового пространства и объемов выгружаемых данных.