Приведенная ниже функция формирует отсортированный список файлов или вложенных папок согласно указанного шаблона. Здесь применяется метод быстрой сортировки. Новое значение сравнивается со значением из середины диапазона, затем одна половина диапазона исключается и цикл повторяется. Когда новое значение становится меньше первого или больше последнего в интервале, оно добавляется в семейство.
Объест Collection объявляется как Dim col As New Collection. Использование New в данном случае обязательно.
В вызывающей процедуре можно применить 2 варианта: Dim col As New Collection Здесь col - пустое семейство. Set col = GetFilesList(......) или Dim col As Collection Здесь col - пустая ссылка на семейство. Set col = GetFilesList(......) Во втором варианте переменная может быть в состоянии Nothing, и обращение к свойству Count или любому методу семейства сгенерирует ошибку. Специалисты настоятельно советуют использовать первый вариант всегда. Другие возможности Collection: Можно использовать конструкцию For Each ..... Next. При добавлении нового элемента можно указать уникальный строковый ключ и затем использовать его при обращении к элементу. Например: col.Add 100, "New" MsgBox col("New") ( или col!New ) col.Remove "New" К сожалению, прочитать значение ключа нельзя. Function GetFilesList(Optional PathName As String, _ Optional FoldersOnly As Boolean) As Collection ' Функция возвращает отсортированное семейство имен файлов или 'вложенных папок (если установлен FoldersOnly). ' Аргумент PathName может принимать значение, распознаваемое 'функцией Dir(). On Error GoTo GetFilesList_err Dim col As New Collection Dim strFileName As String, strCompareFileName As String, _ i As Integer, j As Integer, MidPos As Integer
If FoldersOnly Then strFileName = Dir$(PathName, vbDirectory) Else strFileName = Dir$(PathName) End If
Do Until Len(strFileName) = 0 ' В режиме поиска вложенных папок игнорирует папки ".",".." и
'файлы. If FoldersOnly Then 'Если первый символ - "."(код 46), игнорируется. If Asc(strFileName) = 46 Then GoTo NextFile 'Если отсутствует аттрибут vbDirectory, игнорируется. If Not (GetAttr(PathName & strFileName) And vbDirectory) = _ vbDirectory Then GoTo NextFile End If
i = 1 j = col.Count 'Если коллекция пуста - добавляет значение. If j = 0 Then col.Add strFileName GoTo NextFile End If
SearchBlock: ' Вычисляется средний индекс в диапазоне и извлекается 'соответствующее значение. MidPos = (i + j) 2 strCompareFileName = col(MidPos)
' Имя нового файла сравнивается с текущим значением. Select Case StrComp(strFileName, strCompareFileName, _ vbTextCompare) Case -1 'strFileName < strCompareFileName 'Новое значение меньше текущего. If MidPos <= i Then ' Если текущий индекс совпадает с начальным(< - для надежности), 'добавляется перед первым значением в диапазоне. col.Add strFileName, , i Else 'Диапазон ограничивается первой половиной и цикл повторяется. j = MidPos - 1 GoTo SearchBlock End If
Case 1 'strFileName > strCompareFileName 'Новое значение больше текущего. If MidPos >= j Then ' Если текущий индекс совпадает с конечным(> - для надежности), 'добавляется после конечного значения в диапазоне. col.Add strFileName, , , j Else 'Диапазон ограничивается второй половиной и цикл повторяется. i = MidPos + 1 GoTo SearchBlock End If
' Case 0 strFileName = strCompareFileName End Select NextFile: strFileName = Dir$(, vbDirectory) Loop
Set GetFilesList = col
GetFilesList_exit: Exit Function
GetFilesList_err: Select Case Err.Number Case 52 MsgBox "Путь к файлу(папке) указан неправильно.", vbCritical Case 68 MsgBox "Устройство недоступно.", vbCritical Case 76 MsgBox "Путь не найден.", vbCritical Case Else MsgBox Err & " - " & Err.Description, vbCritical, _ "GetFilesList" End Select Resume GetFilesList_exit End Function |