在excel中复制、重命名和验证多个文件和路径是否成功

在excel中复制、重命名和验证多个文件和路径是否成功,excel,vba,validation,copy,rename,Excel,Vba,Validation,Copy,Rename,在过去的5天里,我一直在这里和网络上四处寻找适合多个文件的东西。许多深夜/清晨拼凑/编码以获得结果都没有成功。提前谢谢 以下代码来自奥斯卡编写的get-digital-help.com/copyrame-a-file-excel-vba 它适用于1个文件,我有8000个文件要在一个深文件夹结构中执行,所以我真的希望每一行查看源路径、源文件名、目标路径和目标文件: 对于每行: 列A列出源路径 列B列出了源文件名 列C列出目标路径 列D列出了新的文件名 列E写“成功”或“失败”验证 如果目标中

在过去的5天里,我一直在这里和网络上四处寻找适合多个文件的东西。许多深夜/清晨拼凑/编码以获得结果都没有成功。提前谢谢

以下代码来自奥斯卡编写的get-digital-help.com/copyrame-a-file-excel-vba 它适用于1个文件,我有8000个文件要在一个深文件夹结构中执行,所以我真的希望每一行查看源路径、源文件名、目标路径和目标文件:

对于每行:

  • 列A列出源路径
  • 列B列出了源文件名
  • 列C列出目标路径
  • 列D列出了新的文件名
列E写“成功”或“失败”验证

  • 如果目标中已存在文件名,则“失败”
  • 如果源文件不存在,则“失败”
