Как правильно копировать файлы с подпапками между сетевыми каталогами в 1С и избежать ошибок доступа?

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

При разработке механизмов обмена файлами или автоматизации архивации в 1С программисты часто сталкиваются с ситуацией, когда стандартная функция КопироватьФайл отказывается работать. Проблема осложняется, когда копирование происходит между сетевыми ресурсами (UNC-пути), а сами файлы имеют атрибут "Только чтение". В данной статье мы подробно разберем, почему возникают ошибки доступа, как правильно реализовать рекурсивный обход папок и какие альтернативные системные инструменты можно задействовать для надежной работы кода на стороне сервера.

Анализ причин возникновения ошибок доступа

Прежде чем приступать к написанию кода, проанализируем ситуацию, когда ручное копирование работает, а программное из 1С — нет. Чаще всего причина кроется в учетной записи, под которой запущена служба "Агент сервера 1С:Предприятие". Рассмотрим основные сценарии:

  1. Локальная учетная запись сервера: По умолчанию 1С устанавливается под пользователем USR1CV8. Эта запись не имеет прав доступа к сетевым ресурсам (папкам вида \\server\share). Чтобы сервер 1С мог "видеть" внешние каталоги, служба должна быть запущена от имени доменного пользователя, которому предоставлены права NTFS и права общего доступа на обе папки (источник и приемник).
  2. Атрибут Read-Only: Если целевой файл в папке назначения уже существует и на нем установлен флаг "Только чтение", функция КопироватьФайл завершится с ошибкой "Доступ запрещен", даже если у пользователя есть полные права. Система не может перезаписать файл, защищенный от изменений.
  3. Проблема "второго прыжка": При попытке обращения к сетевому ресурсу через серверную процедуру права текущего пользователя 1С не транслируются на сетевой ресурс напрямую. Все действия выполняются от имени системной службы.

Решение 1: Исправление логики стандартного копирования 1С

Рассмотрим, как модифицировать код, чтобы он корректно обрабатывал вложенные папки и снимал блокирующие атрибуты. Ключевым моментом здесь является проверка существования файла в приемнике и явное снятие атрибута ТолькоЧтение перед попыткой копирования.

Проанализируем пример функции, которая подготавливает структуру каталогов:


&НаСервере
Функция СкопироватьФайлБезопасно(ИмяФайлаИсточник, ИмяФайлаНазначение)
    
    ФайлПриемник = Новый Файл(ИмяФайлаНазначение);
    
    // Проверим наличие целевого каталога и создадим его при необходимости
    КаталогНазначения = ФайлПриемник.Путь;
    СоздатьКаталог(КаталогНазначения);
    
    // Важный этап: снятие атрибута "Только чтение" с существующего файла
    Если ФайлПриемник.Существует Тогда
        Если ФайлПриемник.ПолучитьТолькоЧтение() Тогда
            ФайлПриемник.УстановитьТолькоЧтение(Ложь);
        КонецЕсли;
    КонецЕсли;
    
    // Снятие атрибута с источника (иногда требуется для некоторых сетевых ФС)
    ФайлИсточник = Новый Файл(ИмяФайлаИсточник);
    Если ФайлИсточник.Существует И ФайлИсточник.ПолучитьТолькоЧтение() Тогда
        ФайлИсточник.УстановитьТолькоЧтение(Ложь);
    КонецЕсли;

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

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

Решение 2: Использование COM-объекта FileSystemObject (FSO)

Если стандартные функции 1С продолжают выдавать неочевидные ошибки, мы можем обратиться к мощностям операционной системы через COMОбъект. Объект Scripting.FileSystemObject предоставляет более гибкие инструменты для работы с файловой системой Windows, включая принудительную перезапись файлов с атрибутом Read-Only.

Посмотрим на пример реализации:


&НаСервере
Процедура КопироватьЧерезFSO(ПутьИсточник, ПутьПриемник)
    
    Попытка
        FSO = Новый COMОбъект("Scripting.FileSystemObject");
        
        // Метод CopyFile(Source, Destination, Overwrite)
        // Третий параметр True позволяет перезаписывать файлы даже с атрибутом ReadOnly в некоторых случаях
        FSO.CopyFile(ПутьИсточник, ПутьПриемник, Истина);
        
    Исключение
        Сообщить("Ошибка FSO: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Преимущество FSO заключается в том, что он работает на уровне системных вызовов Windows и иногда лучше справляется с очень длинными путями (более 255 символов) и специфическими сетевыми блокировками.

Решение 3: Рекурсивный обход вложенных каталогов

Для задачи, описанной автором темы (когда нужно перенести структуру папок из Excel), необходимо реализовать рекурсию. Проанализируем правильный алгоритм обхода:


&НаСервере
Процедура СкопироватьРекурсивно(Откуда, Куда)
    
    // Получаем список всех файлов и папок в источнике
    МассивФайлов = НайтиФайлы(Откуда, "*.*");
    
    Для Каждого ОбъектФайл Из МассивФайлов Цикл
        
        НовыйПутьНазначения = Куда + "\" + ОбъектФайл.Имя;
        
        Если ОбъектФайл.ЭтоКаталог Тогда
            // Создаем папку в приемнике и идем глубже
            СоздатьКаталог(НовыйПутьНазначения);
            СкопироватьРекурсивно(ОбъектФайл.ПолноеИмя, НовыйПутьНазначения);
        Иначе
            // Вызываем нашу безопасную функцию копирования файла
            СкопироватьФайлБезопасно(ОбъектФайл.ПолноеИмя, НовыйПутьНазначения);
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

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

Дополнительные рекомендации по работе с сетевыми путями

Выясним еще несколько важных моментов, которые помогут избежать проблем при внедрении:

Таким образом, для успешного копирования файлов во вложенных папках нам необходимо обеспечить три условия: правильную учетную запись службы 1С для доступа к сети, программное снятие атрибута "Только чтение" и корректный рекурсивный обход с созданием структуры каталогов. Сочетание этих методов гарантирует стабильную работу обработки в любых условиях.

← На главную