Solved

Searching for files

Posted on 1998-06-01
11
150 Views
Last Modified: 2010-05-03
I have a directory with files like
0003.dat
0004.dat
0005.dat
....
0279.dat
0456.dat
0457.dat
My question is how to extract the filename which has the lowest number and the file with the highest number as fast as possible. Note that the files are not necessarily continously numbered.
0
Comment
Question by:tell
  • 4
  • 4
  • 2
  • +1
11 Comments
 
LVL 18

Expert Comment

by:deighton
ID: 1462222
Private Sub Command1_Click()
    Dim sSearch As String
    Dim sPath As String
    Dim iVal As Long
    Dim iMin As Long     'Minimum value
    Dim iMax As Long     'Maximum value
   
    iMin = 99999
   
    sPath = "a:"     'YOUR PATH
   
   
    sSearch = Dir(sPath + "*.dat")
    If sSearch = "" Then
        MsgBox "No matches"
        Exit Sub
    End If
   
    Do
   
        iVal = Val(Left(sSearch, 4))
        If iVal > iMax Then iMax = iVal
        If iVal < iMin Then iMin = iVal
       
        sSearch = Dir

    Loop Until sSearch = ""

   
End Sub

0
 
LVL 18

Expert Comment

by:deighton
ID: 1462223
Here I've added a bit to give you the actual full name - not just the number
I think this is pretty efficient


Private Sub Command1_Click()
    Dim sSearch As String
    Dim sPath As String
    Dim iVal As Long
    Dim iMin As Long     'Minimum value
    Dim iMax As Long     'Maximum value
    Dim sMin As String   'name of lowest
    Dim sMax As String  'name of highest
   
    iMin = 99999
   
    sPath = "a:"     'YOUR PATH
   
   
    sSearch = Dir(sPath + "*.dat")
    If sSearch = "" Then
        MsgBox "No matches"
        Exit Sub
    End If
   
    Do
   
        iVal = Val(Left(sSearch, 4))
        If iVal > iMax Then iMax = iVal: sMax = sSearch
        If iVal < iMin Then iMin = iVal: sMin = sSearch
       
        sSearch = Dir

    Loop Until sSearch = ""
   
   
   'view results
   
   MsgBox "maximim = " + Format(iMax)
   MsgBox "minimum = " + Format(iMin)
   MsgBox "maximim = " + sMax
   MsgBox "minimum = " + sMin
   
   
End Sub



0
 
LVL 4

Expert Comment

by:zsi
ID: 1462224
tell,

There is a much faster way of dong this.  And with less code, too.

====================================================
In [Declarations]:

Option Explicit
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Declare Function GetLastError Lib "kernel32" () As Long
Const ERROR_NO_MORE_FILES = 18&


Const MAX_PATH = 260
Private Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
End Type

Private 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

===================================================
Public Sub FindMyFiles()

   Dim h As Long
   Dim fd As WIN32_FIND_DATA
   Dim High As String
   Dim Low As String
   
   h = FindFirstFileMyPath & "\*.dat", fd)
   High = fd.cFileName
   Low = fd.cFileName
   While GetLastError() <> ERROR_NO_MORE_FILES
      If fd.cFileName > High Then
         High = fd.cFileName
      ElseIf fd.cFileName < Low Then
         Low = fd.cFileName
      End If
      Call FindNextFile(h, fd)
   Wend
     
   Debug.Print "High: " & High
   Debug.Print "Low: " & Low

   Call FindClose(h)


End Sub
0
 
LVL 18

Expert Comment

by:deighton
ID: 1462225
Dear Zsi,

Your solution has loads of code and definintely more characters in it.  Also its a Rolls Royce solution where a VW Beetle would have done.

A.Nutter






0
 
LVL 4

Expert Comment

by:zsi
ID: 1462226
Yes, but since Tell is asking for a solution with a V-8 as opposed to an air-cooled V-4 that has a difficult time accellerating while going uphill, you need the API.  Tell *did* ask for a solution that would be as fast as possible.

Feel free to run the benchmarks yourself.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 4

Expert Comment

by:yowkee
ID: 1462227
deighton,
   zsi's method will be much faster than you especially there got a lot files under the directory. :)

   Just want to provide a alternative way , it may not be faster than zsi's, I didn't test its real performance. Just suddenly think of it. Have fun. :)

**Declaration of API under a module:
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Public Const LB_DIR = &H18D
Public Const DDL_READWRITE = &H0
Public Const DDL_ARCHIVE = &H20

**Put a Listbox in a Form, set its property "Sorted" to True.

Private Sub Form_Load()

  SendMessage List1.hwnd, LB_DIR, DDL_READWRITE Or
              DDL_ARCHIVE, "*.dat"
  If List1.ListCount <> 0 Then
      MsgBox "Min: " + List1.List(0)
      MsgBox "Max: " + List1.List(List1.ListCount - 1)
  End If
End Sub

   
0
 
LVL 4

Expert Comment

by:zsi
ID: 1462228
yowkee,

That method will get very slowed in instances where there are a lot of files.  Especially with the sorted property set to true as it will sort on the insertion of each entry.
0
 

Author Comment

by:tell
ID: 1462229
Thanks a lot,

zsi's solution is definitely my favourite.
ATTENTION ( for those who use the code later on):
 there is a syntax error in line
            h = FindFirstFileMyPath & "\*.dat", fd)
correct:    h = FindFirstFile(MyPath & "\*.dat", fd)
0
 
LVL 18

Expert Comment

by:deighton
ID: 1462230
I accept defeat
0
 
LVL 4

Accepted Solution

by:
zsi earned 50 total points
ID: 1462231
I accept victory.  :)

tell, sorry about the syntax error there.  When I posted the code onto the board, I made some changes to the variables so that the code would be more in line with your needs.  

For those too lazy to scroll down, here is the answer again:
-------------------------------------------------------------------------

      In [Declarations]:

      Option Explicit
      Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As
      String, lpFindFileData As WIN32_FIND_DATA) As Long
      Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As
      Long, lpFindFileData As WIN32_FIND_DATA) As Long
      Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
      Private Declare Function GetLastError Lib "kernel32" () As Long
      Const ERROR_NO_MORE_FILES = 18&


      Const MAX_PATH = 260
      Private Type FILETIME
              dwLowDateTime As Long
              dwHighDateTime As Long
      End Type

      Private 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

      ===================================================
      Public Sub FindMyFiles()

         Dim h As Long
         Dim fd As WIN32_FIND_DATA
         Dim High As String
         Dim Low As String
         
         h = FindFirstFileMyPath & "\*.dat", fd)
         High = fd.cFileName
         Low = fd.cFileName
         While GetLastError() <> ERROR_NO_MORE_FILES
            If fd.cFileName > High Then
               High = fd.cFileName
            ElseIf fd.cFileName < Low Then
               Low = fd.cFileName
            End If
            Call FindNextFile(h, fd)
         Wend
             
         Debug.Print "High: " & High
         Debug.Print "Low: " & Low

         Call FindClose(h)


      End Sub
0
 

Author Comment

by:tell
ID: 1462232
Greetings to both, zsi and deighton.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now