Как в 1С найти файл в каталоге по маске и переименовать его?

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

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

Проанализируем ситуацию: у нас есть каталог, в который выгружаются файлы с именами вроде ИмяФайла_20231026103045.txt. Нам нужно найти этот файл, зная только его префикс ИмяФайла, и присвоить ему новое, стандартное имя, например, Обработан.txt. Разберем по шагам, как это сделать.

Решение 1: Использование встроенных функций 1С

Самый простой, надежный и кросс-платформенный способ решения этой задачи — использовать комбинацию двух встроенных функций языка 1С: НайтиФайлы() и ПереместитьФайл(). Этот подход работает как на Windows, так и на Linux серверах, что делает его предпочтительным.

Шаг 1. Поиск файла по маске с помощью НайтиФайлы()

Функция НайтиФайлы() предназначена для поиска файлов и каталогов по заданному пути и маске. Она возвращает массив объектов типа Файл, которые соответствуют условиям поиска.

Синтаксис функции:

НайтиФайлы(Путь, МаскаПоиска, Рекурсивно)

В нашей задаче мы знаем путь к каталогу и начальную часть имени файла. Значит, маска будет выглядеть как "ИмяФайла*.txt". Напишем код для поиска:


ПутьККаталогу = "C:\Temp\Uploads\";
МаскаФайла = "ИмяФайла*.txt";

// Выполняем поиск и получаем массив найденных файлов
МассивНайденныхФайлов = НайтиФайлы(ПутьККаталогу, МаскаФайла);

Шаг 2. Проверка результата поиска и переименование файла

После выполнения поиска переменная МассивНайденныхФайлов будет содержать массив. Перед тем как что-то делать, важно проверить, а нашлись ли файлы вообще. Если массив пуст, то попытка обратиться к его элементам вызовет ошибку.

Для переименования файла используется функция ПереместитьФайл(). Несмотря на свое название, она может не только перемещать файл в другой каталог, но и переименовывать его в текущем. Для этого в качестве нового пути указывается тот же каталог, но с новым именем файла.

Синтаксис функции:

ПереместитьФайл(ИсходноеИмя, НовоеИмя)

Теперь объединим все шаги в единый работающий код. Предположим, нам нужно переименовать только первый найденный файл.


Процедура НайтиИПереименоватьФайл()

    ПутьККаталогу = "C:\Temp\Uploads\";
    МаскаФайла   = "ИмяФайла*.txt";
    НовоеИмяФайла = "Обработан.txt";

    // Выполняем поиск файлов по заданной маске
    МассивНайденныхФайлов = НайтиФайлы(ПутьККаталогу, МаскаФайла);

    // Проверяем, был ли найден хотя бы один файл
    Если МассивНайденныхФайлов.Количество() > 0 Тогда
        
        // Получаем первый элемент из массива найденных файлов.
        // Это объект типа "Файл".
        НайденныйФайл = МассивНайденныхФайлов[0];
        
        // Формируем полное исходное и новое имя файла
        ПолноеИмяИсходногоФайла = НайденныйФайл.ПолноеИмя;
        ПолноеИмяНовогоФайла = ПутьККаталогу + НовоеИмяФайла;
        
        // Пытаемся переименовать файл
        Попытка
            ПереместитьФайл(ПолноеИмяИсходногоФайла, ПолноеИмяНовогоФайла);
            Сообщить("Файл успешно переименован: " + ПолноеИмяИсходногоФайла + " -> " + ПолноеИмяНовогоФайла);
        Исключение
            // Обрабатываем возможные ошибки (например, файл занят другим процессом или нет прав)
            ИнформацияОбОшибке = ИнформацияОбОшибке();
            Сообщить("Не удалось переименовать файл. Ошибка: " + ОписаниеОшибки(ИнформацияОбОшибке));
        КонецПопытки;
        
    Иначе
        // Сообщаем, что файлы по указанной маске не найдены
        Сообщить("Файлы по маске '" + МаскаФайла + "' в каталоге '" + ПутьККаталогу + "' не найдены.");
    КонецЕсли;

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

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


// ... (начало такое же)

// Проверяем, был ли найден хотя бы один файл
Если МассивНайденныхФайлов.Количество() > 0 Тогда

    Для Каждого НайденныйФайл Из МассивНайденныхФайлов Цикл
        // Генерируем уникальное новое имя, например, добавляя GUID
        НовоеИмя = "Обработан_" + Новый УникальныйИдентификатор() + ".txt";
        ПолноеИмяНовогоФайла = НайденныйФайл.Путь + НовоеИмя;

        Попытка
            ПереместитьФайл(НайденныйФайл.ПолноеИмя, ПолноеИмяНовогоФайла);
            Сообщить("Файл переименован: " + НайденныйФайл.ПолноеИмя + " -> " + ПолноеИмяНовогоФайла);
        Исключение
            // ... обработка ошибки
        КонецПопытки;
    КонецЦикла;

Иначе
    // ... файлы не найдены
КонецЕсли;

Решение 2: Использование внешних компонент (WScript.Shell)

Существует и альтернативный способ, который заключается в вызове команд операционной системы через 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:

Итоги и рекомендации

Для задачи поиска и переименования файлов в 1С настоятельно рекомендуется использовать первый способ — комбинацию функций НайтиФайлы() и ПереместитьФайл(). Этот метод является стандартным, надежным, кросс-платформенным и полностью контролируется из кода 1С, включая обработку ошибок.

Второй способ с WScript.Shell следует рассматривать как "запасной" вариант для специфических задач, которые невозможно или слишком сложно решить встроенными средствами, и только в том случае, если вы уверены, что ваш код будет всегда выполняться в среде Windows.

← На главную