В процессе автоматизации различных задач часто возникает необходимость работать с файлами на диске. Одна из таких типовых операций — найти определенный файл в каталоге, имя которого известно лишь частично (например, содержит дату или уникальный идентификатор), и переименовать его для дальнейшей обработки или архивации. Рассмотрим, как реализовать этот механизм с помощью встроенных средств платформы 1С.
Проанализируем ситуацию: у нас есть каталог, в который выгружаются файлы с именами вроде ИмяФайла_20231026103045.txt. Нам нужно найти этот файл, зная только его префикс ИмяФайла, и присвоить ему новое, стандартное имя, например, Обработан.txt. Разберем по шагам, как это сделать.
Самый простой, надежный и кросс-платформенный способ решения этой задачи — использовать комбинацию двух встроенных функций языка 1С: НайтиФайлы() и ПереместитьФайл(). Этот подход работает как на Windows, так и на Linux серверах, что делает его предпочтительным.
Шаг 1. Поиск файла по маске с помощью НайтиФайлы()
Функция НайтиФайлы() предназначена для поиска файлов и каталогов по заданному пути и маске. Она возвращает массив объектов типа Файл, которые соответствуют условиям поиска.
Синтаксис функции:
НайтиФайлы(Путь, МаскаПоиска, Рекурсивно)
Путь (обязательный) — строка, содержащая путь к каталогу, в котором будет производиться поиск.МаскаПоиска (необязательный) — строка, определяющая шаблон для имен файлов. Можно использовать символы-джокеры: * (заменяет любую последовательность символов) и ? (заменяет один любой символ). Например, маска "Отчет_*.xlsx" найдет все файлы Excel, начинающиеся с "Отчет_".Рекурсивно (необязательный) — булево значение. Если Истина, поиск будет производиться также и во всех вложенных подкаталогах.В нашей задаче мы знаем путь к каталогу и начальную часть имени файла. Значит, маска будет выглядеть как "ИмяФайла*.txt". Напишем код для поиска:
ПутьККаталогу = "C:\Temp\Uploads\";
МаскаФайла = "ИмяФайла*.txt";
// Выполняем поиск и получаем массив найденных файлов
МассивНайденныхФайлов = НайтиФайлы(ПутьККаталогу, МаскаФайла);
Шаг 2. Проверка результата поиска и переименование файла
После выполнения поиска переменная МассивНайденныхФайлов будет содержать массив. Перед тем как что-то делать, важно проверить, а нашлись ли файлы вообще. Если массив пуст, то попытка обратиться к его элементам вызовет ошибку.
Для переименования файла используется функция ПереместитьФайл(). Несмотря на свое название, она может не только перемещать файл в другой каталог, но и переименовывать его в текущем. Для этого в качестве нового пути указывается тот же каталог, но с новым именем файла.
Синтаксис функции:
ПереместитьФайл(ИсходноеИмя, НовоеИмя)
ИсходноеИмя — полное имя файла, который нужно переместить/переименовать.НовоеИмя — новое полное имя файла.Теперь объединим все шаги в единый работающий код. Предположим, нам нужно переименовать только первый найденный файл.
Процедура НайтиИПереименоватьФайл()
ПутьККаталогу = "C:\Temp\Uploads\";
МаскаФайла = "ИмяФайла*.txt";
НовоеИмяФайла = "Обработан.txt";
// Выполняем поиск файлов по заданной маске
МассивНайденныхФайлов = НайтиФайлы(ПутьККаталогу, МаскаФайла);
// Проверяем, был ли найден хотя бы один файл
Если МассивНайденныхФайлов.Количество() > 0 Тогда
// Получаем первый элемент из массива найденных файлов.
// Это объект типа "Файл".
НайденныйФайл = МассивНайденныхФайлов[0];
// Формируем полное исходное и новое имя файла
ПолноеИмяИсходногоФайла = НайденныйФайл.ПолноеИмя;
ПолноеИмяНовогоФайла = ПутьККаталогу + НовоеИмяФайла;
// Пытаемся переименовать файл
Попытка
ПереместитьФайл(ПолноеИмяИсходногоФайла, ПолноеИмяНовогоФайла);
Сообщить("Файл успешно переименован: " + ПолноеИмяИсходногоФайла + " -> " + ПолноеИмяНовогоФайла);
Исключение
// Обрабатываем возможные ошибки (например, файл занят другим процессом или нет прав)
ИнформацияОбОшибке = ИнформацияОбОшибке();
Сообщить("Не удалось переименовать файл. Ошибка: " + ОписаниеОшибки(ИнформацияОбОшибке));
КонецПопытки;
Иначе
// Сообщаем, что файлы по указанной маске не найдены
Сообщить("Файлы по маске '" + МаскаФайла + "' в каталоге '" + ПутьККаталогу + "' не найдены.");
КонецЕсли;
КонецПроцедуры
Важный момент: если по маске может быть найдено несколько файлов, а переименовать нужно все, то код необходимо немного изменить (так часто происходит, когда выполняется массовая выгрузка картинок номенклатуры в каталог), организовав цикл по всем элементам массива.
// ... (начало такое же)
// Проверяем, был ли найден хотя бы один файл
Если МассивНайденныхФайлов.Количество() > 0 Тогда
Для Каждого НайденныйФайл Из МассивНайденныхФайлов Цикл
// Генерируем уникальное новое имя, например, добавляя GUID
НовоеИмя = "Обработан_" + Новый УникальныйИдентификатор() + ".txt";
ПолноеИмяНовогоФайла = НайденныйФайл.Путь + НовоеИмя;
Попытка
ПереместитьФайл(НайденныйФайл.ПолноеИмя, ПолноеИмяНовогоФайла);
Сообщить("Файл переименован: " + НайденныйФайл.ПолноеИмя + " -> " + ПолноеИмяНовогоФайла);
Исключение
// ... обработка ошибки
КонецПопытки;
КонецЦикла;
Иначе
// ... файлы не найдены
КонецЕсли;
Существует и альтернативный способ, который заключается в вызове команд операционной системы через COM-объект WScript.Shell. Этот метод более гибкий, так как позволяет использовать всю мощь командной строки Windows, но имеет существенный недостаток — он не будет работать на сервере 1С под управлением Linux.
Этот подход может быть оправдан, если требуется выполнить сложную пакетную операцию с файлами, которую трудно реализовать стандартными средствами 1С. Для нашей простой задачи переименования он избыточен, но для общего развития его стоит рассмотреть.
Идея заключается в том, чтобы выполнить команду командной строки ren (rename). Для более специфических задач, таких как распаковка конфигураций, используются другие консольные утилиты.
Процедура ПереименоватьЧерезCMD()
ПутьККаталогу = "C:\Temp\Uploads\";
СтараяМаска = "ИмяФайла*.txt";
НоваяМаска = "Обработан*.txt"; // Команда ren позволяет использовать маски и для нового имени
// Формируем команду для выполнения в командной строке
// %ComSpec% - системная переменная, указывающая на cmd.exe
// /C - флаг, который говорит cmd.exe выполнить команду и завершиться
// ren - команда переименования
Команда = "%ComSpec% /C ren """ + ПутьККаталогу + СтараяМаска + """ """ + НоваяМаска + """";
// Этот код будет работать только на клиенте или сервере под управлением Windows
#Если Клиент ИЛИ Сервер Тогда
Попытка
// Создаем COM-объект для работы с командной строкой
WshShell = Новый COMОбъект("WScript.Shell");
// Выполняем команду. 0 - скрыть окно, True - ждать завершения команды
WshShell.Run(Команда, 0, Истина);
Сообщить("Команда на переименование файлов выполнена.");
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
Сообщить("Не удалось выполнить команду. Ошибка: " + ОписаниеОшибки(ИнформацияОбОшибке));
КонецПопытки;
#КонецЕсли
КонецПроцедуры
Преимущества и недостатки WScript.Shell:
WScript.Shell и выполнение команд.Для задачи поиска и переименования файлов в 1С настоятельно рекомендуется использовать первый способ — комбинацию функций НайтиФайлы() и ПереместитьФайл(). Этот метод является стандартным, надежным, кросс-платформенным и полностью контролируется из кода 1С, включая обработку ошибок.
Второй способ с WScript.Shell следует рассматривать как "запасной" вариант для специфических задач, которые невозможно или слишком сложно решить встроенными средствами, и только в том случае, если вы уверены, что ваш код будет всегда выполняться в среде Windows.