1 (изменено: wildwolf007, 2014-01-30 15:52:03)

Тема: WSH:Рекурсивный вывод файлов в папке.

Есть папка в которую поступают файлики в разные директории на диске "D:\". (В момент поступления создается своя определенная по названию директория).

Конечная задача:
Нужно рекурсивно пройтись по всем папкам директории "D:\" и считать все имена файлов.
После чего все найденное поместить в трехмерный массив i, j, k, или может использовать Dictionary где
i - это полный путь папки.
j - имя файлов.
k - дата создания папки в которой находится файл.
Так же необходимо потом будет все данные массива сортировать по дате поступления (создания папки). 


Теперь в чем у меня трудность:

1) Накидал пару строк где я перебираю содержимое директории "D:\", но не могу понять как сделать так что б начать рекурсивно перебирать все папки в данной директории?
Думал использовать if, но уровень сложений тогда придется статически описывать, что не есть правильно.

2) Занесение данных в трехмерный массив не составит труда.
3) А вот как отсортировать массив по дате создания папки тоже пока вопрос.


On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\" 
If fso.FolderExists (startFolder) Then Start startFolder

Function Start(folderName)
    Dim folder, file, fileCollection, folderCollection, subFolder    
    Set folder = fso.GetFolder(folderName)
    Set folderCollection = folder.SubFolders
    For Each subFolder In folderCollection
        MsgBox subFolder.Path
        Next
    Set fileCollection = folder.Files   
    For Each file In fileCollection
        MsgBox file.Path
        Next 
    
End Function

рекурсию по папкам кажется можно реализовать вот так:

AllDir = "D:\1"                     

OutStr = AllDir + vbCrLf
OutStr = OutStr + AllFolders(AllDir)

MsgBox OutStr

