Results 1 to 4 of 4

Thread: recursive function

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,539
    here is what am trying to do
    let say i have a directory called
    c:\ARTISTS

    thats the root
    in that directory there is let say 30 different artits
    and in those artists SOME can have more than one album
    those that dont have more than one album
    the songs are located in just the name of the artist

    so if artst1 had one album
    all the songs would be located in c:\Artists\artist1

    and if artist2 had 2 albums
    it would be like
    c:\artists\artist2\album1 (songs for this album go here)
    c:\artists\artist2\album2 (songs for album2 go here)

    so i would like someone to help me out with making a function that when given c:\artist\
    it will go into every directory
    and copy artist name(directory), album name( sub directory), and song names (filenames)
    into a table..

    thank you

  2. #2
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    You can use my function I wrote a while back. Drop a listbox and a command button:
    Code:
    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 GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
    Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
    Private Const MAX_PATH = 260
    Private Const MAXDWORD = &HFFFF
    Private Const INVALID_HANDLE_VALUE = -1
    Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
    Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
    Private Const FILE_ATTRIBUTE_HIDDEN = &H2
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const FILE_ATTRIBUTE_READONLY = &H1
    Private Const FILE_ATTRIBUTE_SYSTEM = &H4
    Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
    
    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
    
    Private m_arrFiles() As String
    Private m_intCount As Integer
    
    
    Function FindFiles(ByRef p_strPath As String, ByRef p_strSearch As String, ByRef p_intFileCount As Integer, ByRef p_intDirCount As Integer, p_ListView As ListView)
        Dim strDirName As String
        Dim arrDirNames() As String
        Dim strFileName As String
        Dim intDirCount As Integer
        Dim i As Integer
        Dim lngSearchHandle As Long
        Dim WFD As WIN32_FIND_DATA
        Dim intCount As Integer
        Dim itmListItem As ListItem
    
        If Right(p_strPath, 1) <> "\" Then p_strPath = p_strPath & "\"
        ' Search for subdirectories.
        intDirCount = 0
        ReDim arrDirNames(intDirCount)
        
        intCount = True
        lngSearchHandle = FindFirstFile(p_strPath & "*", WFD)
        
        If lngSearchHandle <> INVALID_HANDLE_VALUE Then
            Do While intCount
                strDirName = StripNull(WFD.cFileName)
                If (strDirName <> ".") And (strDirName <> "..") Then
                    ' Check if it's a directory
                    If GetFileAttributes(p_strPath & strDirName) And FILE_ATTRIBUTE_DIRECTORY Then
                        arrDirNames(intDirCount) = strDirName
                        p_intDirCount = p_intDirCount + 1
                        intDirCount = intDirCount + 1
                        ReDim Preserve arrDirNames(intDirCount)
                    End If
                End If
                intCount = FindNextFile(lngSearchHandle, WFD)  'next subdirectory.
            Loop
            intCount = FindClose(lngSearchHandle)
        End If
    
        'Walk through this directory and get file sizes.
        lngSearchHandle = FindFirstFile(p_strPath & p_strSearch, WFD)
        intCount = True
        If lngSearchHandle <> INVALID_HANDLE_VALUE Then
            Do While intCount
                strFileName = StripNull(WFD.cFileName)
                If (strFileName <> ".") And (strFileName <> "..") Then
                    FindFiles = FindFiles + (WFD.nFileSizeHigh * MAXDWORD) + WFD.nFileSizeLow
                    p_intFileCount = p_intFileCount + 1
                    
                    ReDim Preserve m_arrFiles(m_intCount)
                    m_arrFiles(m_intCount) = p_strPath & strFileName
                    m_intCount = m_intCount + 1
                End If
                intCount = FindNextFile(lngSearchHandle, WFD)  'Get next file
            Loop
            intCount = FindClose(lngSearchHandle)
        End If
    
        'Check for SubDirectories
        If intDirCount > 0 Then
            For i = 0 To intDirCount - 1
                FindFiles = FindFiles + FindFiles(p_strPath & arrDirNames(i) _
                & "\", p_strSearch, p_intFileCount, p_intDirCount, p_ListView)
            Next i
        End If
    End Function
    
    
    Private Function IsArrayDimensioned(p_Array As Variant) As Boolean
        On Error Resume Next
        
        IsArrayDimensioned = IsNumeric(UBound(p_Array))
    End Function
    
    
    Public Function StripNull(p_strString As String) As String
       If InStr(p_strString, vbNullChar) Then
          p_strString = Left(p_strString, InStr(p_strString, vbNullChar) - 1)
       End If
       StripNull = p_strString
    End Function
    Then you can use this function like this:
    Code:
    Private Sub Command1_Click()
        Dim i As Integer
        Dim intNumFiles As Integer
        Dim intNumDirs As Integer
        Dim lngFileSize As Long
        Dim strMsg As String
        Dim strPath As String
        
        strPath = "C:\ARTISTS"
        lngFileSize = FindFiles(strPath, "*.*", intNumFiles, intNumDirs, ListView1)
        If IsArrayDimensioned(m_arrFiles) Then
            For i = 0 To UBound(m_arrFiles)
                List1.AddItem m_arrFiles(i)
            Next
        End If
        
        strMsg = intNumFiles & " Files found in " & intNumDirs + 1 & " Directories" & vbCrLf
        strMsg = strMsg & "Size of files found under " & strPath & " = "
        strMsg = strMsg & Format(lngFileSize, "#,###,###,##0") & " Bytes"
        MsgBox strMsg
    End Sub
    Regards,

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Posts
    1,539

    hmm

    Code:
    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 GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
    Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
    Private Const MAX_PATH = 260
    Private Const MAXDWORD = &HFFFF
    Private Const INVALID_HANDLE_VALUE = -1
    Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
    Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
    Private Const FILE_ATTRIBUTE_HIDDEN = &H2
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const FILE_ATTRIBUTE_READONLY = &H1
    Private Const FILE_ATTRIBUTE_SYSTEM = &H4
    Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
    
    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
    
    Private m_arrFiles() As String
    Private m_intCount As Integer
    Function FindFiles(ByRef p_strPath As String, ByRef p_strSearch As String, ByRef p_intFileCount As Integer, ByRef p_intDirCount As Integer, p_ListView As ListView) As String
        Dim strDirName As String
        Dim arrDirNames() As String
        Dim strFileName As String
        Dim intDirCount As Integer
        Dim i As Integer
        Dim lngSearchHandle As Long
        Dim WFD As WIN32_FIND_DATA
        Dim intCount As Integer
        Dim itmListItem As ListItem
    
        If Right(p_strPath, 1) <> "\" Then p_strPath = p_strPath & "\"
        ' Search for subdirectories.
        intDirCount = 0
        ReDim arrDirNames(intDirCount)
        
        intCount = True
        lngSearchHandle = FindFirstFile(p_strPath & "*", WFD)
        
        If lngSearchHandle <> INVALID_HANDLE_VALUE Then
            Do While intCount
                strDirName = StripNull(WFD.cFileName)
                If (strDirName <> ".") And (strDirName <> "..") Then
                    ' Check if it's a directory
                    If GetFileAttributes(p_strPath & strDirName) And FILE_ATTRIBUTE_DIRECTORY Then
                        arrDirNames(intDirCount) = strDirName
                        p_intDirCount = p_intDirCount + 1
                        intDirCount = intDirCount + 1
                        ReDim Preserve arrDirNames(intDirCount)
                    End If
                End If
                intCount = FindNextFile(lngSearchHandle, WFD)  'next subdirectory.
            Loop
            intCount = FindClose(lngSearchHandle)
        End If
    
        'Walk through this directory and get file sizes.
        lngSearchHandle = FindFirstFile(p_strPath & p_strSearch, WFD)
        intCount = True
        If lngSearchHandle <> INVALID_HANDLE_VALUE Then
            Do While intCount
                strFileName = StripNull(WFD.cFileName)
                If (strFileName <> ".") And (strFileName <> "..") Then
                    FindFiles = FindFiles + (WFD.nFileSizeHigh * MAXDWORD) + WFD.nFileSizeLow
                    p_intFileCount = p_intFileCount + 1
                    
                    ReDim Preserve m_arrFiles(m_intCount)
                    m_arrFiles(m_intCount) = p_strPath & strFileName
                    m_intCount = m_intCount + 1
                End If
                intCount = FindNextFile(lngSearchHandle, WFD)  'Get next file
            Loop
            intCount = FindClose(lngSearchHandle)
        End If
    
        'Check for SubDirectories
        If intDirCount > 0 Then
            For i = 0 To intDirCount - 1
                FindFiles = FindFiles + FindFiles(p_strPath & arrDirNames(i) _
                & "\", p_strSearch, p_intFileCount, p_intDirCount, p_ListView)
            Next i
        End If
    End Function
    
    
    
    Private Sub Command1_Click()
    Dim i As Integer
        Dim intNumFiles As Integer
        Dim intNumDirs As Integer
        Dim lngFileSize As Long
        Dim strMsg As String
        Dim strPath As String
        
        strPath = "C:\work\virtualkurdistan"
        lngFileSize = FindFiles(strPath, "*.*", intNumFiles, intNumDirs, ListView1)
        If IsArrayDimensioned(m_arrFiles) Then
            For i = 0 To UBound(m_arrFiles)
                List1.AddItem m_arrFiles(i)
            Next
        End If
        
        strMsg = intNumFiles & " Files found in " & intNumDirs + 1 & " Directories" & vbCrLf
        strMsg = strMsg & "Size of files found under " & strPath & " = "
        strMsg = strMsg & Format(lngFileSize, "#,###,###,##0") & " Bytes"
        MsgBox strMsg
    
    End Sub
    thats almost identical to what you posted (except i had to remove one space from one of the constants....)
    this also needs a listview..
    so i added a listview as well

    how ever it fails on bolded, because i think you forgot to post that function/sub

    thanks sooo much for the help hehe
    i thought it would be a easy one 2 three function

  4. #4
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744
    It is the same function that I've posted a while ago. Also, IsArrayDimensioned function is there, but created as Private, because this code was created with 1 form. So, in your case, all you have to do is to change it to Public.

    Regards,

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width