У меня есть приведенный ниже код, в котором перечислены все имена файлов (без расширения файла), а также размеры изображений — не поймите меня неправильно, он работает, но для перечисления имен файлов и размеров для 1100 изображений в формате PNG требуется пара часов. . Мне просто интересно, есть ли более быстрый способ сделать это? Честно говоря, я не знаю, как это сделать.
Sub Get_Properties_Men()
Dim sFile As Variant
Dim oShell As Object, oDir As Object
Dim i As Long
Set oShell = CreateObject("Shell.Application")
Set oDir = oShell.Namespace("W:\Gegenpress Graphics\-- Crests Master\Clubs")
i = 4
For Each sFile In oDir.Items
Cells(i, 1).Value = sFile.Name
Cells(i, 2).Value = sFile.ExtendedProperty("Dimensions")
i = i + 1
Next
Set oShell = CreateObject("Shell.Application")
Set oDir = oShell.Namespace("W:\Gegenpress Graphics\-- Crests Master\Competitions")
i = 4
For Each sFile In oDir.Items
Cells(i, 4).Value = sFile.Name
Cells(i, 5).Value = sFile.ExtendedProperty("Dimensions")
i = i + 1
Next
MsgBox "Men's crests and competitions added."
End Sub
@TimWilliams это подключенный сетевой диск.
Если вы (например) скопируете половину файлов на локальный диск, сколько времени потребуется на обработку только этих файлов?
Есть ли у вас какой-либо дополнительный код для изменения настроек системы, чтобы она работала быстрее, например отключения обновления экрана? Компьютеры тратят много энергии на пересчеты и другие действия в фоновом режиме, если им не говорят, что они могут временно избегать этих действий.
Я запустил ваш код в локальной папке (диск C), содержащей около 500 файлов, и он завершился чуть более чем за 4 секунды. Таким образом, ваша проблема, скорее всего, связана с используемым вами диском, а не с чем-то конкретным, связанным с самим VBA.
Да, я скопировал на локальный диск, и это произошло очень быстро. Есть ли способ оптимизировать работу с подключенным Google Диском?
Я не использую Google Диск, но, может быть, есть настройка для локального хранения синхронизированных файлов?
Похоже, вам нужна опция «зеркалирование», а не «потоковая передача» — support.google.com/drive/answer/…
Я снова прочитал ваш вопрос и вижу (теперь), что дело не в диске Google, а только в подключенном сетевом диске, поскольку меня вдохновили приведенные выше комментарии... Я протестировал опубликованный мной код на таком подключенном диске. (разумеется, в локальной сети) и ему нужно около одной-двух секунд, чтобы Set oDir
и тогда он почти мгновенно обрабатывает 100 файлов... Я думаю, 1к тоже должен обрабатываться за секунды. Возможно, ваша сеть не работает должным образом. Попробуйте проверить, какую скорость передачи данных показывает ваш компьютер при загрузке/загрузке (больших) файлов в соответствующую папку.
Очевидно, что ваша проблема связана со способом чтения папки с диска. Это должно быть вопросом скорости сетевого соединения, но есть две проблемы, которые соответственно улучшат эффективность кода:
Запись количества раз за каждую итерацию требует времени и ресурсов Excel. Таким образом, размещение возвращаемых значений в массивах и удаление их содержимого в конце сэкономит некоторое время.
Использование раннего связывания позволяет «компилятору выполнять важные оптимизации, которые обеспечивают более эффективные приложения. Объекты с ранним связыванием работают значительно быстрее, чем объекты с поздним связыванием, и делают ваш код более простым для чтения и обслуживания, точно указывая, какие объекты используются». Кроме того, вы также можете воспользоваться предложениями Intellisense... Посмотрите здесь, что заявляет Microsoft по этому вопросу.
А. Следующий фрагмент кода автоматически добавляет ссылку на «Элементы управления и автоматизацию Microsoft Shell»:
Private Sub addShell32Ref()
'Microsoft Shell Controls and Automation`...
On Error Resume Next
ThisWorkbook.VBProject.References.AddFromFile "C:\Windows\SysWOW64\Shell32.dll"
If err.number = 32813 Then
MsgBox "The reference already exists..."
Else
MsgBox "The reference added sucressfully..."
End If
On Error GoTo 0
End Sub
Б. Следующий адаптированный код использует два предложенных способа оптимизации скорости:
Sub Get_Properties_Men()
'it needs a reference to 'Microsoft Shell Controls and Automation`...
Dim oShell As Shell32.shell, oDir As Shell32.Folder, sFile As Shell32.FolderItem
Dim i As Long, arr1, arr2
Set oShell = New Shell32.shell
Set oDir = oShell.NameSpace("W:\Gegenpress Graphics\-- Crests Master\Clubs")
ReDim arr1(1 To oDir.Items.count, 1 To 2) 'redim the array to keep the necessary data
i = 1
For Each sFile In oDir.Items
arr1(i, 1) = sFile.Name
arr1(i, 2) = sFile.ExtendedProperty("Dimensions")
i = i + 1
Next
'you can use the same oShell object:
Set oDir = oShell.NameSpace("W:\Gegenpress Graphics\-- Crests Master\Competitions")
ReDim arr2(1 To oDir.Items.count, 1 To 2)
i = 1
For Each sFile In oDir.Items
arr2(i, 1) = sFile.Name
arr2(i, 2) = sFile.ExtendedProperty("Dimensions")
i = i + 1
Next
'drop the loaded arrays content, at once:
Range("A4").Resize(UBound(arr1), UBound(arr1, 2)).Value = arr1
Range("D4").Resize(UBound(arr2), UBound(arr2, 2)).Value = arr2
MsgBox "Men's crests and competitions added."
End Sub
Не могу себе представить, насколько это увеличит скорость кода, но что-то наверняка даст...
Пожалуйста, оставьте отзыв после тестирования. Возможно, было бы полезно также сравнить возврат в случае, если файлы были перемещены локально. Я имею в виду, используя ваш существующий код и этот адаптированный...
Время поездки по карте сократилось с 2+ часов до примерно 22 минут! С локальными файлами время сократилось с 2 минут до 1 секунды.
@ffc2004 Рад, что смог помочь! Но попытаться понять, почему такая большая разница, полезно... Попробуйте сделать то, что я предложил в своем комментарии. Я имею в виду тестирование скорости передачи данных между вашим компьютером и соответствующим диском. Нужны ли вам учетные данные для подключения?
Какой тип привода W? Местный? Сеть?