Link to home
Create AccountLog in
Avatar of Clay Willing
Clay WillingFlag for United Arab Emirates

asked on

vba code to check folder size doesn't work on Win 7 PC's

I have an access based file monitor app that basically scans folder sizes to see if they have increased after x seconds (set by form timer property).  Each folder being scanned is being filled with data sniffed from winsockets and creating text files of data received and due to my winsocket program, i can see the data arriving so the data is indeed being stored.  
The code uses the filesystemobject - folder.size property to test for change and works perfectly well on Win XP PC's running Office 2010.  However when i copy the same accdb onto a win 7 machine, the code runs without error but does not detect and therefore update the underlying table.
I also re-wrote the code to iterate through sub folders to get the accumulated and therefore ultimate parent folder size and I get the same effect.  It just refuses to detect any change in the folder size.
Bizarrely, with the code running and showing my form, (a text box shows green if the folder size displayed in the box increases and reverts to red if the size remains the same) and I open a subfolder that I am testing with windows explorer, which shows the latest stored file, i can see the file size in details view change from zero to the proper size and my program responds appropriately.  If I do nothing, again the size reverts to the same as listed previously.  Once again, if I hit F5, the size in Win Ex changes and the program instantly responds.
I initially suspected some form of Windows 7 vaguery, so I borrowed a PC with a completely vanilla install of win 7 and got the same effect.
I have also checked Access references to ensure the scripting objects etc are all the same. Has anyone else come across a similar effect when using the fso?
I will post the detection code when I get back to my other PC.

Kind regards, a rather stumped vba access programmer
Avatar of Mike in IT
Mike in IT
Flag of United States of America image

Perhaps you need to have the code open the explorer (in the background possibly hidden) to the location that it's checking to have it update correctly. At least that's what it sounds like worked in your description. I don't work as much with Access so I don't have any code to provide.
Avatar of Anders Ebro (Microsoft MVP)
Could you show your code?
I have used FSO on windows 7 to get the folder size, although admittedly at startup, not continuously.
ASKER CERTIFIED SOLUTION
Avatar of Jim Dettman (EE MVE)
Jim Dettman (EE MVE)
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Also, you might want to try the built-in VBA verbs to handle this rather than FSO.  DIR() and Filelen() are available.  

Jim.
Avatar of Clay Willing

ASKER

Thanks Jim I definitely think it's to do with the OS. I will have to look up those 2 constructs and see if I can modify the approach but that will have to wait until tomorrow. Will get back to you
However I don't want to check for files because they are only created once an hour and I need to check in close to real time so my guys can react if data is lost.
I had thought of capturing the socket activity instead but I also use lab view to capture some of the data so I need an independent method which was working well on xp
As I left the laptop at work I will have to update you all tomorrow
Thanks so far

E
Here's my code that runs on timer event set in form open sub

As you can see in this version, I iterate through subfolders to check the size.  The original does it at line 1110 with
1110    Param = Round(fsoFolder.Size / 1024, 2)

I also forgot to mention that I have also tested for DateLastAccessed and DateLastModified of the scripting.filesystemobject.  Neither of those would update until the folder was opened in win exp either.
1112    FldAccDate = fsoFolder.DateLastAccessed
1114    FldModDate = fsoFolder.DateLastModified

As you can see this is quite frustrating.

