From: MP on 24 Nov 2008 14:27 I'm trying to use cFileSearch cls but am doing something wrong getting the correct subdirectory when searchdepth = -1 (all sub dirs) I'm getting back filenames where the file is out of sync with the folder in which it really exists oFileSearch.search oFileSearch.BuildTreeIndexes For i = 0 To oFileSearch.DirsCount - 1 With oFileSearch.DirsTree(i) For N = 0 To .FoundFilesCount - 1 colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name Next N End With Next i anyone see what I'm doing wrong? thanks mark 'filtering for files *.dwg Public Function DwgsInFolder(FolderName As String, _ Optional FileNameMatch As String, _ Optional lSearchDepthMax As Long = -1) _ As Collection On Error GoTo GetDwgsInFolder2_Error Dim bSuccess As Boolean Dim oFileSearch As CFileSearch Dim colRtn As Collection Dim i As Long, N As Long Set oFileSearch = New CFileSearch Set colRtn = New Collection If Len(FolderName) = 0 Then GoTo ExitHere End If If FolderExists(FolderName) Then oFileSearch.StartPath = FolderName End If 'SearchDepthMax constrains the search depth. 'Possible Values: '<0: no search depth constraint, all dirs below the start dir are searched '0 : only the start dir is scanned '1 : the start dir and its subdirs are scanned '2 : the start dir, its subdirs and their subdirs are scanned 'n : and so on oFileSearch.SearchDepthMax = lSearchDepthMax If FileNameMatch = "*" Or FileNameMatch = "*.*" Then oFileSearch.FileNameFilter = "*.dwg" ElseIf Len(FileNameMatch) > 0 Then If Not Right$(FileNameMatch, 4) = ".dwg" Then oFileSearch.FileNameFilter = FileNameMatch & "*.dwg" End If Else oFileSearch.FileNameFilter = "*.dwg" End If oFileSearch.search oFileSearch.BuildTreeIndexes ' LogEntry "oFileSearch.FoundFilesCount ", oFileSearch.FoundFilesCount For i = 0 To oFileSearch.DirsCount - 1 DoEvents With oFileSearch.DirsTree(i) For N = 0 To .FoundFilesCount - 1 colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name Next N End With Next i Set DwgsInFolder = colRtn ExitHere: On Error GoTo 0 Exit Function GetDwgsInFolder2_Error: LogError ProcName Resume ExitHere End Function
From: MP on 24 Nov 2008 17:46 think i got it i needed DirIdxFromTreeIdx For i = 0 To oFileSearch.DirsCount - 1 With oFileSearch.DirsTree(i) lDirIdx = oFileSearch.DirIdxFromTreeIdx(i) sThisFolder = oFileSearch.GetDirPath(lDirIdx, True) For N = 0 To .FoundFilesCount - 1 colRtn.Add sThisFolder & "\" & .FoundFiles(N).Name Next N End With Next i "MP" <NoSpam(a)Thanks.com> wrote in message news:OyLglqmTJHA.4680(a)TK2MSFTNGP06.phx.gbl... > I'm trying to use cFileSearch cls but am doing something wrong getting the > correct subdirectory > when searchdepth = -1 (all sub dirs) > I'm getting back filenames where the file is out of sync with the folder > in which it really exists > > oFileSearch.search > oFileSearch.BuildTreeIndexes > For i = 0 To oFileSearch.DirsCount - 1 > With oFileSearch.DirsTree(i) > For N = 0 To .FoundFilesCount - 1 > colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name > Next N > End With > Next i > > anyone see what I'm doing wrong? > thanks > mark > > 'filtering for files *.dwg > snip >
From: Ulrich Korndoerfer on 24 Nov 2008 18:11 Hi, MP schrieb: > I'm trying to use cFileSearch cls but am doing something wrong getting the > correct subdirectory > when searchdepth = -1 (all sub dirs) > I'm getting back filenames where the file is out of sync with the folder in > which it really exists > > oFileSearch.search > oFileSearch.BuildTreeIndexes > For i = 0 To oFileSearch.DirsCount - 1 > With oFileSearch.DirsTree(i) > For N = 0 To .FoundFilesCount - 1 > colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name > Next N > End With > Next i > > anyone see what I'm doing wrong? > thanks > mark > You should use colRtn.Add oFileSearch.GetDirPath(oFileSearch.DirIdxFromTreeIdx(i)) _ & "\" & .FoundFiles(N).Name In your loop you use an index i to adress an dir entry in the DirsTree view of the Dirs list (by using oFileSearch.DirsTree(i)), but then to return the dirs path you use the same index to address a directory in the Dirs list (by using oFileSearch.GetDirPath(i)). However GetDirPath expects an index adressing an entry in the Dirs list, not an index for the DirsTree view on the Dirs list! So for GetDirPath in your case you must use oFileSearch.DirIdxFromTreeIdx(i) to "translate" an DirsTree index to a Dirs index. Please note (copied from the accompanying source code of CFileSearch): <cite> 'The Dirs list holds in its name member only the name of the dir. 'To get the path to the dir, call GetDirPath. *DirIdx must be an 'index to the Dirs list.* 'If AbsPath is True, it returns a path starting with StartPath, 'that is an absolute path to the dir, otherwise it returns a 'relative path starting with StartDir. 'The returned path does not have a trailing backslash! Public Function GetDirPath(ByVal DirIdx As Long, _ Optional ByVal AbsPath As Boolean = True) As String .... End Function .... 'Use it to get an index to the Dirs list from an index to 'the DirsTree view. Both indexes then reference the same dir. Public Property Get DirIdxFromTreeIdx(ByVal DirTreeIdx As Long) As Long .... End Property .... 'Use it to get an index to the DirsTree view from an index 'to the Dirs list. Both indexes then reference the same dir. Public Property Get TreeIdxFromDirIdx(ByVal DirIdx As Long) As Long .... End Property </cite> Some background information (also explained in the comments of CFileSearch's source code): CFileSearch during a search collects all found directories in an array (I call it the Dirs list), *in the order they are detected during search*. Each method or property named Dirs* or having an index parameter named DirIdx uses and adresses entries in this array. However the order the directories appear in the Dirs list is *not* reflecting the hierarchical order the dirs have in your filesystem, because the search algorithm first collects all subdirs in a dir, then collects the subdirs of the subdirs. For example for a startdir StartDir: StartDir SubDir1 SubSubDir SubDir2 the Dirs list after a full search has the entries Index 0: StartDir Index 1: SubDir1 Index 2: SubDir2 Index 3: SubSubDir For getting a directory list reflecting the hierarchical order, one has to call after a search BuildTreeIndexes (that is what you did). This creates an index array for the Dirs list like such: Index 0: 0 (points to StartDir) Index 1: 1 (points to SubDir1) Index 2: 3 (points to SubSubDir) Index 3: 2 (points to SubDir2) You iterate over this sequence by using DirsTree(i). Therefore for eg. i = 2 you get the dir data of the dir SubSubDir. Then you use the same index i for getting the dir's path by calling GetDirPath(i). However GetDirPath uses the Dirs list and therefore for i = 2 returns the path for the dir SubDir2, and you got a mismatch. I choose to implement CFileSearch in such a way ("breadth first" search) because of performance reasons. Doing not a "drill down first" or "depth first" search is faster. In many cases the user is not interested in the hierarchical order of the dirs, eg. if he just searches for some files, so a "depth first" algorithm would be overkill. However, if needed, the user also can have the dirs sorted in their hierarchical order. This can be achieved by calling BuildTreeIndexes, which generates an index array using a recursive algorithm. This one is very fast as it just shuffles around some long values. In fact I believe doing a "breadth first" search first and then create an index array is faster than doing a "depth first" search. My approach of course needs some memory for the additional index array, but the additional memory requirements are low: eg. for 10000 dirs 40000 Bytes. The result is: CFileSearch has two methods for accessing dir data: one using the Dirs list, expecting a DirIdx index and one using the DirsTree view, expecting a DirTreeIdx index. AFAIR GetDirPath is the only method which only works with DirIdx and does not have a DirTreeIdx counter part. However the two properties DirIdxFromTreeIdx and TreeIdxFromDirIdx at any time allow translation, so for methods using the Dirs list only a DirTreeIdx can be used by calling DirIdxFromTreeIdx and vice versa. Hope that did remove some possible confusion :-) Btw, I have a newer, unpublished version of CFileSearch. May be I will publish it on my web site in the next weeks. I could add a GetDirPath property using the dirs tree view for the users convenience. -- Ulrich Korndoerfer VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
From: MP on 24 Nov 2008 18:39 thanks Ulrich, I found that a while ago just before your reply, sorry, I should have seen that in the comments before posting. But thanks for the additional info and thanks for the great class. mark "Ulrich Korndoerfer" <ulrich_wants_nospam(a)prosource.de> wrote in message news:%23OOp2noTJHA.3952(a)TK2MSFTNGP06.phx.gbl... > Hi, > > MP schrieb: > >> I'm trying to use cFileSearch cls but am doing something wrong getting >> the correct subdirectory >> when searchdepth = -1 (all sub dirs) >> I'm getting back filenames where the file is out of sync with the folder >> in which it really exists >> >> oFileSearch.search >> oFileSearch.BuildTreeIndexes >> For i = 0 To oFileSearch.DirsCount - 1 >> With oFileSearch.DirsTree(i) >> For N = 0 To .FoundFilesCount - 1 >> colRtn.Add oFileSearch.GetDirPath(i) & "\" & .FoundFiles(N).Name >> Next N >> End With >> Next i >> >> anyone see what I'm doing wrong? >> thanks >> mark >> > > You should use > > colRtn.Add oFileSearch.GetDirPath(oFileSearch.DirIdxFromTreeIdx(i)) _ > & "\" & .FoundFiles(N).Name > > In your loop you use an index i to adress an dir entry in the DirsTree > view of the Dirs list (by using oFileSearch.DirsTree(i)), but then to > return the dirs path you use the same index to address a directory in the > Dirs list (by using oFileSearch.GetDirPath(i)). However GetDirPath expects > an index adressing an entry in the Dirs list, not an index for the > DirsTree view on the Dirs list! So for GetDirPath in your case you must > use oFileSearch.DirIdxFromTreeIdx(i) to "translate" an DirsTree index to a > Dirs index. > > Please note (copied from the accompanying source code of CFileSearch): > > <cite> > > 'The Dirs list holds in its name member only the name of the dir. > 'To get the path to the dir, call GetDirPath. *DirIdx must be an > 'index to the Dirs list.* > > 'If AbsPath is True, it returns a path starting with StartPath, > 'that is an absolute path to the dir, otherwise it returns a > 'relative path starting with StartDir. > > 'The returned path does not have a trailing backslash! > > Public Function GetDirPath(ByVal DirIdx As Long, _ > Optional ByVal AbsPath As Boolean = True) As String > ... > End Function > > ... > > 'Use it to get an index to the Dirs list from an index to > 'the DirsTree view. Both indexes then reference the same dir. > > Public Property Get DirIdxFromTreeIdx(ByVal DirTreeIdx As Long) As Long > ... > End Property > > ... > > 'Use it to get an index to the DirsTree view from an index > 'to the Dirs list. Both indexes then reference the same dir. > > Public Property Get TreeIdxFromDirIdx(ByVal DirIdx As Long) As Long > ... > End Property > > </cite> > > Some background information (also explained in the comments of > CFileSearch's source code): > > CFileSearch during a search collects all found directories in an array (I > call it the Dirs list), *in the order they are detected during search*. > Each method or property named Dirs* or having an index parameter named > DirIdx uses and adresses entries in this array. > > However the order the directories appear in the Dirs list is *not* > reflecting the hierarchical order the dirs have in your filesystem, > because the search algorithm first collects all subdirs in a dir, then > collects the subdirs of the subdirs. > > For example for a startdir StartDir: > > StartDir > SubDir1 > SubSubDir > SubDir2 > > the Dirs list after a full search has the entries > > Index 0: StartDir > Index 1: SubDir1 > Index 2: SubDir2 > Index 3: SubSubDir > > For getting a directory list reflecting the hierarchical order, one has to > call after a search BuildTreeIndexes (that is what you did). This creates > an index array for the Dirs list like such: > > Index 0: 0 (points to StartDir) > Index 1: 1 (points to SubDir1) > Index 2: 3 (points to SubSubDir) > Index 3: 2 (points to SubDir2) > > You iterate over this sequence by using DirsTree(i). Therefore for eg. i = > 2 you get the dir data of the dir SubSubDir. Then you use the same index i > for getting the dir's path by calling GetDirPath(i). However GetDirPath > uses the Dirs list and therefore for i = 2 returns the path for the dir > SubDir2, and you got a mismatch. > > I choose to implement CFileSearch in such a way ("breadth first" search) > because of performance reasons. Doing not a "drill down first" or "depth > first" search is faster. In many cases the user is not interested in the > hierarchical order of the dirs, eg. if he just searches for some files, so > a "depth first" algorithm would be overkill. > > However, if needed, the user also can have the dirs sorted in their > hierarchical order. This can be achieved by calling BuildTreeIndexes, > which generates an index array using a recursive algorithm. This one is > very fast as it just shuffles around some long values. In fact I believe > doing a "breadth first" search first and then create an index array is > faster than doing a "depth first" search. My approach of course needs some > memory for the additional index array, but the additional memory > requirements are low: eg. for 10000 dirs 40000 Bytes. > > The result is: CFileSearch has two methods for accessing dir data: one > using the Dirs list, expecting a DirIdx index and one using the DirsTree > view, expecting a DirTreeIdx index. AFAIR GetDirPath is the only method > which only works with DirIdx and does not have a DirTreeIdx counter part. > However the two properties DirIdxFromTreeIdx and TreeIdxFromDirIdx at any > time allow translation, so for methods using the Dirs list only a > DirTreeIdx can be used by calling DirIdxFromTreeIdx and vice versa. > > Hope that did remove some possible confusion :-) > > Btw, I have a newer, unpublished version of CFileSearch. May be I will > publish it on my web site in the next weeks. I could add a GetDirPath > property using the dirs tree view for the users convenience. > > -- > Ulrich Korndoerfer > > VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
|
Pages: 1 Prev: How to get server Time Next: ImmGetDescription to find out Japanese IME |