Как в 1С 7.7 программно переместить или скопировать папку со всем содержимым

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В платформе 1С:Предприятие 7.7 работа с файловой системой реализована достаточно базово, и стандартный объект ФС (Файловая Система) не содержит прямой команды вроде «ПереместитьКаталог» или «КопироватьКаталог». Разработчики часто сталкиваются с трудностями, когда нужно перенести целую иерархию папок с файлами. В этой статье мы подробно разберем несколько способов решения этой задачи: от простого использования встроенных функций до применения мощных системных инструментов.

Способ 1. Использование встроенной функции ПереименоватьФайл

Многие программисты воспринимают функцию ПереименоватьФайл только как инструмент для смены имени конкретного файла. Однако в 1С 7.7 она обладает скрытой и очень полезной особенностью: эта функция способна работать с каталогами и выполнять их мгновенное перемещение.

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

Рассмотрим пример кода:


// Определяем пути
ПутьОткуда = "C:\MyFolder\SourceData";
ПутьКуда = "C:\Archives\OldData";

// Выполняем перемещение всей папки целиком
ФС.ПереименоватьФайл(ПутьОткуда, ПутьКуда, 1);

Здесь третий параметр 1 означает перезапись, если папка с таким именем уже существует. Если вам нужно именно переместить папку «по-простому», обязательно сначала попробуйте этот метод.

Способ 2. Рекурсивное копирование и удаление через объект ФС

Если данные нужно перенести между разными дисками или сетевыми ресурсами, метод переименования не поможет. В такой ситуации нам придется реализовать алгоритм «обхода дерева», который будет заходить в каждую подпапку, создавать её копию в новом месте и копировать файлы по одному. Проанализируем пример кода, который часто используют разработчики, и выясним, почему он может выдавать ошибку.

Для начала нам понадобится вспомогательная функция, которая определяет, является ли найденный объект файлом или папкой. Мы будем использовать метод АтрибутыФайла:


Функция ЭтоКаталог(ИмяФайла) 
    Перем Размер, Атрибуты, Создан, Доступ, Запись, РасшИмяФайла; 
    Рез = 0; 
    ФС.АтрибутыФайла(ИмяФайла, Размер, Атрибуты, Создан, Доступ, Запись, РасшИмяФайла); 
    // В строке атрибутов 4-й символ "1" означает директорию
    Если Сред(Атрибуты,4,1) = "1" Тогда 
        Рез = 1; 
    КонецЕсли; 
    Возврат Рез; 
КонецФункции

Теперь разберем основную процедуру копирования. Обратите внимание, что мы используем рекурсию — функция вызывает саму себя для обработки вложенных папок:


Процедура КопироватьФайлы(ПутьОткуда, ПутьКуда)      
    ФС_ = СоздатьОбъект("ФС");
    
    // Проверяем, существует ли целевая папка, если нет — создаем
    Если (ФС_.СуществуетФайл(ПутьКуда) = 0) Тогда 
        ФС_.СоздатьКаталог(ПутьКуда); 
    КонецЕсли; 
    
    ИмяФайла = ФС_.НайтиПервыйФайл(ПутьОткуда + "\*.*"); 
    Пока ПустаяСтрока(ИмяФайла) = 0 Цикл 
        // Игнорируем служебные записи "." и ".."
        Если (ИмяФайла <> ".") И (ИмяФайла <> "..") Тогда 
            ПолныйПутьИсточника = ПутьОткуда + "\" + ИмяФайла;
            ПолныйПутьПриемника = ПутьКуда + "\" + ИмяФайла;

            Если ЭтоКаталог(ПолныйПутьИсточника) = 1 Тогда 
                // Если это папка, вызываем эту же процедуру (рекурсия)
                КопироватьФайлы(ПолныйПутьИсточника, ПолныйПутьПриемника); 
            Иначе
                // Если это файл, просто копируем его
                ФС_.КопироватьФайл(ПолныйПутьИсточника, ПолныйПутьПриемника, 0); 
            КонецЕсли;
        КонецЕсли; 
        ИмяФайла = ФС_.НайтиСледующийФайл(); 
    КонецЦикла;                                 
КонецПроцедуры

Почему не работает УдалитьКаталог? Анализируем ошибки

Часто после завершения копирования программист пытается вызвать ФС.УдалитьКаталог(ПутьОткуда), но получает ошибку «Ошибка при выполнении команды». Проанализируем причины этой ситуации:

  1. Каталог не пуст: Метод УдалитьКаталог в 1С 7.7 работает только с абсолютно пустыми папками. Если вы просто скопировали файлы, оригиналы остались на месте. Чтобы удалить папку, вам нужно сначала удалить все файлы внутри неё с помощью ФС.УдалитьФайл(), причем делать это нужно также рекурсивно, начиная с самых глубоких уровней вложенности.
  2. Блокировка платформой: 1С 7.7 имеет особенность «удерживать» папки. Если вы программно выбирали файл из этой папки или открывали текстовый документ через Текст.Открыть(), папка считается занятой процессом 1С.
  3. Текущий рабочий каталог: Если папка, которую вы хотите удалить, является текущим рабочим каталогом программы, Windows не позволит её удалить. Выясним, как это исправить: перед удалением нужно принудительно сменить рабочий каталог на любой другой (например, на папку с базой данных или временную папку).

Для «освобождения» папки используйте команду:

ФС.УстТекКаталог(КаталогИБ());

Способ 3. Использование Windows Script Host (FSO) — самый надежный метод

Если мы хотим избежать написания сложных рекурсивных функций и корректно обрабатывать удаление непустых папок, лучше всего воспользоваться мощностями операционной системы через COM-объект Scripting.FileSystemObject (FSO). Этот метод считается наиболее профессиональным для 1С 7.7.

Посмотрим на пример перемещения папки одной командой:


// Создаем объект для работы с файловой системой Windows
FSO = СоздатьОбъект("Scripting.FileSystemObject");

Попытка
    // Метод MoveFolder сам перенесет всё дерево каталогов
    FSO.MoveFolder("C:\SourcePath", "D:\DestinationPath");
    Сообщить("Папка успешно перемещена!");
Исключение
    Сообщить("Произошла ошибка: " + ОписаниеОшибки());
КонецПопытки;

Преимущества использования FSO:

Способ 4. Вызов системных утилит (Robocopy)

Для задач, связанных с перемещением огромных массивов данных (гигабайты файлов), или при работе в нестабильных сетях, рекомендуется использовать встроенную утилиту Windows — Robocopy. Она умеет возобновлять копирование при разрывах связи и корректно переносит права доступа.

Разберем, как запустить её из 1С:


// /MOVE - переместить (удалить из источника после копирования)
// /E - копировать все подпапки (включая пустые)
Команда = "robocopy ""C:\Откуда"" ""D:\Куда"" /MOVE /E";
КомандаСистемы(Команда);

Подведем итог: если вам нужно быстро переименовать папку на том же диске — используйте ФС.ПереименоватьФайл. Если нужно надежное программное управление с минимумом кода — выбирайте Scripting.FileSystemObject. А если вы решите писать свой велосипед с рекурсией через ФС, не забудьте сначала очистить папку от файлов, прежде чем пытаться удалить сам каталог.

← На главную