很高兴拥有/完全可选!!!:)

  • 检查源文件A和B列是否存在,=F列中的True或False。如果为True,则继续复制和重命名
  • 如果目标文件已经存在,则失败,列F=重复
  • 保留第一行以输入列标题名称
  • 
    
    子副本重命名文件()
    '维度变量和声明数据类型
    Dim src为字符串,dst为字符串,fl为字符串
    作为字符串的Dim rfl
    '将单元格A2中指定的源目录保存到变量src
    src=范围(“A2”)
    '将单元格C2中指定的目标目录保存到变量dst
    dst=范围(“C2”)
    '将单元格B2中指定的文件名保存到变量fl
    fl=范围(“B2”)
    '将单元格D2中指定的新文件名保存到变量rfl
    rfl=范围(“D2”)
    '启用错误处理
    出错时继续下一步
    '将基于变量src和fl的文件复制到基于变量dst的目标文件夹,并根据rfl中的值命名文件
    文件拷贝src&“\”&fl,dst&“\”&rfl
    '检查是否发生了错误
    如果错误号为0,则
    '使用消息框显示错误
    MsgBox“复制错误:&src&“\”&rfl
    如果结束
    '禁用错误处理
    错误转到0
    端接头
    
    使用文件列表复制文件
    • 此解决方案包括三个步骤。您只运行第一个:
      copyramenefile
      。其他两个,
      getOffsetColumn
      writeOffsetRange
      将在必要时由第一个调用

    • 最好使用新工作簿对其进行测试。插入模块并将代码复制到其中。现在打开原始工作簿并将某些值复制到新工作簿的
      Sheet1
      。由于代码是为
      此工作簿
      (包含此代码的工作簿)编写的,因此原始工作簿将是安全的(不会写入)

    • 首先调整常量部分中的值(标题为
      工作表
      其他
      )。然后测试空工作表。然后使用列
      A
      中的一个文件夹进行测试,然后使用更多文件夹进行测试,然后缓慢地继续使用其他列进行测试。应抑制可能的错误,并且其消息(说明)应显示在
      VBE
      Immediate
      窗口(CTRL+G)中

    • 作为本次调查的副产品,我还添加了
      createFolders
      功能,在
      MkDir
      “不能”的情况下创建文件夹,并添加了两个过程对其进行测试

    代码

    Option Explicit
    
    Sub copyRenameFile()
    
        ' Initialize error handling.
        Const ProcName As String = "copyRenameFile"
        On Error GoTo clearError ' Turn on error trapping.
        
        ' Worksheet
        Const wsName As String = "Sheet1"        ' Worksheet Name
        Const FirstRow As Long = 2               ' First Row Number
        Const LastRowCol As Variant = "A"        ' Last Row Column Index
        Dim srcCols As Variant                   ' Source Columns Array
        srcCols = VBA.Array("A", "B", "C", "D")
        Dim tgtCols As Variant                   ' Target Columns Array
        tgtCols = VBA.Array("E", "F")
        
        ' Other
        Dim filMsg() As Variant                  ' File Messages
        filMsg = VBA.Array("Fail", "Success")
        Dim folMsg() As Variant                  ' Folder Messages
        folMsg = VBA.Array(False, True, "Duplicate")
        Dim PathDelimiter As String
        PathDelimiter = Application.PathSeparator
        Dim wb As Workbook
        Set wb = ThisWorkbook ' 'Thisworkbook' is the workbook containing this code.
        
        ' Define Last Row Column Range ('rng').
        Dim ws As Worksheet
        Set ws = wb.Worksheets(wsName)
        Dim LastRow As Long
        LastRow = ws.Cells(ws.Rows.Count, LastRowCol).End(xlUp).Row
        If LastRow < FirstRow Then
            GoTo FirstRowBelowLastRow
        End If
        Dim rng As Range
        Set rng = ws.Range(ws.Cells(FirstRow, LastRowCol), _
                           ws.Cells(LastRow, LastRowCol))
         
        ' Write Source Column Ranges to Source Jagged Array ('Source').
        Dim ubcS As Long
        ubcS = UBound(srcCols)
        Dim Source As Variant
        ReDim Source(0 To ubcS)
        Dim Data As Variant
        Dim j As Long
        For j = 0 To ubcS
            getOffsetColumn Data, srcCols(j), rng
            Source(j) = Data
        Next j
        
        ' Define Target Jagged Array ('Target').
        Dim ubcT As Long
        ubcT = UBound(tgtCols)
        Dim ubs As Long
        ubs = UBound(Source(0))
        Dim Target As Variant
        ReDim Target(0 To ubcT)
        ReDim Data(1 To ubs, 1 To 1)
        For j = 0 To ubcT
            Target(j) = Data
        Next j
        
        ' Declare additional variables for the For Next loop.
        Dim i As Long
        Dim Copied As Long
        Dim srcPath As String
        Dim tgtPath As String
        
        ' Loop through rows of arrays of Source Jagged Array, check folders,
        ' check files and finally copy if condition is met. At the same time
        ' write results to arrays of Target Jagged Array.
        ' The condition to copy is met when source file exists,
        ' and target file does not.
        
        For i = 1 To ubs
            
            ' Folders
            srcPath = Source(0)(i, 1)
            If Dir(srcPath, vbDirectory) = "" Then
                ' Source Folder and Source File do not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source Folder exists.
            tgtPath = Source(1)(i, 1)
            If Dir(tgtPath, vbDirectory) = "" Then
                ' Target Folder and Target File do not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source Folder and Target Folder exist.
            
            ' Files
            srcPath = srcPath & PathDelimiter & Source(2)(i, 1)
            If Dir(srcPath) = "" Then
                ' Source File does not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source File exists.
            tgtPath = tgtPath & PathDelimiter & Source(3)(i, 1)
            If Dir(tgtPath) <> "" Then
                ' Target File exists.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(2)
                GoTo NextRow
            End If
            ' Source File exists and Target File does not.
            Target(0)(i, 1) = filMsg(1)
            Target(1)(i, 1) = folMsg(1)
            
            ' Copy
            FileCopy srcPath, tgtPath
            ' Count files copied.
            Copied = Copied + 1
             
    NextRow:
        Next i
        
        ' Write values (results) from arrays of Target Jagged Array
        ' to Target Columns.
        For j = 0 To ubcT
            writeOffsetRange Target(j), tgtCols(j), rng
        Next j
    
        ' Inform user.
        MsgBox "Copied " & Copied & " files.", vbInformation, "Success"
    
    ProcExit:
        Exit Sub
    
    FirstRowBelowLastRow:
        Debug.Print "'" & ProcName & "': First row below last row."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
        
    End Sub
    
    Sub getOffsetColumn(ByRef Data As Variant, _
                        OffsetColumnIndex As Variant, _
                        ColumnRange As Range)
        
        ' Initialize error handling.
        Const ProcName As String = "getOffsetColumn"
        On Error GoTo clearError ' Turn on error trapping.
        
        Data = Empty
        If ColumnRange Is Nothing Then
            GoTo NoRange
        End If
        
        Dim ws As Worksheet
        Set ws = ColumnRange.Worksheet
        
        If ColumnRange.Rows.Count > 1 Then
            Data = ColumnRange.Offset(, ws.Columns(OffsetColumnIndex).Column _
                                      - ColumnRange.Column) _
                              .Value
        Else
            ReDim Data(1 To 1, 1 To 1)
            Data(1, 1) = ColumnRange.Offset(, ws.Columns(OffsetColumnIndex) _
                                                .Column _
                                            - ColumnRange.Column) _
                                    .Value
        End If
    
    ProcExit:
        Exit Sub
    
    NoRange:
        Debug.Print "'" & ProcName & "': No Range."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
    
    End Sub
    
    Sub writeOffsetRange(Data As Variant, _
                         OffsetColumnIndex As Variant, _
                         ColumnRange As Range)
        
        ' Initialize error handling.
        Const ProcName As String = "writeOffsetColumn"
        On Error GoTo clearError ' Turn on error trapping.
        
        If ColumnRange Is Nothing Then
            GoTo NoRange
        End If
        
        Dim ws As Worksheet
        Set ws = ColumnRange.Worksheet
        
        ColumnRange.Offset(, ws.Columns(OffsetColumnIndex).Column _
                           - ColumnRange.Column).Value = Data
    
    ProcExit:
        Exit Sub
    
    NoRange:
        Debug.Print "'" & ProcName & "': No Range."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
    
    End Sub
    

    您可以使用
    Dir(fullPathHere)
    检查文件是否存在。首先,您好,这是一项非常了不起的工作。你的详细解决方案让我大吃一惊。我已经按照新Excel文件中的指示运行了测试。从一列一列开始。文件/文件夹消息写入指定列,但无法正常工作或按预期工作。运行完整的测试集,从A列中添加数据开始,然后重新运行B列、C列,最后运行D列。不确定如何上传excel文件以显示我正在测试的内容??我忘了提到路径不应该有尾随的反斜杠\现在我发现我混淆了这些列(我认为
    文件夹,文件夹,文件,文件
    ):用
    “A”,“B”,“C”,“D”代替
    “A”,“C”,“B”,“D”
    ,效果很好。不能发布文件或屏幕转储(对本论坛来说太新)A=C:\temp3\Source,B=C:\temp3\Destination,C=1.txt,D=10.txt结果通过,E Copy=Success&F Source Exists=TRUE。再次运行测试,一切正常-Copy=Fail,SourceFile=duplicate它在下一行失败,其中:A=C:\temp3\Source\Original1,B=C:\temp3\Destination\01,C=3.txt,D=12.txt-Copy=Fail&Source=FAl这意味着文件夹
    C:\temp3\Source\Original1
    不存在,因为
    Source=FALSE
    。如果文件夹存在且
    12.txt
    存在,则它将是
    Source=replicate
    Option Explicit
    
    Sub copyRenameFile()
    
        ' Initialize error handling.
        Const ProcName As String = "copyRenameFile"
        On Error GoTo clearError ' Turn on error trapping.
        
        ' Worksheet
        Const wsName As String = "Sheet1"        ' Worksheet Name
        Const FirstRow As Long = 2               ' First Row Number
        Const LastRowCol As Variant = "A"        ' Last Row Column Index
        Dim srcCols As Variant                   ' Source Columns Array
        srcCols = VBA.Array("A", "B", "C", "D")
        Dim tgtCols As Variant                   ' Target Columns Array
        tgtCols = VBA.Array("E", "F")
        
        ' Other
        Dim filMsg() As Variant                  ' File Messages
        filMsg = VBA.Array("Fail", "Success")
        Dim folMsg() As Variant                  ' Folder Messages
        folMsg = VBA.Array(False, True, "Duplicate")
        Dim PathDelimiter As String
        PathDelimiter = Application.PathSeparator
        Dim wb As Workbook
        Set wb = ThisWorkbook ' 'Thisworkbook' is the workbook containing this code.
        
        ' Define Last Row Column Range ('rng').
        Dim ws As Worksheet
        Set ws = wb.Worksheets(wsName)
        Dim LastRow As Long
        LastRow = ws.Cells(ws.Rows.Count, LastRowCol).End(xlUp).Row
        If LastRow < FirstRow Then
            GoTo FirstRowBelowLastRow
        End If
        Dim rng As Range
        Set rng = ws.Range(ws.Cells(FirstRow, LastRowCol), _
                           ws.Cells(LastRow, LastRowCol))
         
        ' Write Source Column Ranges to Source Jagged Array ('Source').
        Dim ubcS As Long
        ubcS = UBound(srcCols)
        Dim Source As Variant
        ReDim Source(0 To ubcS)
        Dim Data As Variant
        Dim j As Long
        For j = 0 To ubcS
            getOffsetColumn Data, srcCols(j), rng
            Source(j) = Data
        Next j
        
        ' Define Target Jagged Array ('Target').
        Dim ubcT As Long
        ubcT = UBound(tgtCols)
        Dim ubs As Long
        ubs = UBound(Source(0))
        Dim Target As Variant
        ReDim Target(0 To ubcT)
        ReDim Data(1 To ubs, 1 To 1)
        For j = 0 To ubcT
            Target(j) = Data
        Next j
        
        ' Declare additional variables for the For Next loop.
        Dim i As Long
        Dim Copied As Long
        Dim srcPath As String
        Dim tgtPath As String
        
        ' Loop through rows of arrays of Source Jagged Array, check folders,
        ' check files and finally copy if condition is met. At the same time
        ' write results to arrays of Target Jagged Array.
        ' The condition to copy is met when source file exists,
        ' and target file does not.
        
        For i = 1 To ubs
            
            ' Folders
            srcPath = Source(0)(i, 1)
            If Dir(srcPath, vbDirectory) = "" Then
                ' Source Folder and Source File do not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source Folder exists.
            tgtPath = Source(1)(i, 1)
            If Dir(tgtPath, vbDirectory) = "" Then
                ' Target Folder and Target File do not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source Folder and Target Folder exist.
            
            ' Files
            srcPath = srcPath & PathDelimiter & Source(2)(i, 1)
            If Dir(srcPath) = "" Then
                ' Source File does not exist.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(0)
                GoTo NextRow
            End If
            ' Source File exists.
            tgtPath = tgtPath & PathDelimiter & Source(3)(i, 1)
            If Dir(tgtPath) <> "" Then
                ' Target File exists.
                Target(0)(i, 1) = filMsg(0)
                Target(1)(i, 1) = folMsg(2)
                GoTo NextRow
            End If
            ' Source File exists and Target File does not.
            Target(0)(i, 1) = filMsg(1)
            Target(1)(i, 1) = folMsg(1)
            
            ' Copy
            FileCopy srcPath, tgtPath
            ' Count files copied.
            Copied = Copied + 1
             
    NextRow:
        Next i
        
        ' Write values (results) from arrays of Target Jagged Array
        ' to Target Columns.
        For j = 0 To ubcT
            writeOffsetRange Target(j), tgtCols(j), rng
        Next j
    
        ' Inform user.
        MsgBox "Copied " & Copied & " files.", vbInformation, "Success"
    
    ProcExit:
        Exit Sub
    
    FirstRowBelowLastRow:
        Debug.Print "'" & ProcName & "': First row below last row."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
        
    End Sub
    
    Sub getOffsetColumn(ByRef Data As Variant, _
                        OffsetColumnIndex As Variant, _
                        ColumnRange As Range)
        
        ' Initialize error handling.
        Const ProcName As String = "getOffsetColumn"
        On Error GoTo clearError ' Turn on error trapping.
        
        Data = Empty
        If ColumnRange Is Nothing Then
            GoTo NoRange
        End If
        
        Dim ws As Worksheet
        Set ws = ColumnRange.Worksheet
        
        If ColumnRange.Rows.Count > 1 Then
            Data = ColumnRange.Offset(, ws.Columns(OffsetColumnIndex).Column _
                                      - ColumnRange.Column) _
                              .Value
        Else
            ReDim Data(1 To 1, 1 To 1)
            Data(1, 1) = ColumnRange.Offset(, ws.Columns(OffsetColumnIndex) _
                                                .Column _
                                            - ColumnRange.Column) _
                                    .Value
        End If
    
    ProcExit:
        Exit Sub
    
    NoRange:
        Debug.Print "'" & ProcName & "': No Range."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
    
    End Sub
    
    Sub writeOffsetRange(Data As Variant, _
                         OffsetColumnIndex As Variant, _
                         ColumnRange As Range)
        
        ' Initialize error handling.
        Const ProcName As String = "writeOffsetColumn"
        On Error GoTo clearError ' Turn on error trapping.
        
        If ColumnRange Is Nothing Then
            GoTo NoRange
        End If
        
        Dim ws As Worksheet
        Set ws = ColumnRange.Worksheet
        
        ColumnRange.Offset(, ws.Columns(OffsetColumnIndex).Column _
                           - ColumnRange.Column).Value = Data
    
    ProcExit:
        Exit Sub
    
    NoRange:
        Debug.Print "'" & ProcName & "': No Range."
        GoTo ProcExit
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
    
    End Sub
    
    ' e.g. "C:\Test" is an existing folder, "C:\Test\Test1" is not.
    ' When you want to create the folder "C:\Test\Test1\Test2", 'MkDir' will return
    ' "Run-time error '76': Path Not found", because "C:\Test\Test1" does not exist.
    ' The 'createFolders' function remedies this by creating as many folders
    ' as needed. In the previous example it first creates "C:\Test\Test1" and
    ' only then creates "C:\Test\Test1\Test2" in it.
    ' The function returns 'True' if the folder previously existed or now exists.
    ' The function returns 'False' if 'PathString' is invalid.
    Function createFolders(PathString As String) As Boolean
        
        ' Initialize error handling.
        Const ProcName As String = "createFolders"
        On Error GoTo clearError ' Turn on error trapping.
    
        ' Split Path String ('PathString') by System Path Separator ('Delimiter')
        ' into 1D zero-based Folders Array 'Folders()'.
        Dim Delimiter As String
        Delimiter = Application.PathSeparator
        Dim Folders() As String
        Folders = Split(PathString, Delimiter)
        
        ' Define Last Subscript ('LastSS') to be considered, because Path String
        ' could be ending with a System Path Separator.
        Dim LastSS As Long
        LastSS = UBound(Folders)
        If Folders(LastSS) = "" Then
            LastSS = LastSS - 1
        End If
        
        ' Using Folders Array, write paths to Paths Array ('Paths()').
        Dim Paths() As String
        ReDim Paths(0 To LastSS)
        Paths(0) = Folders(0)
        Dim j As Long
        If LastSS > 0 Then
            For j = 1 To LastSS
                Paths(j) = Paths(j - 1) & Delimiter & Folders(j)
            Next j
        End If
        
        ' Create each folder if it does not exist.
        For j = 0 To LastSS
            If Dir(Paths(j), vbDirectory) = "" Then
                MkDir Paths(j)
            End If
        Next j
        
        ' Write result.
        createFolders = True
        
    ProcExit:
        Exit Function
    
    clearError:
        Debug.Print "'" & ProcName & "': " & vbLf _
                  & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
                  & "        " & Err.Description
        On Error GoTo 0 ' Turn off error trapping.
        GoTo ProcExit
        
    End Function
    
    Sub testCreateFolders()
        Const PathString As String = "C:\Test\Test1\Test2"
        Dim Result As Boolean
        Result = createFolders(PathString)
        If Result Then
            MsgBox "If the path previously didn't exist, now it certainly does."
        Else
            MsgBox "The supplied path is invalid."
        End If
    End Sub
    
    Sub testMkDir()
        Const PathString As String = "C:\Test\Test1\Test2"
        MkDir PathString
    End Sub