My next step is to investigate this construct instead:
Dim getInfo As System.IO.DirectoryInfo
getInfo = My.Computer.FileSystem.GetDirectoryInfo _
(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
MsgBox("The directory was created at " & getInfo.CreationTime)
MsgBox("The directory was last accessed at " & getInfo.LastAccessTime)
MsgBox("The directory was last written to at " & getInfo.LastWriteTime)

But I don't know what dependencies and references I need in VB to get access to this.....yet

Anyway my working code on an xp box looks like this:

Public Sub CheckFolder()
On Error GoTo CheckFolderErr:
'Close the form
Dim db As Database
Dim rsSize As DAO.Recordset
Dim strSQL As String
Dim strSpeech As String
Dim fso As Object
Dim fsoFolder As Object
Dim fsoSubs As Object
Dim fsosubFld As Object
Dim Ctrl As Control
Dim CtrlName As String
Dim subSize As Double
Dim FinalSub As Double


'    Const strFolderName As String = "C:\My Documents"

1000  Set db = CurrentDb
1010  strSQL = "SELECT * FROM FileSizes WHERE [InUse] = True"
1020  Set rsSize = db.OpenRecordset(strSQL, dbOpenDynaset)
1030  rsSize.MoveFirst
1040 Do While Not rsSize.EOF
1042   subSize = 0
'************Get Folder Path*************
1050  strFilePath = rsSize![FilePath]
'1050  strFileName = rsSize![FileName]      '*******use this line for file size instead
'************Set the previous folder size in the OldSize Field*************
1060  rsSize.Edit
1070  rsSize![OldSize] = rsSize![NewSize]
'1072  txtOldSize.Value = rsSize![OldSize]
1080  rsSize.Update

'************Check how big it is now*************
'1100  Param = FileLen(strFilePath & strFileName) /1024   '*************Use this line for file size instaed
1090    Set fso = CreateObject("Scripting.FileSystemObject")
1100    Set fsoFolder = fso.GetFolder(strFilePath)
1102    Set fsoSubs = fsoFolder.SubFolders
1104      For Each fsosubFld In fsoSubs
1106        subSize = subSize + fsosubFld.Size
1108      Next

1111    FinalParam = FormatNumber(subSize / 1048576, 5)

'************Update the new size field*************
1120  rsSize.Edit
1130  rsSize![NewSize] = FinalParam
'1132  txtNewSize.Value = FinalParam
1140  rsSize.Update

'************Compare values and make alert sound*************
1150  If rsSize![OldSize] = rsSize![NewSize] Then
1160    strSpeech = rsSize![Dataname]
1170    ANNOUNCE (strSpeech)
1180    CtrlName = rsSize![filetrap]
1190    Set Ctrl = Me.Controls(CtrlName)
1200    Ctrl.BackColor = vbRed
1210    If rsSize![fired] = False Then
1220      rsSize.Edit
1230      rsSize![timelost] = Now
1240      rsSize![fired] = True
1250      rsSize.Update
1260    End If
1270  Else
'************If no missing then turn traffic light green and set flag****************
1280    CtrlName = rsSize![filetrap]
1290    Set Ctrl = Me.Controls(CtrlName)
1300    Ctrl.BackColor = vbGreen
1305    Ctrl.Value = rsSize![NewSize]
1310    rsSize.Edit
1320    rsSize![fired] = False
1330    rsSize.Update
1340  End If
1350  rsSize.MoveNext
1360  Loop

9000  rsSize.Close
9010  Set rsSize = Nothing
9020  db.Close
9030  Set db = Nothing
9040  Set fsoFolder = Nothing
9050  Set fso = Nothing

CheckFolderExit:
  Exit Sub
CheckFolderErr:
  FormNametxt = "CheckFolder"
  ProcNametxt = "CheckFolder"
  MsgBox "There has been an error.  Please report it to Developer." & vbCrLf & "Error Produced was " & Err.Number & " = " & Err.Description, vbExclamation
  Call ErrorCheck(FormNametxt, ProcNametxt)
  GoTo CheckFolderExit
End Sub

Open in new window

Hmmmm.......

Looking at directoryinfo, getdirectoryinfo via the filesystem object is not recognised by the access debugger and tells me it is a user defined type not recognised.  Annoying.

Mike In IT:
opening the parent folder that i was testing the size of has no effect, it has to be the last folder that contains the last file that is being written to to update correctly.  Using your suggestion I would have to open win exp and get it to refresh each subfolder after finding a way to find out which was the last one created each time.

Can someone help me understand how to get access to the FileSystemInfo Class in vba?  In here it describes a method to refresh the class as otherwise the data such as we are trying to get from the code above will be out of date.

Alternatively I think I am onto something here if I can find a refresh method for the fso class then i have a solution for my code above.
Jim,  I have assigned you as the best solution.  Ultimately, it is the underlying OS which has floored my code and I am going to adjust my approach.  I am either going down the system file IO constructs to use an updated method of the current one or I will modify some of the data capture code to light a traffic light using winsockets.  I use them to capture port traffic from TCP sources and create the analysis data, I will need to do the same for the UDP based ports too which may prove to be more challenging.