Microsoft Developer Network > Программирование в Microsoft Visual Basic > Office/VBA

Совет 367. Поиск файлов с помощью объекта FileSearch

Задача поиска файлов по некоторым критериям встречается довольно часто. Например, вам нужно найти самый последний измененный файл в некотором каталоге. Для этого можно написать достаточно простой код с использованием функции Dir, с помощью которой делается выборка всех файлов по заданному шаблону:

Листинг 1.

' поиск самого последнего модифицированного файла
Dim FileName$, LastFile$, ThisDate As Date, LastDate As Date
Dim PathName$, Template$

PathName = "c:\" ' поиск в корневом каталоге C:
Template = PathName & "*.*" ' все файлы
FileName = Dir(Template) ' инициализация
LastDate = #1/1/80#
' просмотр файлов в заданном каталоге
Do While FileName <> ""
  ThisDate = FileDateTime(PathName & FileName) ' дата и время
  ' поиск макс. даты (последней)
  If ThisDate > LastDate Then ' нашли более поздний
    LastDate = ThisDate
    LastFile = PathName & FileName
  End If
  FileName = Dir ' выборка следующего
Loop
If LastFile <> "" Then 'что-то найдено
  MsgBox "Последний по дате файл по шаблону " & _
         Template & vbCrLf & _
         "Имя файла = " & LastFile & vbCrLf & _
         "Дата коррекции = " & LastDate
Else
  MsgBox "Вообще нет файлов с шаблоном " & Template
End If

Однако если помимо этого потребуется поиск в подкаталогах, то придется дополнительно сделать их выборку, используя рекурсивные конструкции. В принципе, это не очень сложно (см. совет 230), но все же требует дополнительных усилий и некоторого опыта программирования. Тогда как в среде Office/VBA проблема может быть решена гораздо проще — путем использования объекта FindSearch. Так, например, следующий код позволяет найти все файлы, содержащиеся в каталоге D:\TMP и во всех вложенных подкаталогах:

Листинг 2.

With Application.FileSearch 
  .LookIn = "d:\tmp"  
  .SearchSubFolders = True  
  .FileType = msoFileTypeAllFiles  
  If .Execute  > 0 Then  
    MsgBox "Число найденных файлов = " & .FoundFiles.Count  
    ' вывод имен файлов  
    For i = 1 To .FoundFiles.Count  
      MsgBox .FoundFiles(i)  
    Next i  
  Else  
    MsgBox "Не найдено подходящих файлов"  
  End If  
End With

Здесь существуют богатые возможности управления режимами выборки, в том числе с поиском по контексту, датам последней модификации и пр. Очень удобно, что имена найденных файлов (свойство FoundFiles) выдаются в виде полных имен. Очевидно, что после получения списка файлов можно выполнить более «тонкую» выборку, например с более жесткими ограничениями по интервалам даты или размера.

Все это можно использовать в обычном VB (или в других системах программирования, поддерживающих ActiveX), подключив библиотеку Microsoft Word 8.0/9.0 Object Library.

Более того, метод Execute позволяет получить список файлов, отсортированный по реквизитам файлов: именам, типам, дате последней модификации и размеру. Так что найти последний измененный файл можно очень просто:

Листинг 3.

With Application.FileSearch
  .LookIn = "d:\tmp"  
  .SearchSubFolders = True  
  .FileType = msoFileTypeAllFiles  
  If .Execute(SortBy:=msoSortByLastModified, _  
      SortOrder:=msoSortOrderDescending) > 0 Then  
    MsgBox "Последний измененный файл = " & .FoundFiles(i)  
  End If

Однако тестирование показало, что в Word 2000 сортировка именно по дате модификации почему-то не работает. Но дальнейшие исследования выявили, что она начинает работать (!) после выполнения поиска с сортировкой по размеру файлов. Такой вариант работает корректно:

Листинг 4.

With Application.FileSearch
  .LookIn = "d:\tmp"  
  .SearchSubFolders = True  
  .FileType = msoFileTypeAllFiles  
  .Execute(SortBy:=msoSortBySize)  ' фиктивная выборка, чтобы  
                                   ' работала следующая строка кода  
  If .Execute(SortBy:=msoSortByLastModified, _  
      SortOrder:=msoSortOrderDescending) > 0 Then  
    MsgBox "Последний измененный файл = " & .FoundFiles(i)  
  End If  
End With