Очистка папок средствами 1С:Предприятия: код, консоль и регламентное задание
Содержание
Файлы из каталога в 1С:Предприятии 8.3 удаляют методом встроенного языка УдалитьФайлы(Путь, Маска). Один файл — УдалитьФайлы("D:\Obmen\order.xml"). Все XML в папке — УдалитьФайлы("D:\Obmen", "*.xml"). Каталог целиком вместе с содержимым — УдалитьФайлы("D:\Obmen") без маски. Если нужно удалить только старые файлы, сначала их находят через НайтиФайлы(), проверяют дату изменения и удаляют по одному.
Типичная история: обмен с сайтом полгода складывает выгрузки в папку на сервере, и однажды диск переполняется. Удалить файлы из каталога руками можно, но через неделю всё повторится. Ниже — код для разовой и регулярной очистки, работа с временными файлами, ручные способы через консоль и разбор ошибок.
Где выполняется код удаления и чьими правами
Прежде чем писать хоть одну строку, решите, на каком компьютере лежит папка. От этого зависит, где выполнять код.
- 🖥️ Файловый вариант базы, тонкий или толстый клиент. Код
&НаСервереи&НаКлиентевыполняется на компьютере пользователя. Права — права пользователя Windows. - 🏢 Клиент-серверный вариант. Код
&НаСерверевыполняется рабочим процессомrphostна сервере 1С. Пути считаются от сервера, права — у учётной записи, под которой запущена служба агента сервера (частоUSR1CV8или специально созданная служебная учётка). - 🌐 Веб-клиент. Доступ к локальным файлам пользователя есть только через расширение работы с файлами, и только асинхронными методами.
Отсюда первое правило. Путь C:\Users\Ivanov\Desktop\report.xlsx, переданный в серверную процедуру, на сервере не существует. Код отработает без удаления или упадёт с ошибкой.
Сетевые папки указывайте в формате UNC: \\fileserver\obmen\. Буква диска Z:\, подключённая у пользователя, для службы сервера 1С не видна.
Второе правило — безопасный режим. Внешние обработки и расширения конфигурации по умолчанию работают в безопасном режиме. В нём обращение к файловой системе запрещено, пока администратор не разрешит его профилем безопасности или не снимет флаг безопасного режима у расширения.
Удаление одного файла кодом
Минимальный рабочий вариант для серверного модуля:
&НаСервере
Процедура УдалитьФайлНаСервере(ПутьКФайлу)
Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
Возврат;
КонецЕсли;
Если Файл.ПолучитьТолькоЧтение() Тогда
Файл.УстановитьТолькоЧтение(Ложь);
КонецЕсли;
Попытка
УдалитьФайлы(ПутьКФайлу);
Исключение
ЗаписьЖурналаРегистрации("Очистка файлов", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось удалить " + ПутьКФайлу + ": " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Что здесь сделано и зачем:
- Объект
Файлпроверяет, что путь существует. Это защищает от лишних исключений при повторном запуске. - Снимается атрибут «Только чтение». Файлы, скопированные с флешки или выгруженные из некоторых программ, часто приходят с ним.
- Удаление обёрнуто в
Попытка. Файл может быть открыт в Excel или занят антивирусом, и без обработки исключения упадёт вся процедура обмена. - Ошибка пишется в журнал регистрации, а не в
Сообщить(): серверный код фонового задания никто не увидит.
УдалитьФайлы удаляет файлы безвозвратно, минуя корзину Windows. Перед первым запуском на рабочей папке проверьте путь и маску на тестовом каталоге.
Очистка каталога по маске и сроку хранения
Здесь три сценария, и у каждого свой метод.
| Задача | Как сделать | Риск |
|---|---|---|
| Удалить всё содержимое вместе с папкой | УдалитьФайлы(Каталог) | Папка исчезнет, её придётся создать заново через СоздатьКаталог() |
| Удалить файлы одного типа | УдалитьФайлы(Каталог, "*.xml") | Маска сработает и на подкаталоги с подходящим именем |
| Удалить файлы старше N дней | НайтиФайлы() + проверка даты + удаление по одному | Самый медленный, зато точный |
Удаление файлов старше заданного срока
Это самый частый запрос: оставить выгрузки за последние 30 дней, остальное убрать.
&НаСервере
Процедура ОчиститьКаталогОтСтарыхФайлов(Каталог, ДнейХранения = 30) Экспорт
Граница = ТекущаяУниверсальнаяДата() - ДнейХранения * 86400;
Найденные = НайтиФайлы(Каталог, ПолучитьМаскуВсеФайлы(), Истина);
Удалено = 0;
Для Каждого Файл Из Найденные Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
Если Файл.ПолучитьУниверсальноеВремяИзменения() >= Граница Тогда
Продолжить;
КонецЕсли;
Попытка
УдалитьФайлы(Файл.ПолноеИмя);
Удалено = Удалено + 1;
Исключение
ЗаписьЖурналаРегистрации("Очистка файлов", УровеньЖурналаРегистрации.Предупреждение, , ,
Файл.ПолноеИмя + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
ЗаписьЖурналаРегистрации("Очистка файлов", УровеньЖурналаРегистрации.Информация, , ,
СтрШаблон("Каталог %1: удалено файлов %2", Каталог, Формат(Удалено, "ЧН=0; ЧГ=0")));
КонецПроцедуры
Три приёма, которые отличают рабочий код от учебного:
- 🕐 Универсальное время с обеих сторон.
ТекущаяУниверсальнаяДата()иПолучитьУниверсальноеВремяИзменения()сравниваются корректно, даже если часовой пояс сервера и сеанса различаются. - 🐧
ПолучитьМаскуВсеФайлы()вместо"*.*". На Linux-сервере маска*.*пропустит файлы без точки в имени. Функция вернёт правильную маску для текущей ОС. - 🔁 Третий параметр
НайтиФайлы=Истина. Поиск идёт и по вложенным папкам. Нужен только верхний уровень — передайтеЛожь.
Пример по срокам: при ДнейХранения = 30 и запуске 15 марта граница — 13 февраля того же года. Всё, что изменялось раньше, удаляется.
Удаление опустевших подкаталогов
После очистки по дате в дереве остаются пустые папки. Удалять их нужно от самых глубоких к верхним, иначе родительская папка ещё не будет пустой.
&НаСервере
Процедура УдалитьПустыеПодкаталоги(Каталог)
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Путь");
Таблица.Колонки.Добавить("Длина");
Для Каждого Файл Из НайтиФайлы(Каталог, ПолучитьМаскуВсеФайлы(), Истина) Цикл
Если Файл.ЭтоКаталог() Тогда
Строка = Таблица.Добавить();
Строка.Путь = Файл.ПолноеИмя;
Строка.Длина = СтрДлина(Файл.ПолноеИмя);
КонецЕсли;
КонецЦикла;
Таблица.Сортировать("Длина Убыв");
Для Каждого Строка Из Таблица Цикл
Если НайтиФайлы(Строка.Путь, ПолучитьМаскуВсеФайлы(), Ложь).Количество() = 0 Тогда
Попытка
УдалитьФайлы(Строка.Путь);
Исключение
// папку держит другой процесс — оставляем до следующего запуска
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Сортировка по длине пути убыванием гарантирует, что D:\Obmen\2025\01 обработается раньше, чем D:\Obmen\2025.
Временные файлы и каталоги: создать, использовать, удалить
Отчёты, обмены и печать постоянно создают промежуточные файлы. Если их не убирать, папка Temp службы 1С на сервере за год разрастается до десятков гигабайт.
Схема, которая не оставляет мусора:
- Получите уникальное имя через
ПолучитьИмяВременногоФайла("xlsx"). Функция только возвращает имя, сам файл не создаётся. - Запишите в него данные и используйте.
- Удалите в любом случае — и при успехе, и при ошибке.
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
Попытка
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
УдалитьФайлы(ИмяФайла);
Исключение
УдалитьФайлы(ИмяФайла);
ВызватьИсключение;
КонецПопытки;
Когда временных файлов несколько (распаковка архива, пакет документов для ЭДО), удобнее завести временный каталог. Приём: имя от ПолучитьИмяВременногоФайла("") уже уникально, по нему создают папку.
ВременныйКаталог = ПолучитьИмяВременногоФайла("");
СоздатьКаталог(ВременныйКаталог);
// ... распаковка, обработка ...
УдалитьФайлы(ВременныйКаталог); // папка удаляется вместе со всем содержимым
Если файл нужно только передать между клиентом и сервером, временный файл часто не нужен вовсе. Двоичные данные кладут во временное хранилище через ПоместитьВоВременноеХранилище() и освобождают через УдалитьИзВременногоХранилища().
Не рассчитывайте, что платформа сама уберёт за вами временные файлы. Явное удаление — единственный надёжный вариант.
Удаление файлов на компьютере пользователя и в веб-клиенте
Если папка лежит у пользователя, а база работает на сервере, удалять нужно клиентским кодом. В современных конфигурациях синхронные вызовы на клиенте запрещены свойством «Режим использования синхронных вызовов расширений платформы и внешних компонент». Поэтому используют асинхронные методы.
На платформе 8.3.18 и новее код короткий:
&НаКлиенте
Асинх Процедура УдалитьФайлНаКлиенте(ПутьКФайлу)
Попытка
Ждать УдалитьФайлыАсинх(ПутьКФайлу);
Исключение
ПоказатьПредупреждение(, "Не удалось удалить файл: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
На более ранних платформах тот же результат даёт НачатьУдалениеФайлов(ОписаниеОповещения, Путь, Маска) с процедурой-обработчиком оповещения.
Для веб-клиента перед удалением проверьте, что установлено расширение работы с файлами. Без него браузер не даст коду доступ к диску пользователя.
Удаление вне кода: консоль, кэш и журналы
Не каждая очистка требует программирования. Часть задач администратор решает средствами Windows и самой платформы.
Скрипт Windows по расписанию
Для папок обмена на файловом сервере проще всего команда forfiles в Планировщике заданий:
forfiles /p "D:\1C\Obmen" /s /m *.xml /d -30 /c "cmd /c del @path"
Ключ /d -30 отбирает файлы, изменённые более 30 дней назад, /s включает подпапки. Аналог на PowerShell:
Get-ChildItem "D:\1C\Obmen" -Recurse -File |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Remove-Item
На Linux-сервере: find /srv/1c/obmen -type f -mtime +30 -delete.
Кэш клиента и сервера
- 🧹 Кэш клиента. Проще всего запустить 1С с параметром
/ClearCache. Вручную — закрыть все окна 1С и удалить папки с длинными именами из%APPDATA%\1C\1cv8и%LOCALAPPDATA%\1C\1cv8. Список баз и настройки пользователя при этом не пострадают, если не трогать файлыibases.v8iи1cestart.cfg. - 🗄️ Сеансовые данные сервера. Папки
snccntx...в каталогеsrvinfo\reg_1541удаляют только при остановленной службе агента сервера 1С.
Остановка службы сервера 1С обрывает сеансы всех пользователей. Делайте это вне рабочего времени и предупредите пользователей заранее. Перед остановкой сделайте копию каталога srvinfo.
Журнал регистрации и технологический журнал
Журнал регистрации хранится в папке 1Cv8Log внутри каталога базы. Удалять его файлы вручную на работающей базе нельзя. Сократить журнал можно в Конфигураторе: откройте Администрирование → Журнал регистрации и воспользуйтесь командой сокращения — задаётся дата, до которой события будут удалены, и при желании файл для сохранения удалённой части.
Технологический журнал чистится сам, если в logcfg.xml у элемента <log> задан атрибут history — срок хранения в часах. Например, history="72" оставит данные за трое суток.
Регламентное задание для автоматической очистки
Разовый запуск через обработку решает проблему на неделю. Надёжное решение — регламентное задание, которое раз в сутки само вызывает процедуру очистки.
Порядок настройки в Конфигураторе (или в расширении конфигурации, чтобы не снимать типовую с поддержки):
- Создайте общий модуль с флагом «Сервер» и перенесите в него процедуру
ОчиститьКаталогОтСтарыхФайловиз раздела выше. - Добавьте процедуру-обработчик без параметров или с параметрами из свойства задания:
Процедура ОчисткаКаталоговОбмена() Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОчисткаКаталоговОбмена);
ОчиститьКаталогОтСтарыхФайлов("\\fileserver\obmen\site", 30);
ОчиститьКаталогОтСтарыхФайлов("\\fileserver\obmen\bank", 90);
КонецПроцедуры
- В ветке
Общие → Регламентные заданиясоздайте заданиеОчисткаКаталоговОбмена, укажите имя метода, установите флаги «Использование» и «Предопределенное». - Задайте расписание: например, ежедневно в 03:00, когда нагрузка минимальна.
- Обновите конфигурацию базы данных.
Вызов ПриНачалеВыполненияРегламентногоЗадания нужен в конфигурациях на БСП: он проверяет права и режим работы базы. В самописной конфигурации без БСП эту строку уберите.
В файловом варианте регламентные задания выполняются, только пока открыт хотя бы один сеанс 1С. Если база файловая и по ночам никто не работает, используйте скрипт Windows из предыдущего раздела.