acsyscmdsetstatus with for each loop

Spawn

New member
Local time
Today, 09:06
Joined
Oct 14, 2015
Messages
4
Hi Everyone,

I am counting files using below code and I want to show how many files counted in system status bar using syscmd acsyscmdsetstatus. However, as this is For Each loop when I use syscmd acsyscmdsetstatus it resets to 0 for each sub folder. How should I modify the code to keep counting files and not reset to 0? I could use something like gCount = gCount + 1, acsyscmdsetstatus, gCount with "Do loop" but for "for each" it doesn't work.

Code:
Private Function CountFiles_FolderAndSubFolders(strFolder As String, Optional strExt As String) As Double
'Author          : Ken Puls
'Function purpose: To count files in a folder and all subfolders.  If a file extension is provided,
'   then count only files of that type, otherwise return a count of all files.
     Dim objFso As Object
    Dim objFiles As Object
    Dim objSubFolder As Object
    Dim objSubFolders As Object
    Dim objFile As Object
    
    'Set Error Handling
    On Error GoTo EarlyExit
     'Create objects to get a count of files in the directory
    Set objFso = CreateObject("Scripting.FileSystemObject")
    Set objFiles = objFso.GetFolder(strFolder).Files
    Set objSubFolders = objFso.GetFolder(strFolder).SubFolders
    
    'Count files (that match the extension if provided)
    If strExt = "All" Then
        CountFiles_FolderAndSubFolders = objFiles.count
    Else
        For Each objFile In objFiles
            If UCase(Right(objFile.path, (Len(objFile.path) - InStrRev(objFile.path, ".")))) = UCase(strExt) Then
                CountFiles_FolderAndSubFolders = CountFiles_FolderAndSubFolders + 1
            End If
        Next objFile
    End If
     'Request count of files in subfolders
    'Do
    SysCmd acSysCmdSetStatus, CountFiles_FolderAndSubFolders
    For Each objSubFolder In objSubFolders
        CountFiles_FolderAndSubFolders = CountFiles_FolderAndSubFolders + _
        CountFiles_FolderAndSubFolders(objSubFolder.path, strExt)
    Next objSubFolder
    DoEvents
    'Loop While objSubFolder <> vbNullString
     
EarlyExit:
    'Clean up
    On Error Resume Next
    Set objFile = Nothing
    Set objFiles = Nothing
    Set objFso = Nothing
 
Hi. Welcome to the forum.

This is a recursive function, right, which is to say it calls itself. So I think you have two options to maintain a counter through those recursive calls, is pass the value in to the function directly, or update a variable with a scope that is global to all the function calls. Maybe the first suggestion is self evident, but for the my second suggestion, consider this code . . .

Code:
dim counter as integer

sub recur()
   if counter < 10 then 
      counter = counter + 1
      recur
   else
      msgbox counter
   end if
end sub
. . . so see how the variable "counter" is global to all instances of this routine as they pile up in the call stack? Contrast with . . .
Code:
sub recur()
[COLOR="Red"]   dim counter as integer[/COLOR]
   if counter < 10 then 
      counter = counter + 1
      recur
   else
      msgbox counter
   end if
end sub
. . . which is an infinite loop because "counter" never exceeds 1.
 
Thank you for your reply MarkK.

I am working on implementing your suggestion.

Cheers!
 
OK. I gave up. My problem here is that I do not know how many files will be counted that's why I cannot give value for "counter < 10". Maybe I understood it wrong.

I call recur sub from my Private Function that counts files and this time it counts without resetting to 0 but counts wrong (let's say, instead of 55 counts 181).

Here is my modified code for counting:
Code:
Private Function CountFiles_FolderAndSubFolders(strFolder As String, IncludeSubfolders As Boolean, strExt As String) As Double
'Author          : Ken Puls
'Function purpose: To count files in a folder and all subfolders.  If a file extension is provided,
'   then count only files of that type, otherwise return a count of all files.
     Dim objFso As Object
    Dim objFiles As Object
    Dim objSubFolder As Object
    Dim objSubFolders As Object
    Dim objFile As Object
    
    'Set Error Handling
    On Error GoTo EarlyExit
     'Create objects to get a count of files in the directory
    Set objFso = CreateObject("Scripting.FileSystemObject")
    Set objFiles = objFso.GetFolder(strFolder).Files
    Set objSubFolders = objFso.GetFolder(strFolder).SubFolders
    
    'Count files (that match the extension if provided)
    If strExt = "*.*" Then
        CountFiles_FolderAndSubFolders = objFiles.count
    Else
        For Each objFile In objFiles
            If UCase(Right(objFile.path, (Len(objFile.path) - InStrRev(objFile.path, ".")))) = UCase(strExt) Then
                CountFiles_FolderAndSubFolders = CountFiles_FolderAndSubFolders + 1
            End If
        Next objFile
    End If
     'Request count of files in subfolders
    If IncludeSubfolders Then
    For Each objSubFolder In objSubFolders
        CountFiles_FolderAndSubFolders = CountFiles_FolderAndSubFolders + CountFiles_FolderAndSubFolders(objSubFolder.path, True, strExt)
    Next objSubFolder
    End If
    DoEvents
    [COLOR=red][B][U]recur[/U][/B][/COLOR]
    
EarlyExit:
    'Clean up
    On Error Resume Next
    Set objFile = Nothing
    Set objFiles = Nothing
    Set objFso = Nothing
    On Error GoTo 0
End Function

Sub to count:
Code:
Sub recur()
counter = counter + 1
SysCmd acSysCmdSetStatus, counter
End Sub

And I was wondering if I can refer to "CountFiles_FolderAndSubFolders" directly without creating another sub?
 
So in that case a workable pattern might be . . .
Code:
private m_files as long

function countFiles(folder) as long
   m_files = 0
   fcount folder
   countFiles = m_files
end function

private fcount(folder)
   for each file in folder.files
      m_files = m_files + 1
   next

   for each subfolder in folder.folders
      fcount subfolder
   next
end sub
 
Air code has omitted the Sub, Mark.

Should be
private Sub fcount(folder)
 
Thanks Cronk. Yeah, my air compiler didn't catch that one . . . :)
 

Users who are viewing this thread

Back
Top Bottom