powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Два раза Dir
10 сообщений из 10, страница 1 из 1
Два раза Dir
    #32345881
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Как известно, функция Dir, если ее вызвать без аргументов, помнит последний переданный аргумент. На этом основаны циклы, которые проходят по всем файлам заданного типа:

Код: plaintext
1.
2.
3.
4.
sFile = Dir(...)
Do Until sFile = ""
    ...
    sFile = Dir
Loop

Проблема в том, что у меня внутри такого цикла есть обращение к функции, которая тоже использует Dir с параметром, но совершенно с другим. В результате цикл сбивается.

Как это обойти? Спасибо!
...
Рейтинг: 0 / 0
Два раза Dir
    #32345885
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
В качестве временного решения завел коллекцию и первым циклом заполнил ее (не обращаясь к функции), а второй цикл пустил по коллекции, а не по Dir.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
sFile = Dir(...)
Do Until sFile = ""
    Coll.Add sFile
    sFile = Dir
Loop
For Each v In Coll
    sFile = v
    ...
Next

Может, есть более красивое решение?
...
Рейтинг: 0 / 0
Два раза Dir
    #32346026
IgorM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно попробовать дополнить поиск альтернативными методами:
см. 1 и 3
...
Рейтинг: 0 / 0
Два раза Dir
    #32346112
Фотография SergeySV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Либо использовать FSO, в принципе неплохой класс и достаточно удобный, некоторые только через него и работают...
...
Рейтинг: 0 / 0
Два раза Dir
    #32346127
zz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага. Сейчас придет Сенин Виктор и выскажет все, что он думает по поводу FSO.
...
Рейтинг: 0 / 0
Два раза Dir
    #32346155
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Либо Office.FileSearch либо WinAPI

HOWTO: Search Directories to Find or List Files

