Search code examples
eventsvbams-officefilesystemwatcher

How do I know when a file has been modified in a VBA Macro?


Is there a way to watch a file in VBA (which is essentially VB6), so that I know when the file has been modified? -- similar to this only I don't want to know when a file is unused, just when its modified.

The answers I've found have recommended using "FileSystemWatcher" and the Win32 API "FindFirstChangeNotification". I can't figure out how to use these though, any idea?


Solution

  • Okay, I put together a solution that is able to detect file system changes, in VBA (VB6).

    Public objWMIService, colMonitoredEvents, objEventObject
    
    'call this every 1 second to check for changes'
    Sub WatchCheck()
    On Error GoTo timeout
        If objWMIService Is Nothing Then InitWatch 'one time init'
        Do While True
            Set objEventObject = colMonitoredEvents.NextEvent(1) 
             '1 msec timeout if no events'
            MsgBox "got event"
    
            Select Case objEventObject.Path_.Class
                Case "__InstanceCreationEvent"
                    MsgBox "A new file was just created: " & _
                        objEventObject.TargetInstance.PartComponent
                Case "__InstanceDeletionEvent"
                    MsgBox "A file was just deleted: " & _
                        objEventObject.TargetInstance.PartComponent
                Case "__InstanceModificationEvent"
                    MsgBox "A file was just modified: " & _
                        objEventObject.TargetInstance.PartComponent
            End Select
        Loop
    Exit Sub
    timeout:
        If Trim(Err.Source) = "SWbemEventSource" And Trim(Err.Description) = "Timed out" Then
            MsgBox "no events in the last 1 sec"
        Else
            MsgBox "ERROR watching"
        End If
    End Sub
    

    Copy and paste this sub near the above, it is called automatically if needed to initialize the global vars.

    Sub InitWatch()
    On Error GoTo initerr
        Dim watchSecs As Integer, watchPath As String
        watchSecs = 1 'look so many secs behind'
        watchPath = "c:\\\\scripts" 'look for changes in this dir'
    
        strComputer = "."
        Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
        Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
            ("SELECT * FROM __InstanceOperationEvent WITHIN " & watchSecs & " WHERE " _
                & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
                    & "TargetInstance.GroupComponent= " _
                        & "'Win32_Directory.Name=""c:\\\\scripts""'")
    
        MsgBox "init done"
    Exit Sub
    initerr:
        MsgBox "ERROR during init - " & Err.Source & " -- " & Err.Description
    End Sub