Очистка папок средствами 1С:Предприятия: код, консоль и регламентное задание

· 9 мин

Содержание

Файлы из каталога в 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С не видна.

Второе правило — безопасный режим. Внешние обработки и расширения конфигурации по умолчанию работают в безопасном режиме. В нём обращение к файловой системе запрещено, пока администратор не разрешит его профилем безопасности или не снимет флаг безопасного режима у расширения.

Удаление одного файла кодом

Минимальный рабочий вариант для серверного модуля:

&НаСервере
Процедура УдалитьФайлНаСервере(ПутьКФайлу)

	Файл = Новый Файл(ПутьКФайлу);
	Если Не Файл.Существует() Тогда
		Возврат;
	КонецЕсли;

	Если Файл.ПолучитьТолькоЧтение() Тогда
		Файл.УстановитьТолькоЧтение(Ложь);
	КонецЕсли;

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

КонецПроцедуры

Что здесь сделано и зачем:

  1. Объект Файл проверяет, что путь существует. Это защищает от лишних исключений при повторном запуске.
  2. Снимается атрибут «Только чтение». Файлы, скопированные с флешки или выгруженные из некоторых программ, часто приходят с ним.
  3. Удаление обёрнуто в Попытка. Файл может быть открыт в Excel или занят антивирусом, и без обработки исключения упадёт вся процедура обмена.
  4. Ошибка пишется в журнал регистрации, а не в Сообщить(): серверный код фонового задания никто не увидит.

УдалитьФайлы удаляет файлы безвозвратно, минуя корзину 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С на сервере за год разрастается до десятков гигабайт.

Схема, которая не оставляет мусора:

  1. Получите уникальное имя через ПолучитьИмяВременногоФайла("xlsx"). Функция только возвращает имя, сам файл не создаётся.
  2. Запишите в него данные и используйте.
  3. Удалите в любом случае — и при успехе, и при ошибке.
ИмяФайла = ПолучитьИмяВременногоФайла("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" оставит данные за трое суток.

Регламентное задание для автоматической очистки

Разовый запуск через обработку решает проблему на неделю. Надёжное решение — регламентное задание, которое раз в сутки само вызывает процедуру очистки.

Порядок настройки в Конфигураторе (или в расширении конфигурации, чтобы не снимать типовую с поддержки):

  1. Создайте общий модуль с флагом «Сервер» и перенесите в него процедуру ОчиститьКаталогОтСтарыхФайлов из раздела выше.
  2. Добавьте процедуру-обработчик без параметров или с параметрами из свойства задания:
Процедура ОчисткаКаталоговОбмена() Экспорт

	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОчисткаКаталоговОбмена);

	ОчиститьКаталогОтСтарыхФайлов("\\fileserver\obmen\site", 30);
	ОчиститьКаталогОтСтарыхФайлов("\\fileserver\obmen\bank", 90);

КонецПроцедуры
  1. В ветке Общие → Регламентные задания создайте задание ОчисткаКаталоговОбмена, укажите имя метода, установите флаги «Использование» и «Предопределенное».
  2. Задайте расписание: например, ежедневно в 03:00, когда нагрузка минимальна.
  3. Обновите конфигурацию базы данных.

Вызов ПриНачалеВыполненияРегламентногоЗадания нужен в конфигурациях на БСП: он проверяет права и режим работы базы. В самописной конфигурации без БСП эту строку уберите.

В файловом варианте регламентные задания выполняются, только пока открыт хотя бы один сеанс 1С. Если база файловая и по ночам никто не работает, используйте скрипт Windows из предыдущего раздела.

Перед включением автоочистки
Выполнено: 0 / 5

Почему файл не удаляется: ошибки и решения

Диагностика: выберите симптом

Частые вопросы

Можно ли восстановить файлы, удалённые методом УдалитьФайлы?
Средствами 1С — нет: файлы не попадают в корзину. Вернуть их можно только из резервной копии диска или теневых копий Windows, если они включены.
Как удалить файлы, прикреплённые к документам в базе?
Это другая задача: присоединённые файлы хранятся в базе или в томах хранения и удаляются пометкой на удаление и обработкой удаления помеченных объектов. Напрямую стирать файлы из томов нельзя — в базе останутся битые ссылки.
Удаляет ли УдалитьФайлы вложенные папки?
Да, если передать путь к каталогу без маски: каталог удаляется вместе со всем деревом. С маской удаляется то, что ей соответствует, поэтому для выборочной очистки надёжнее перебор через НайтиФайлы.
Можно ли запустить очистку из командной строки 1С?
Можно открыть базу в пакетном режиме с параметром /Execute и путём к внешней обработке, в которой выполняется очистка при открытии. Но для регулярной задачи регламентное задание или скрипт Windows проще и надёжнее.