When looking for files, it is often necessary to search through subdirectories. This
article demonstrates two methods for recursively searching directories and
retrieving file information.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
   Declare Function FindFirstFile Lib  "kernel32"  Alias _
    "FindFirstFileA"  (ByVal lpFileName As String, lpFindFileData _
   As WIN32_FIND_DATA) As Long

   Declare Function FindNextFile Lib  "kernel32"  Alias  "FindNextFileA"  _
   (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long

   Declare Function GetFileAttributes Lib  "kernel32"  Alias _
    "GetFileAttributesA"  (ByVal lpFileName As String) As Long

   Declare Function FindClose Lib  "kernel32"  (ByVal hFindFile As Long) _
   As Long

   Declare Function FileTimeToLocalFileTime Lib  "kernel32"  _
   (lpFileTime As FILETIME, lpLocalFileTime As FILETIME) As Long
     
   Declare Function FileTimeToSystemTime Lib  "kernel32"  _
   (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long

   Public Const MAX_PATH =  260 
   Public Const MAXDWORD = &HFFFF
   Public Const INVALID_HANDLE_VALUE = - 1 
   Public Const FILE_ATTRIBUTE_ARCHIVE = &H20
   Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
   Public Const FILE_ATTRIBUTE_HIDDEN = &H2
   Public Const FILE_ATTRIBUTE_NORMAL = &H80
   Public Const FILE_ATTRIBUTE_READONLY = &H1
   Public Const FILE_ATTRIBUTE_SYSTEM = &H4
   Public Const FILE_ATTRIBUTE_TEMPORARY = &H100

   Type FILETIME
     dwLowDateTime As Long
     dwHighDateTime As Long
   End Type

   Type WIN32_FIND_DATA
     dwFileAttributes As Long
     ftCreationTime As FILETIME
     ftLastAccessTime As FILETIME
     ftLastWriteTime As FILETIME
     nFileSizeHigh As Long
     nFileSizeLow As Long
     dwReserved0 As Long
     dwReserved1 As Long
     cFileName As String * MAX_PATH
     cAlternate As String *  14 
   End Type

   Type SYSTEMTIME
     wYear As Integer
     wMonth As Integer
     wDayOfWeek As Integer
     wDay As Integer
     wHour As Integer
     wMinute As Integer
     wSecond As Integer
     wMilliseconds As Integer
   End Type

   Public Function StripNulls(OriginalStr As String) As String
      If (InStr(OriginalStr, Chr( 0 )) >  0 ) Then
         OriginalStr = Left(OriginalStr, _
          InStr(OriginalStr, Chr( 0 )) -  1 )
      End If
      StripNulls = OriginalStr
   End Function
					
   Function FindFilesAPI(path As String, SearchStr As String, _
    FileCount As Integer, DirCount As Integer)
   Dim FileName As String   ' Walking filename variable...
   Dim DirName As String    ' SubDirectory Name
   Dim dirNames() As String ' Buffer for directory name entries
   Dim nDir As Integer   ' Number of directories in this path
   Dim i As Integer      ' For-loop counter...
   Dim hSearch As Long   ' Search Handle
   Dim WFD As WIN32_FIND_DATA
   Dim Cont As Integer
   Dim FT As FILETIME
   Dim ST As SYSTEMTIME
   Dim DateCStr As String, DateMStr As String
     
   If Right(path,  1 ) <>  "\"  Then path = path &  "\" 
   ' Search for subdirectories.
   nDir = 0
   ReDim dirNames(nDir)
   Cont = True
   hSearch = FindFirstFile(path & "*", WFD)
   If hSearch <> INVALID_HANDLE_VALUE Then
      Do While Cont
         DirName = StripNulls(WFD.cFileName)
         ' Ignore the current and encompassing directories.
         If (DirName <>  "." ) And (DirName <>  ".." ) Then
            ' Check for directory with bitwise comparison.
            If GetFileAttributes(path & DirName) And _
             FILE_ATTRIBUTE_DIRECTORY Then
               dirNames(nDir) = DirName
               DirCount = DirCount + 1
               nDir = nDir + 1
               ReDim Preserve dirNames(nDir)
               ' Uncomment the next line to list directories
               'List1.AddItem path & FileName
            End If
         End If
         Cont = FindNextFile(hSearch, WFD)  ' Get next subdirectory.
      Loop
      Cont = FindClose(hSearch)
   End If

   ' Walk through this directory and sum file sizes.
   hSearch = FindFirstFile(path & SearchStr, WFD)
   Cont = True
   If hSearch <> INVALID_HANDLE_VALUE Then
      While Cont
         FileName = StripNulls(WFD.cFileName)
            If (FileName <> ".") And (FileName <> "..") And _
              ((GetFileAttributes(path & FileName) And _
               FILE_ATTRIBUTE_DIRECTORY) <> FILE_ATTRIBUTE_DIRECTORY) Then
            FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * _
             MAXDWORD) + WFD.nFileSizeLow
            FileCount = FileCount + 1
            ' To list files w/o dates, uncomment the next line
            ' and remove or Comment the lines down to End If
            'List1.AddItem path & FileName
            
           ' Include Creation date...
           FileTimeToLocalFileTime WFD.ftCreationTime, FT
           FileTimeToSystemTime FT, ST
           DateCStr = ST.wMonth & "/" & ST.wDay & "/" & ST.wYear & _
              " " & ST.wHour & ":" & ST.wMinute & ":" & ST.wSecond
           ' and Last Modified Date
           FileTimeToLocalFileTime WFD.ftLastWriteTime, FT
           FileTimeToSystemTime FT, ST
           DateMStr = ST.wMonth &  "/"  & ST.wDay &  "/"  & ST.wYear & _
               " "  & ST.wHour &  ":"  & ST.wMinute &  ":"  & ST.wSecond
           List1.AddItem path & FileName & vbTab & _
              Format(DateCStr,  "mm/dd/yyyy hh:nn:ss" ) _
              & vbTab & Format(DateMStr,  "mm/dd/yyyy hh:nn:ss" )
          End If
         Cont = FindNextFile(hSearch, WFD)  ' Get next file
      Wend
      Cont = FindClose(hSearch)
   End If

   ' If there are sub-directories...
    If nDir >  0  Then
      ' Recursively walk into them...
      For i =  0  To nDir -  1 
        FindFilesAPI = FindFilesAPI + FindFilesAPI(path & dirNames(i) _
         &  "\" , SearchStr, FileCount, DirCount)
      Next i
   End If
   End Function

   Private Sub Command1_Click()
   Dim SearchPath As String, FindStr As String
   Dim FileSize As Long
   Dim NumFiles As Integer, NumDirs As Integer

   Screen.MousePointer = vbHourglass
   List1.Clear
   SearchPath = Text1.Text
   FindStr = Text2.Text
   FileSize = FindFilesAPI(SearchPath, FindStr, NumFiles, NumDirs)
   Text3.Text = NumFiles &  " Files found in "  & NumDirs +  1  & _
     " Directories" 
   Text4.Text =  "Size of files found under "  & SearchPath &  " = "  & _
   Format(FileSize,  "#,###,###,##0 ") &  " Bytes" 
   Screen.MousePointer = vbDefault
   End Sub
...
Рейтинг: 0 / 0
Два раза Dir
    #32346163
Фотография SergeySV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ссылка IgorM :)
...
Рейтинг: 0 / 0
Два раза Dir
    #32346173
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я ссылок не читаю :) - я МСДН читаю.к тому же доступ к микрософту у меня закрыт :(
==
кстати, в МСДН написано, что быстрей через API работать не будет - Не верю (С) :)
...
Рейтинг: 0 / 0
Два раза Dir
    #32346238
Функции поиска на основе API друг другу не мешают, к тому же они не мешают и Dir().
Эта тестовая процедура возвращает все файлы по 3-м маскам. Использует самодельный класс "clsFilesSystem" и его метод "FindFileForMask".

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Sub TestFind()
Dim s1 As String, s2 As String, s3 As String
Dim FS1 As New clsFilesSystem
Dim FS2 As New clsFilesSystem

    s1 = FS1.FindFileForMask("C:\MyDB\*.mdb")
    s2 = FS2.FindFileForMask("C:\MyDB\*.mde")
    s3 = Dir$("C:\MyDB\*.bak")
 Do While Len(s1) > 0 Or Len(s2) > 0 Or Len(s3) > 0
  If Len(s1) > 0 Then
    Debug.Print s1
    s1 = FS1.FindFileForMask
  End If
  If Len(s2) > 0 Then
    Debug.Print Tab; s2
    s2 = FS2.FindFileForMask
  End If
  If Len(s3) > 0 Then
    Debug.Print Tab; Tab; s3
    s3 = Dir$
  End If
 Loop
End Sub



А FSO не имеет методов поиска по маске(?!). Если его использовать в среде VB(A), то можно использовать Like, а вот VBScript не поддерживает ни Like, ни Declare (чтоб использовать API). К сожалению...
...
Рейтинг: 0 / 0
Два раза Dir
    #32346387
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Понял, спасибо! Похоже, что все варианты столь же некрасивы, как и мой. :^)
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Два раза Dir
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]