Почему я получаю ошибку времени выполнения 58 — файл уже существует при копировании файлов в VBA?

#vba

#excel #vba

Вопрос:

Я пытаюсь скопировать файлы в VBA, используя этот код

 Sub move_data()

Dim FSO As Object
Dim FileInFromFolder As Object

Dim FromPath As String
Dim ToPath As String
Dim ws As Worksheet:

Set FSO = CreateObject("scripting.filesystemobject")
Set ws = ThisWorkbook.Sheets("Sheet1")

FromPath = FSO.GetFolder(ws.Range("E1").Value)
ToPath = FSO.GetFolder(ws.Range("E3").Value)

For Each FileInFromFolder In FSO.GetFolder(FromPath).Files
FileInFromFolder.Move ToPath
Next FileInFromFolder

End Sub
 

Я получаю

Ошибка времени выполнения 58 — файл уже существует

хотя в ToPath

Если я ссылаюсь на папки напрямую, а не ссылаюсь на имена папок в ячейках E1 и E3 листа 1, код работает.

Комментарии:

1. Итак, если вы жестко закодируете значения, FromPath и ToPath это сработает? Вы проверили значения, сохраненные в диапазоне? Возможно, проблема со ссылкой на рабочий лист, хотя вы явно заявили, что это маловероятно. Я бы Debug.Print ws.Range("E1").Value и т. Д. Просто проверил, переходя по коду

2. Уточнение: конечно, я пытаюсь перемещать файлы, а не копировать их

3. Вы пробовали FileInFromFolder.Move ToPath amp; "" amp; FileInFromFolder.Name ?

4. Предложение VBasic2008 решило проблему. Спасибо!

5. После изучения проблемы можно сделать вывод, что FileInFromFolder.Move ToPath amp; "" этого достаточно. Смотрите Второе решение в моем ответе ниже.

Ответ №1:

Переместить все файлы

Документы Microsoft по Move :

Примечания
Результаты метода перемещения файла или папки идентичны операциям, выполняемым с помощью FileSystemObject.MoveFile или FileSystemObject.MoveFolder. Однако следует отметить, что альтернативные методы способны перемещать несколько файлов или папок.

Документы Microsoft по MoveFile :

Примечания
Если источник содержит подстановочные знаки или назначение заканчивается разделителем путей, предполагается, что назначение указывает существующую папку, в которую нужно переместить соответствующие файлы. В противном случае предполагается, что адресатом является имя файла назначения для создания. В любом случае при перемещении отдельного файла могут произойти три вещи:

  • Если пункт назначения не существует, файл перемещается. Это обычный случай.
  • Если адресатом является существующий файл, возникает ошибка.
  • Если адресатом является каталог, возникает ошибка.

Расследование
fso.MoveFile

  • На первый взгляд кажется fso.MoveFile , что это правильный путь, но это не так просто.
  • Первая проблема заключается в том, что если в исходном коде нет файлов, возникнет ошибка: решаемая с If .GetFolder(FromPath).Files.Count > 0 Then помощью .
  • Вторая (худшая) проблема заключается в том, что если файл уже существует в месте назначения, вы не можете быть уверены, что будет скопировано, прежде чем возникнет ошибка: не решена.
  • Конечно, если вы знаете, что место назначения пустое или, по крайней мере, нет никаких существующих файлов, это более эффективный способ. Но я бы не стал делать ставку на это.
  • FromPath за ним должно следовать PathSeparator и, по крайней мере * , , в то время ToPath как должно заканчиваться на PathSeparator .

fso.File.Move

  • fso.File.Move Решение должно перебирать файлы. Но вам не нужно проверять количество файлов, и вы можете реализовать If Not .FileExists(ToPath amp; fsoFile.Name) Then проверку существования файла с тем же именем в пункте назначения.
  • ToPath должен заканчиваться PathSeparator , но при желании за ним может следовать имя файла ( fsoFile.Name ) .

Код

 Option Explicit

Sub moveAllFilesFSO()
    
    Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
    Dim FromPath As String: FromPath = ws.Range("E1").Value
    Dim ToPath As String: ToPath = ws.Range("E3").Value
    
    With CreateObject("Scripting.FileSystemObject")
        If .FolderExists(FromPath) And .FolderExists(ToPath) Then
            If .GetFolder(FromPath).Files.Count > 0 Then
                Dim Sep As String: Sep = Application.PathSeparator
                If Right(FromPath, 1) <> Sep Then
                    FromPath = FromPath amp; Sep
                End If
                FromPath = FromPath amp; "*" ' "*.*"
                If Right(ToPath, 1) <> Sep Then
                    ToPath = ToPath amp; Sep
                End If
                .MoveFile FromPath, ToPath
            Else
                Debug.Print "No files found in " amp; "'" amp; FromPath amp; "'."
            End If
        Else
            Debug.Print "At least one of the folders does not exist."
        End If
    End With

End Sub

Sub moveAllFilesFile()
    
    Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
    Dim FromPath As String: FromPath = ws.Range("E1").Value
    Dim ToPath As String: ToPath = ws.Range("E3").Value
    
    With CreateObject("Scripting.FileSystemObject")
        If .FolderExists(FromPath) And .FolderExists(ToPath) Then
            ToPath = .GetFolder(ToPath) amp; Application.PathSeparator
            Dim fsoFile As Object
            For Each fsoFile In .GetFolder(FromPath).Files
                If Not .FileExists(ToPath amp; fsoFile.Name) Then
                    fsoFile.Move ToPath ' amp; fsoFile.Name
                'Else
                    ' File already exists.
                End If
            Next fsoFile
        Else
            Debug.Print "At least one of the folders does not exist."
        End If
    End With

End Sub