В процессе разработки и сопровождения систем на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с нестандартным поведением файловой системы. Типичная ситуация: вы вызываете встроенную функцию для переименования файла, код выполняется без ошибок, но целевой файл на диске остается прежним. При этом платформа не выдает никаких предупреждений или системных исключений, оставляя разработчика в полном недоумении.
В этой статье мы подробно разберем, почему встроенный метод ФС.ПереименоватьФайл() может «тихо» игнорировать выполнение операции, проанализируем механизм блокировки файлов в платформе 1С 7.7, исправим распространенные ошибки склейки путей и рассмотрим профессиональное решение этой задачи с использованием объектной модели операционной системы Windows.
Разберем типичную ошибку начинающих разработчиков. Столкнувшись с тем, что файл не переименовывается, многие пытаются обернуть исполняемый код в стандартную конструкцию перехвата ошибок:
Попытка
ФС.ПереименоватьФайл(Путь1, Путь2, 1);
Исключение
Сообщить(ОписаниеОшибки()); // Этот блок никогда не выполнится!
КонецПопытки;
Выясним причину, почему этот подход не работает. Дело в том, что встроенный объект ФС и большинство его методов (включая ПереименоватьФайл) проектировались более двадцати лет назад. При возникновении ошибок на уровне операционной системы (например, если файл занят другим процессом или к нему нет прав доступа) метод не генерирует системное исключение. Он просто возвращает числовой статус работы:
1 — операция переименования или перемещения завершилась успешно;0 — произошла ошибка (файл занят, отсутствует, нет прав доступа или целевой файл уже существует, а флаг перезаписи равен 0).Поэтому правильная обработка результатов работы со встроенным объектом ФС всегда должна строиться на анализе возвращаемого значения, а не на блоке Попытка...Исключение:
Если ФС.ПереименоватьФайл(ИмяНачКаталога + ИмяФайла1, ИмяНачКаталога + ИмяФайла, 1) = 0 Тогда
Предупреждение("Не удалось переименовать файл! Проверьте, не открыт ли он в других программах.");
КонецЕсли;
---
Обратим внимание на то, как формируются пути к файлам в кодовой базе. Часто в конфигурациях встречается подобный код:
ИмяНачКаталога = КаталогПользователя();
ФС.ПереименоватьФайл(ИмяНачКаталога + "\" + ИмяФайла1, ИмяНачКаталога + "\" + ИмяФайла, 1);
Проанализируем работу встроенной функции КаталогПользователя(). Согласно спецификации платформы 1С 7.7, данный метод возвращает полный путь к каталогу, который уже заканчивается обратным слэшем (символом \). Например, результатом вызова функции будет строка вида "C:\Base_1c\DB\USR\".
Когда разработчик принудительно добавляет конструкцию + "\" +, итоговый путь к файлу начинает содержать двойной слэш:
C:\Base_1c\DB\USR\\t0.txt
Хотя операционные системы семейства Windows (особенно устаревшие версии) часто прощают подобные ошибки автозамены путей в адресной строке, современные ОС (такие как Windows 10 и Windows 11), а также сетевые протоколы передачи данных (UNC-пути в локальной сети) могут интерпретировать двойной слэш некорректно. Это приводит к отказам в доступе на уровне драйверов файловой системы.
Правило разработки: При работе с методами КаталогПользователя(), КаталогИБ() и КаталогВременныхФайлов() никогда не добавляйте разделитель каталогов вручную. Правильный синтаксис склейки выглядит так:
ПолныйПуть = КаталогПользователя() + ИмяФайла;
---
Наиболее частая причина, по которой файл отказывается переименовываться — это удержание дескриптора файла (file handle) самой платформой 1С. Рассмотрим типичный сценарий автоматизации:
СоздатьОбъект("Текст").Проблема кроется в том, что у объекта Текст в 1С 7.7 отсутствует явный метод Закрыть(). Windows продолжает удерживать монопольную блокировку файла до тех пор, пока объект, открывший его на запись или чтение, существует в оперативной памяти компьютера.
Чтобы операционная система позволила переименовать файл, необходимо принудительно уничтожить объект Текст (освободить переменную) перед вызовом файловых команд. Посмотрим, как это реализовать на практике:
// Шаг 1: Создаем и записываем файл
Приемник = СоздатьОбъект("Текст");
Приемник.ДобавитьСтроку("Тестовые данные для выгрузки...");
ПутьКФайлу = КаталогПользователя() + "t0.txt";
Приемник.Записать(ПутьКФайлу);
// Шаг 2: СБРАСЫВАЕМ БЛОКИРОВКУ ФАЙЛА
// Присвоение пустого значения уничтожает COM-ссылку и закрывает файл в ОС
Приемник = "";
// Шаг 3: Теперь файл свободен, его можно переименовывать
НовыйПуть = КаталогПользователя() + "text_file_10.09.2019.txt";
Если ФС.ПереименоватьФайл(ПутьКФайлу, НовыйПуть, 1) = 0 Тогда
Сообщить("Не удалось переименовать файл!", "!");
КонецЕсли;
Альтернативный способ очистки переменной — использование глобальной функции 1С ПолучитьПустоеЗначение(). Суть метода остается той же: пока переменная удерживает объект типа «Текст», операционная система будет отклонять любые попытки переименовать, переместить или удалить данный файл.
---
Если вам требуется построить максимально надежный и отказоустойчивый код для работы на современных операционных системах Windows, встроенный объект ФС лучше заменить на работу с системной библиотекой Microsoft Scripting Runtime через COM-соединение.
Объект Scripting.FileSystemObject (FSO) предоставляет разработчику гораздо более мощный инструментарий для манипуляции файловой системой. Главным его преимуществом является то, что при возникновении ошибок (блокировка файла, отсутствие прав, некорректный путь) он генерирует полноценные COM-исключения. Это позволяет нам использовать стандартную конструкцию Попытка...Исключение для вывода подробного системного сообщения об ошибке.
Рассмотрим пример реализации переименования файла с использованием FSO:
Процедура ПереименоватьФайлЧерезFSO(ПутьИсточник, ПутьПриемник)
Попытка
// Создаем системный объект для работы с файлами
ФСО = СоздатьОбъект("Scripting.FileSystemObject");
// Метод MoveFile выполняет функции переименования и перемещения
ФСО.MoveFile(ПутьИсточник, ПутьПриемник);
Сообщить("Файл успешно переименован.");
Исключение
// В случае ошибки мы получим реальное описание из ОС Windows
Сообщить("Не удалось переименовать файл! Ошибка: " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецПроцедуры
Использование Scripting.FileSystemObject решает сразу несколько проблем:
Подводя итоги нашего анализа работы с файлами в 1С 7.7, выделим ключевые правила, которые помогут избежать ошибок в дальнейшей работе:
ФС.ПереименоватьФайл() не вызывает исключений. Обязательно проверяйте его возвращаемое значение (1 или 0).КаталогПользователя() возвращает путь со знаком \ на конце. Избегайте появления двойных слэшей в путях.Текст всегда очищайте переменную (Текст = "";) перед тем, как производить файловые манипуляции с сохраненным документом.Scripting.FileSystemObject, который гарантирует надежный контроль ошибок и корректную интеграцию с актуальными версиями ОС Windows.