Код VBA для вывода списка всех файлов в папке, а также размеров изображения

У меня есть приведенный ниже код, в котором перечислены все имена файлов (без расширения файла), а также размеры изображений — не поймите меня неправильно, он работает, но для перечисления имен файлов и размеров для 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

Какой тип привода W? Местный? Сеть?

Tim Williams 30.07.2024 17:42

@TimWilliams это подключенный сетевой диск.

ffc2004 30.07.2024 17:43

Если вы (например) скопируете половину файлов на локальный диск, сколько времени потребуется на обработку только этих файлов?

Tim Williams 30.07.2024 17:48

Есть ли у вас какой-либо дополнительный код для изменения настроек системы, чтобы она работала быстрее, например отключения обновления экрана? Компьютеры тратят много энергии на пересчеты и другие действия в фоновом режиме, если им не говорят, что они могут временно избегать этих действий.

Mark S. 30.07.2024 18:01

Я запустил ваш код в локальной папке (диск C), содержащей около 500 файлов, и он завершился чуть более чем за 4 секунды. Таким образом, ваша проблема, скорее всего, связана с используемым вами диском, а не с чем-то конкретным, связанным с самим VBA.

Tim Williams 30.07.2024 18:09

Да, я скопировал на локальный диск, и это произошло очень быстро. Есть ли способ оптимизировать работу с подключенным Google Диском?

ffc2004 30.07.2024 18:52

Я не использую Google Диск, но, может быть, есть настройка для локального хранения синхронизированных файлов?

Tim Williams 30.07.2024 19:34

Похоже, вам нужна опция «зеркалирование», а не «потоковая передача» — support.google.com/drive/answer/…

Tim Williams 30.07.2024 23:13

Я снова прочитал ваш вопрос и вижу (теперь), что дело не в диске Google, а только в подключенном сетевом диске, поскольку меня вдохновили приведенные выше комментарии... Я протестировал опубликованный мной код на таком подключенном диске. (разумеется, в локальной сети) и ему нужно около одной-двух секунд, чтобы Set oDir и тогда он почти мгновенно обрабатывает 100 файлов... Я думаю, 1к тоже должен обрабатываться за секунды. Возможно, ваша сеть не работает должным образом. Попробуйте проверить, какую скорость передачи данных показывает ваш компьютер при загрузке/загрузке (больших) файлов в соответствующую папку.

FaneDuru 31.07.2024 12:32
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
9
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Очевидно, что ваша проблема связана со способом чтения папки с диска. Это должно быть вопросом скорости сетевого соединения, но есть две проблемы, которые соответственно улучшат эффективность кода:

  1. Запись количества раз за каждую итерацию требует времени и ресурсов Excel. Таким образом, размещение возвращаемых значений в массивах и удаление их содержимого в конце сэкономит некоторое время.

  2. Использование раннего связывания позволяет «компилятору выполнять важные оптимизации, которые обеспечивают более эффективные приложения. Объекты с ранним связыванием работают значительно быстрее, чем объекты с поздним связыванием, и делают ваш код более простым для чтения и обслуживания, точно указывая, какие объекты используются». Кроме того, вы также можете воспользоваться предложениями 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 31.07.2024 12:39

@ffc2004 Рад, что смог помочь! Но попытаться понять, почему такая большая разница, полезно... Попробуйте сделать то, что я предложил в своем комментарии. Я имею в виду тестирование скорости передачи данных между вашим компьютером и соответствующим диском. Нужны ли вам учетные данные для подключения?

FaneDuru 31.07.2024 12:52

Другие вопросы по теме