Function AllFolders(WDir)
'   MsgBox WDir
    Rezult = ""
    Set F = CreateObject("Scripting.FileSystemObject").GetFolder(WDir)
    Set SubF = F.SubFolders

    For Each Folder In SubF
        Rezult = Rezult + WDir + "\" + Folder.Name + vbCrLf
        Rezult = Rezult + AllFolders(WDir + "\" + Folder.Name)
    Next

    AllFolders = Rezult
End Function

2 (изменено: wildwolf007, 2014-01-30 16:19:22)

Re: WSH:Рекурсивный вывод файлов в папке.

Сделал вот так еще не знаю насколько правильно пока летят ошибки:

'On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\" 
If fso.FolderExists (startFolder) Then Start startFolder

Function Start(folderName)
MsgBox folderName
    Dim folder, file, fileCollection, folderCollection, subFolder
'MsgBox "1"    & fso.GetFolder(folderName) 
    Set folder = fso.GetFolder(folderName)

    Set folderCollection = folder.subFolders
    For Each subFolder In folderCollection
        MsgBox subFolder.Path
        Set fileCollection = subFolder.Files   
        For Each file In fileCollection
            MsgBox file.Path
            Next 
        Next
   
End Function

3

Re: WSH:Рекурсивный вывод файлов в папке.

Нужно рекурсивно пройтись по всем папкам директории "D:\"…

Сколько же ещё будет подниматься этот вопрос?

http://forum.script-coding.com/viewtopi … 7851#p7851:

The gray Cardinal пишет:

Пример скрипта, использующего компонент (рекурсивно выведет подкаталоги каталога C:\Temp)…

4

Re: WSH:Рекурсивный вывод файлов в папке.

Зарегистрируйте компонент командой наподобие следующей:
regsvr32 "%SystemRoot%\system32\test.wsc"

У меня нет возможности регистрировать данный компонент на клиентской станции для этого необходим админские права, которых у пользователя нет. Поэтому и нужно все переписать на vbs.
+ кусок там написан на JS  я все пишу на VBS зачем все писать на разных языках ?

5

Re: WSH:Рекурсивный вывод файлов в папке.

wildwolf007 пишет:

рекурсию по папкам кажется можно реализовать вот так:

Это не рекурсия. Вот пример рекурсивного удаления файлов старше двух дней (и пустых каталогов заодно):


Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\temp\"
OlderThanDate = DateAdd("d", -2, Date)
 
DeleteOldFiles startFolder, OlderThanDate
 
Function DeleteOldFiles(folderName, BeforeDate)
   Dim folder, file, fileCollection, folderCollection, subFolder 
   Set folder = fso.GetFolder(folderName)
   Set fileCollection = folder.Files
   For Each file In fileCollection
      If file.DateLastModified < BeforeDate Then
         fso.DeleteFile file.Path, True
      End If
   Next 
    Set folderCollection = folder.SubFolders
    For Each subFolder In folderCollection
       DeleteOldFiles subFolder.Path, BeforeDate
       If subFolder.Size = 0 Then subFolder.Delete True
    Next
End Function

Обратите внимание - функция DeleteOldFiles в своем теле вызывает сама себя.

6

Re: WSH:Рекурсивный вывод файлов в папке.

Регистрировать не обязательно, можно положить файл рядом с использующим скриптом:

Set dirs = GetObject("script:" & WScript.ScriptFullName & "..\dirwalker.wsc")

Если же скрипт в формате WSF, всё можно объеденить в один файл:

<?xml version='1.0' encoding='windows-1251' standalone='yes'?>
<package>
<job>
<script language='VBScript'><![CDATA[
Set dirs = GetObject("script:" & WScript.ScriptFullName)
' . . .
]]></script>
</job>
<!--==============================-->
<component>
<!-- Здесь код компонента. . . -->
</component>
</package>
wildwolf007 пишет:

…кусок там написан на JS…

Это не помешает использованию компонента.

7

Re: WSH:Рекурсивный вывод файлов в папке.

Dab00 спасибо попробую разобраться.
Wisgest скажите зачем обращивать исполняемый файл еще дополнительными файлами ведь это в дальнейшем усложняет восприятие читабельность кода. Спасибо, но Ваше решение я не могу использовать в своем коде.

8

Re: WSH:Рекурсивный вывод файлов в папке.

Основной исполняемый файл в hta

9

Re: WSH:Рекурсивный вывод файлов в папке.

Спасибо, но Ваше решение я не могу использовать в своем коде.

Зато Вы можете использовать код из предложенного решения, ибо ничто не мешает при условии отсутствия дополнительных файлов использовать hta c двумя языками.

10

Re: WSH:Рекурсивный вывод файлов в папке.

Dab00 Ваше решение перебирает только файлы в одной директории.

11

Re: WSH:Рекурсивный вывод файлов в папке.

alexii пишет:

Спасибо, но Ваше решение я не могу использовать в своем коде.

Зато Вы можете использовать код из предложенного решения, ибо ничто не мешает при условии отсутствия дополнительных файлов использовать hta c двумя языками.

Ну, а всеж нельзя ли все на одном языке ? На VBS ? А то я с vbs только начинаю более или менее разбираться, а тут другой JS опять погружаться и опять на 2-3 дня.

12

Re: WSH:Рекурсивный вывод файлов в папке.

wildwolf007 пишет:

Dab00 Ваше решение перебирает только файлы в одной директории.

В одной директории и всех ее поддиректориях, жаль, что Вы не вкурили.

wildwolf007 пишет:

Ну, а всеж нельзя ли все на одном языке ?

Не смотрел, что за компонент предлагает уважаемый wisgest, но по задаче напрашивается JS, та же сортировка массива, на VBS сложнее.

13

Re: WSH:Рекурсивный вывод файлов в папке.

dab00 пишет:
wildwolf007 пишет:

Dab00 Ваше решение перебирает только файлы в одной директории.

В одной директории и всех ее поддиректориях, жаль, что Вы не вкурили.

Да действительно все удаляет попробовал сделать так - не получилось, а если так не получается тогда тут и с массивом все не особо получится (скрипт заточен под удаление нужно что-то другое придумать будет):

Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\1\"
OlderThanDate = DateAdd("d", -2, Date)
 
DeleteOldFiles startFolder, OlderThanDate
 
Function DeleteOldFiles(folderName, BeforeDate)
   Dim folder, file, fileCollection, folderCollection, subFolder 
   Set folder = fso.GetFolder(folderName)
   Set fileCollection = folder.Files
   For Each file In fileCollection
      If file.DateLastModified < BeforeDate Then
        MsgBox file.Path
         'fso.DeleteFile file.Path, True
      End If
   Next 
    Set folderCollection = folder.SubFolders
    For Each subFolder In folderCollection
        MsgBox subFolder.Path
       'DeleteOldFiles subFolder.Path, BeforeDate
       'If subFolder.Size = 0 Then subFolder.Delete True
    Next
End Function

14 (изменено: wildwolf007, 2014-01-31 22:23:04)

Re: WSH:Рекурсивный вывод файлов в папке.

Не могу понять почему появляется ошибка при выполнении кода хотя по началу выдает так как нужно ?

Хотя мое предположение это проблема при работе с файловой системой попал на папку в которой запрещен вход.

Осталось все упорядочить относительно даты создания.

Строка 16 символ 3 разрешение отклонено
на строке
For Each file In fileCollection

'On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\" 
If fso.FolderExists (startFolder) Then Start startFolder

Function Start(folderName)
MsgBox folderName
    Dim folder, file, fileCollection, folderCollection, subFolder, all
    all = ""
    Set folder = fso.GetFolder(folderName)
    Set folderCollection = folder.subFolders
    For Each subFolder In folderCollection
        MsgBox subFolder.Path
        all = all + subFolder.Path +vbCrLf
        Set fileCollection = subFolder.Files   
        For Each file In fileCollection
            MsgBox file.Path
            all = all + file.Path +vbCrLf
        Next 
    Next
        
    MsgBox all
   
End Function

15

Re: WSH:Рекурсивный вывод файлов в папке.

Не могу понять почему появляется ошибка при выполнении кода … разрешение отклонено

Например, при попытке обратиться к содержимому «D:\System Volume Information».

16 (изменено: wildwolf007, 2014-01-31 22:27:34)

Re: WSH:Рекурсивный вывод файлов в папке.

Спасибо я тоже к этому склоняюсь. Поэкспериментировал с отдельной папкой и все получилось.

(Мое предположение это проблема при работе с файловой системой попал на папку в которой запрещен вход.)

Скажите, а по логике все правильно построил какие Вы бы добавили дополнения или может могут вылести подводные камни ???

Теперь я предполагаю все нужно поместить в трехмерный массив
i - это полный путь папки.
j - имя файлов.
k - дата создания папки в которой находится файл.

и потом перебрать получившийся массив методом сортировки

17

Re: WSH:Рекурсивный вывод файлов в папке.

wildwolf007, пример рекурсивной обработки вложенных папок (с обработкой ошибок) Вы можете увидеть, например, здесь.

Теперь я предполагаю все нужно поместить в трехмерный массив

Зачем именно в трёхмерный? Используйте полный путь вместо пути и имени по отдельности.

и потом перебрать получившийся массив методом сортировки

Некорректное выражение: перебирать что-либо методом сортировки невозможно. По каким критериям Вы собираетесь делать сортировку?

18

Re: WSH:Рекурсивный вывод файлов в папке.

По дате создания папки в которой находится файл.

Получилось вот так вот только чет я с многомерными массивами напортачил:

'On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\1\" 
If fso.FolderExists (startFolder) Then Start startFolder

Function Start(folderName)
'MsgBox folderName
    Dim folder, file, fileCollection, folderCollection, subFolder, all, allmassiv
    Dim a(),i,j,k
    i=0        
    k=0
    reDim a(1,1)
    
    all = ""
    allmassiv = ""
    Set folder = fso.GetFolder(folderName)
    Set folderCollection = folder.subFolders
    For Each subFolder In folderCollection
        'MsgBox subFolder.Path
        all = all + subFolder.Path +vbCrLf
        a(i) = all
        a(k) = subFolder.DateCreated
        'MsgBox subFolder.DateCreated
        i=i+1
        k=k+1
        reDim preserve a(i,k)
        Set fileCollection = subFolder.Files   
        For Each file In fileCollection
            'MsgBox file.Path
            all = all + file.Path +vbCrLf
            a(i)=all
            i=i+1
            k=k+1
            j=i
            reDim preserve a(i,k)
        Next 
    Next
        
    MsgBox all
    k=0
    For i=0 To j Step 1
    allmassiv = a(i,k) +vbCrLf
    k=k+1
    Next
   MsgBox allmassiv
End Function

19

Re: WSH:Рекурсивный вывод файлов в папке.

Дописал полноценную рекурсию на VBS для просмотра каталогов начальной директории всех файлов  вот код если кому будет необходимо:

Dim startFolder, Files(), RazmerMassivaFiles,i,SpisokIzMassiva

RazmerMassivaFiles = 0
reDim Files(RazmerMassivaFiles)

Files(RazmerMassivaFiles) = "В данной структуре каталогов нет файлов"

Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "D:\GamesMailRu\"

CheckFolderInFolder startFolder

'Вывод значений массива
For i=0 To RazmerMassivaFiles Step 1
    SpisokIzMassiva = SpisokIzMassiva + Files(i) +vbCrLf
    i=i+1
Next

MsgBox SpisokIzMassiva

Function CheckFolderInFolder (AdresFolder)
    'MsgBox AdresFolder
    Dim File
    Set Folder = FSO.GetFolder(AdresFolder)
    Set CollectionFolder = Folder.SubFolders
    Set CollectionFile = Folder.Files
    'MsgBox CollectionFile.count
    If CollectionFile.count > 0 Then
        For Each File In CollectionFile
            Files(RazmerMassivaFiles) = File.Path
            'MsgBox "В массив Files("&RazmerMassivaFiles &") помещено значение = " 

&Files(RazmerMassivaFiles)
            RazmerMassivaFiles = RazmerMassivaFiles + 1
            reDim preserve Files(RazmerMassivaFiles)
            'Files(RazmerMassivaFiles) = "Пустое значение"
        Next
    End If
    
    For Each SubFolder In CollectionFolder
        CheckFolderInFolder SubFolder
    Next

End Function

Единственное не могу понять почему  строка "MsgBox SpisokIzMassiva" не выводит в сообщении весь массив ?

20

Re: WSH:Рекурсивный вывод файлов в папке.

wisgest пишет:

Нужно рекурсивно пройтись по всем папкам директории "D:\"…

Сколько же ещё будет подниматься этот вопрос?

http://forum.script-coding.com/viewtopi … 7851#p7851:

The gray Cardinal пишет:

Пример скрипта, использующего компонент (рекурсивно выведет подкаталоги каталога C:\Temp)…


Вопрос будет подниматься до тех пор, пока решение не будет предложено на мой взгляд Ваше решение немного замудрено.

21

Re: WSH:Рекурсивный вывод файлов в папке.

Убрал все лишнее оставил только суть:

Dim startFolder

Set fso = CreateObject("Scripting.FileSystemObject")
'Место указания пути рекурсии
startFolder = "D:\1\"

CheckFolderInFolder startFolder

Function CheckFolderInFolder (AdresFolder)
    Dim File
    Set Folder = FSO.GetFolder(AdresFolder)
    Set CollectionFolder = Folder.SubFolders
    Set CollectionFile = Folder.Files

    If CollectionFile.count > 0 Then
        For Each File In CollectionFile
            ' Сообщение о файле при переборе
            MsgBox File.Path
        Next
    End If
    
    For Each SubFolder In CollectionFolder
        CheckFolderInFolder SubFolder
    Next

End Function