Перебор папок и файлов

Автор Dr_Lecter, 18 сентября 2015, 19:24

0 Пользователи и 1 гость просматривают эту тему.

Dr_Lecter

To ALL

Не знаю насколько офтопп, но попробую спросить здесь, чтобы не засорять форум темами, т.к. подозреваю что опять спрошу очевидное, если что - могу удалить и открыть новую тему:

Для сквозной нумерации протоколов нужно знать сколько уже создано.
Каждый год нумерация заново у каждого врача.
Протоколы хранятся в структуре типа:
2014
 01_2014
 02_2014
 ...
 12_2014
2015
 И так далее.

Т.е. нужно посчитать сколько уже создано. Для этого написал код ниже, но он ищет только в одном каталоге.


Sub Main
Dim sPathDir as string
Dim sFileList
Dim i as Integer
Dim s as String

sPathDir = ConvertToURL("C:\ТестовыйПуть\*.odt")
i = 0
sFileList = Dir(sPathDir,0)
Do While (sFileList <> "")
i = i + 1
s = s & "File " & CStr(i) & "=" & sFileList & Chr$(10)
sFileList = Dir()
Loop
Print i
End Sub


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

Наверняка есть более элегантное и быстрое решение.
Просто лопатить к концу года 4000 - 5000 файлов в папках для того чтобы их посчитать как-то... Ведь эта информация уже есть в файловой системе.

И еще глюк - почему мой код если изменить Print i на Print s дает сначала первые два файла отдельными окнами, а потом все остальные одним окном? Это нормально?

Спасибо всем заранее!

rami

Цитата: Dr_Lecter от 18 сентября 2015, 17:24И еще глюк - почему мой код дает сначала первые два файла отдельным окном, а потом все остальные вторым окном?
Это особенности Print, используйте msgbox

...начало кода
Loop
msgbox i
End Sub

rami

Цитата: Dr_Lecter от 18 сентября 2015, 17:24Для сквозной нумерации протоколов нужно знать сколько уже создано.
Каждый год нумерация заново у каждого врача.
Протоколы хранятся в структуре типа:
2014
  01_2014
  02_2014
  ...
  12_2014
2015
  И так далее.
Я так понимаю, что речь идёт о двух уровнях папок: в папке года есть подпапки месяцев, в которых находятся файлы.
Цитата: Dr_Lecter от 18 сентября 2015, 17:24Прикинул решение: весь код помещаем в еще один цикл, в котором ищем все папки месяцев по очереди от 01 до 12.
Но что делать если в какой-то месяц врача не было, и папки такой нет - значит нужно сначала найти все существующие папки, создать из них массив, элементы массива по очереди передать в цикл в котором будет вложенный цикл поиска файлов и сложение полученной цифры в конце.
Ваше предположение в целом правильное: нужно перебрать подпапки и записать их в массив, а затем в цикле перебрать массив подпапок и найти (пересчитать) в них файлы.
Sub Main Dim path$, sFolders$, sFileName$, f$, s(), j%, t$
path="C:\ТестовыйПуть\"   'Путь к годовой папке должен завершаться слэшем, не включает подпапки и расширения файлов
sFolders=Dir(path,16)
Do Until sFolders=""
f=f+sFolders+"/,"
sFolders=Dir()
Loop
s=split(f,",")
For i=0 To UBound(s)
sFileName=Dir(path+s(i)+"*.odt",0)
Do While sFileName <> ""
j=j+1
t=t+sFileName+chr(10)
sFileName=Dir()
Loop
Next
msgbox "файлов в папке: "+j,32,"Количество"
msgbox t,32,"Перечень файлов"
End Sub

Цитата: Dr_Lecter от 18 сентября 2015, 17:24Наверняка есть более элегантное и быстрое решение.
Просто лопатить к концу года 4000 - 5000 файлов в папках для того чтобы их посчитать как-то... Ведь эта информация уже есть в файловой системе.
Не знаю как в вашей файловой системе, но на Маке я бы решил эту задачу с помощью создания смарт-папки — это виртуальная папка собирающая из указанного места всё что соответствует критериям отбора (выбор из сотен критериев), а в строке состояния видно количество объектов.

Просьба к администраторам разделить эту тему на две. Новая тема: Перебор папок и файлов

Helen

Цитата: rami от 20 сентября 2015, 13:27Просьба к администраторам разделить эту тему на две. Новая тема: Перебор папок и файлов
сделано.

bigor

для винды,
с помощью dir посчитать количество файлов и затянуть значение себе в макрос

dir /B /A-D /S %1 | find /N /C /V "" > c:\tools\filescount.txt это содержимое батника C:\tools\FilesCount.bat

а вот макрос, который его вызывает из ООО
Sub Main
Shell ("C:\tools\FilesCount.bat", 2, """d:\Мои документы\ответы""", true)
FileName = ConvertToURL("c:\tools\filescount.txt")
n = FreeFile()
Open FileName For input As #n
Input #n, s
close #n
msgbox s
End Sub


батник в одну строку, наверное можно его и в shell запихнуть, но я на кавычках застрял, которые в find задают строку поиска

Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

Dr_Lecter

Был в командировке поэтому не заходил.

Сделал так:

REM Процедура поиска существующих подпапок
iFolders = 0
sFoldersList = Dir(sPathDir, 16)
Do While (sFoldersList <> "")
iFolders = iFolders + 1
sAllFoldersList = sAllFoldersList & sFoldersList & Chr$(10)
sFoldersList = Dir()
Loop
aFoldersList = Split(sAllFoldersList, Chr$(10))

REM Процедура подсчета файлов в найденных подпапках
iFiles = 0
For iSubFolders = 2 To UBound(aFoldersList) Step 1
sSubFolders = aFoldersList(iSubFolders)
sPathSubDir = ConvertToURL(sPathDir & sSubFolders & GetPathSeparator() & sSearchFilesType)
sFilesList = Dir(sPathSubDir, 0)
Do While (sFilesList <> "")
iFiles = iFiles + 1
sFilesList = Dir()
Loop
Next iSubFolders

REM Запись текущего номера протокола в документ
oProtocolNumber.Content = iFiles + 1


Проверил на Mac и на Windows (внутри VMWare Fusion) при поиске в папках содержащих порядка 10000 файлов тормозов нет на машине 2013г с обычным винтом.

Bigor

Ваш вариант по сути такой-же, т.к. dir внутри операционки тоже ищет все файлы, нет смысла усложнять дополнительным вызовом и терять совместимость c версией под Mac и Linux.

Просто я думал что есть возможность напрямую запросить число файлов из метаданных файловой системы и желательно универсально для всех типов ОС, но такого решения не нашел.

Dr_Lecter

Задача решена.
Тему можно закрывать.
Всем спасибо за участие!  :beer: