简体   繁体   English

目录之间的Excel VBA宏文件复制

[英]Excel VBA Macro file copy between directories

I need some help trying to make this code run more quickly. 我需要一些帮助,以使此代码更快地运行。 Presently it runs like molasses, far too slow to be practical. 目前,它像糖蜜一样运转,太慢而不能实际应用。

This program is intended to compare each file in a directory of files against a list of file names. 该程序旨在将文件目录中的每个文件与文件名列表进行比较。 The files are listed in sub-directories according to the date they were generated, so a typical file path might look like >16>06>27>example.wav. 这些文件根据生成日期在子目录中列出,因此典型的文件路径可能类似于> 16> 06> 27> example.wav。 The list of file names I need to copy into another directory is located in Sheet1, column R. 我需要复制到另一个目录中的文件名列表位于Sheet1的R列中。

I started this project in Excel 2010 and upgraded to the 64 bit version of Excel 2016 in order to take advantage of the expanded virtual memory cap in that version of Office but it's still running VERY slowly and crashing before the program runs to completion. 我在Excel 2010中启动了该项目,并升级到了64位版本的Excel 2016,以利用该版本Office中扩展的虚拟内存容量,但是它仍然运行非常缓慢,并且在程序运行完成之前崩溃。

Both the folder where the files are stored and the folder I'm copying them to are on a network drive, stored in the office's server. 文件存储所在的文件夹和我要将它们复制到的文件夹都位于网络驱动器上,存储在办公室的服务器中。 Is that causing the issue? 那是问题所在吗? Am I doing something wrong with the code? 我的代码有问题吗? I can't imagine a computer with the power under the hood that mine has is encountering problems with a couple nested For loops and a binary search. 我无法想象一台拥有强大功能的计算机遇到了嵌套嵌套的For循环和二进制搜索的问题。

Sub CopyFile()
Application.Calculation = xlCalculationManual 'trying to speed things up.
ActiveSheet.DisplayPageBreaks = False

'This code takes the directory where the files are stored from the Active worksheet Range B3 and the goal directory where the copies are to be stored from Range G3
'It then lists all of the subdirectories (months) of the year we start with in column B,
'all of the days of that month in Column C and all the files in a given day in column D.

'List all the months in Column B
ListFilesinFolder ("B") 'lists the months in the year directory

With ActiveSheet
For i = 6 To Range("B6", Range("B6").End(xlDown)).Rows.Count + 5
    Range("B3") = Range("B3") & Range("B" & i) & "\" 'Add the month to the folder name
    ListFilesinFolder ("C") 'List all of the days in the month in Column C

    For x = 6 To Range("C6", Range("C6").End(xlDown)).Rows.Count + 5

        Range("B3") = Range("B3") & Range("C" & x) & "\" 'Add the day to the folder name
        ListFilesinFolder ("D") 'List all of the files in column D

        For y = Range("D6", Range("D6").End(xlDown)).Rows.Count + 5 To 6 Step -1

            binarySearch (y) 'Search for the filename against our list of potential filenames in Sheet1 column R

        Next y

        Range("D6", Range("D6").End(xlDown)).ClearContents
        Range("B3") = Left(Range("B3"), 23) 'Get the folder name in B3 back to year and month

    Next x

    Range("C6", Range("C6").End(xlDown)).ClearContents
    Range("B3") = Left(Range("B3"), 20) 'Get the folder name in B3 back to just the year
Next i
End With

Application.Calculation = xlCalculationAutomatic

End Sub

Sub ListFilesinFolder(ColName As String) 'lists all the files or sub-directories in a folder in the column passed to this function.
    Dim Value As String
    Dim strt As Range
    Set strt = Range(ColName & "6")
    Value = Dir(Range("B3"), &H1F)
    Do Until Value = ""
    If Value <> "." And Value <> ".." Then
        strt = Value
        Set strt = strt.Offset(1, 0)
    End If
    Value = Dir
    Loop
End Sub

Sub binarySearch(index As Long)
Dim low As Double
Dim mid As Long
Dim high As Double
Dim sheetNotesInfo As Worksheet
Dim src As String, dst As String, fl As String

'Source directory
src = Range("B3")
'Destination directory
dst = Range("G3")
'File name
fl = Range("B6")

'sheet with potential file names
Set sheetNotesInfo = ActiveWorkbook.Sheets("Sheet1")

low = 2
high = sheetNotesInfo.UsedRange.Rows.Count

            Do While (low <= high)

                mid = (low + high) / 2

                If (sheetNotesInfo.Range("R" & mid) > Left(Range("D" & index), 19)) Then
                    high = mid - 1

                ElseIf (sheetNotesInfo.Range("R" & mid) < Left(Range("D" & index), 19)) Then
                    low = mid + 1

                Else 'found
                src = Range("B3") 'setting the source of the file to be the source folder
                fl = Range("D" & index) 'setting the filename to be the filename we are currently inspecting

                On Error Resume Next
                    FileCopy src & "\" & fl, dst & "\" & fl
                    If Err.Number <> 0 Then
                    End If
                On Error GoTo 0
                low = 1
                high = -1
                End If
            Loop

End Sub

I think I figured it out. 我想我知道了。 I at least got it working. 我至少能正常工作。

The issue was looping to Range("ExampleRange", Range("ExampleRange").End(xlDown)).Rows.Count in cases where there were no contents in that column. 问题是循环到Range("ExampleRange", Range("ExampleRange").End(xlDown)).Rows.Count ,以防止该列中没有内容。 In cases where there were no contents in the column the index of my for loop was getting set to... for example, "1048576" and then looping down to 6 and running a binary search on every blank cell between. 如果列中没有内容,则将for循环的索引设置为...,例如“ 1048576”,然后循环至6,并在其间的每个空白单元格上运行二进制搜索。

So yeah. 是的。 Loooots of wasted time running loops and calculations that were completely useless. 浪费大量的时间运行循环和计算完全没有用。 Improper debugging on my part. 我的调试不当。

I fixed it with a simple If statement checking if the first cell in the column had anything in it and, if not, exiting that For loop. 我用一个简单的If语句修复了该错误,该语句检查列中的第一个单元格是否包含任何内容,如果没有,则退出该For循环。

If Not Range("ExampleRange") = "" Then

   binarySearch (y) 'Search for the filename against our list of potential filenames in Sheet1 column R

Else

   Exit For

End If

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM