Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


blackeangel, дык, я не настаиваю именно на словаре. Я просто пишу, что массивы в данном случае явно не лучший выбор. Почему — потому что вижу многомерные массивы вкупе со множественными ReDim и ReDim Preserve. Я бы ещё понял, если бы Вы пользовали одномерный массив из структур (Type Statement). Словарь — это, собственно, тот же массив, только ассоциативный. Вместо многомерного массива используется тот факт, что его элементами могут быть не только простые типы данных, но и другие, «вложенные», словари.

Цитата blackeangel:
Дальше, мы его будем делать двухмерным, по тем самым регуляркам, что тогда так долго пытали. »
Почему не сразу делать двумерным?

Цитата blackeangel:
Далее заполнять оставшиеся не заполненные 3 столбца напротив файлов, читая данные из файла и/или же из правил по вхождению имени файла. »
Почему не сразу заполнять?

В общем, вот такой Вам примерчик, с использованием простого и незатейливого средства — набора записей (RecordSet):
Скрытый текст
Код: Выделить весь код
Option Explicit

Sub Sample()
    Dim strSourceFolder As String
    Dim objFSO As New Scripting.FileSystemObject
    Dim objRecordset As New ADODB.Recordset
    Dim arrFoldersAndFiles As Variant
    
    Dim i As Integer, j As Integer
    
    
    strSourceFolder = "C:\test"
    
    If objFSO.FolderExists(strSourceFolder) Then
        With objRecordset
            With .Fields
                .Append "RelativePath", ADODB.adVarChar, 255
                .Append "Attributes1", ADODB.adVarChar, 10
                .Append "Attributes2", ADODB.adVarChar, 10
                .Append "Attributes3", ADODB.adVarChar, 10
            End With
            
            .Open
            .Sort = "RelativePath ASC"
            
            ScanSubFolders objFSO.GetFolder(strSourceFolder), Len(objFSO.GetParentFolderName(strSourceFolder)) + 1, objRecordset
            
            '.MoveFirst
            '
            'Do Until .EOF
            '    With .Fields
            '        Debug.Print .Item("RelativePath").Value, .Item("Attributes1").Value, .Item("Attributes2").Value, .Item("Attributes3").Value
            '    End With
            '
            '    .MoveNext
            'Loop
            
            .MoveFirst
            arrFoldersAndFiles = .GetRows()
            .Close
            
            For i = LBound(arrFoldersAndFiles, 1) To UBound(arrFoldersAndFiles, 1)
                For j = LBound(arrFoldersAndFiles, 2) To UBound(arrFoldersAndFiles, 2)
                    Debug.Print "arrFoldersAndFiles("; i; ";"; j; ")="; arrFoldersAndFiles(i, j)
                Next j
            Next i
        End With
    Else
        Debug.Print "Can't find source folder [" & strSourceFolder & "]."
    End If
End Sub

Sub ScanSubFolders(objFolder As Scripting.Folder, intTruncateTo As Integer, objRecordset As ADODB.Recordset)
    Dim objFile As Scripting.File
    Dim objSubFolder As Scripting.Folder
    
    'Debug.Print Replace(Mid(objFolder.Path, intTruncateTo), "\", "/") & " 0 0 0755"
    objRecordset.AddNew Array("RelativePath", "Attributes1", "Attributes2", "Attributes3"), Array(Replace(Mid(objFolder.Path, intTruncateTo), "\", "/"), "0", "0", "0755")
    
    For Each objFile In objFolder.Files
        'Debug.Print Replace(Mid(objFile.Path, intTruncateTo), "\", "/")
        objRecordset.AddNew Array("RelativePath"), Array(Replace(Mid(objFile.Path, intTruncateTo), "\", "/"))
    Next objFile
    
    For Each objSubFolder In objFolder.SubFolders
        ScanSubFolders objSubFolder, intTruncateTo, objRecordset
    Next objSubFolder
End Sub

Конечным итогом будет, как Вы и просили, двумерный массив arrFoldersAndFiles. В свойствах проекта необходимо добавить ссылку на Microsoft ActiveX Data Objects Library (их может быть несколько, выбирайте не ниже 2.8, выше — можно).


Использование словарей/ассоциативных массивов или наборов записей (RecordSet) уместно там, где нам заранее неизвестен конечный размер данных, потому как в этих случаях мы можем легко и произвольно его наращивать (в отличие от обычного массива, который требует предварительного указания точного размера).

Цитата blackeangel:
И где по-человечески дано определение ключа. Я вот этого не понимаю. »
Человеческим языком это рассказано здесь: Dictionary.

Главный недостаток класса Scripting.Dictionary — в нём в принципе нет возможности обратиться к элементу коллекции по порядковому номеру. Позже, когда Microsoft делала .Net, в нём это было исправлено, и класс .Net System.Collections.ArrayList (ArrayList Class (System.Collections)) получил такую возможность. Кстати, данный класс может также использоваться не только как класс .Net, но и ограниченно — как объект Automation (может потребоваться принудительная регистрация его библиотеки), со всеми его приятственными плюшками. Например: VBScript Scripting Techniques: ArrayLists.

Отправлено: 07:33, 01-03-2017 | #14