2015-07-03 7 views
5

Ich möchte einen Wert überwachen und eine E-Mail-Benachrichtigungen erhalten, wenn bestimmte Bedingungen erfüllt sind. Ich habe ein Makro wie folgt:Wie bekomme ich VBA Macro, um kontinuierlich im Hintergrund zu laufen?

Do While True 

    Worksheet.Calculate 

    If Value > 10 Then 
     SendEmail 
    End If 

    Sleep 60*CLng(1000) 

Loop 

Allerdings, wenn ich dies ausführen, verstopft es das gesamte Programm und schaltet nicht mehr reagiert, wenn ich versuche, etwas zu tun.

Gibt es das trotzdem, aber muss es im Hintergrund laufen oder zumindest nicht das Programm zum Absturz bringen?

Was ich vorher tat war mit VBScript, um eine nicht sichtbare Tabelle zu öffnen und das VBScript lief kontinuierlich im Hintergrund die Bedingung und funktionierte gut, aber mein Client möchte wirklich eine GUI und dafür im Programm selbst sein .

Irgendwelche Gedanken?

+0

Wenn Sie den Wert einer Zelle überwachen müssen, müssen Sie nicht ständig einen Code ausführen, sondern das Änderungsereignis des Arbeitsblatts verwenden. –

+0

@ MátéJuhász Ich glaube nicht, dass sich der Wert von alleine ändern wird. Es muss dazu aufgefordert werden. Ich aktualisiere den Beispielcode. Kann ich das Änderungsereignis des Arbeitsblatts weiterhin verwenden? –

+0

Werfen Sie einen Blick hier: http://www.mrexcel.com/forum/excel-questions/79144-automatical-update-time-date.html, könnte es für Sie nützlich sein. –

Antwort

6

Verwenden Sie die Methode Application.OnTime, um einen Code zu planen, der in einer Minute ausgeführt wird.

Ihr Code wird so etwas wie diese (ungetestet) aussehen:

Sub CreateNewSchedule() 
    Application.OnTime EarliestTime:=DateAdd("n", 1, Now), Procedure:="macro_name", Schedule:=True 
End Sub 

Sub macro_name() 

    If Value > 10 Then 
     SendEmail 
    Else 
     CreateNewSchedule 
    End If 

End Sub 

Sie könnten die Zeit des nächsten Zeitplan in einer globalen Variablen gespeichert werden sollen, so dass das Workbook_BeforeClose Ereignis den nächsten Zeitplan abbrechen. Andernfalls wird Excel die Arbeitsmappe erneut öffnen.

Public nextScheduledTime As Date 

Sub CreateNewSchedule() 
    nextScheduledTime = DateAdd("n", 1, Now) 
    Application.OnTime EarliestTime:=nextScheduledTime , Procedure:="macro_name", Schedule:=True 
End Sub 

Sub macro_name() 

    If Value > 10 Then 
     SendEmail 
    Else 
     CreateNewSchedule 
    End If 

End Sub 

Private Sub Workbook_BeforeClose(Cancel As Boolean) 
On Error Resume Next 
    Application.OnTime EarliestTime:=nextScheduledTime, Procedure:="macro_name", Schedule:=False 
End Sub 

Sie können dann weiterhin Excel zwischen den geplanten Zeiten verwenden.

+0

Danke. Ihre 'CreateNewSchedule' Funktion funktioniert perfekt. Ich wusste nichts von dieser Funktion –

1

Ich denke, Sie müssen den Application Event Stack mit einem DoEvents Aufruf speziell verarbeiten. Dies ermöglicht Benutzerinteraktionen mit der Tabelle, wobei normalerweise das Makro Vorrang hat. Sie Code würde in etwa so aussehen:

Do While True 

    If Value > 10 Then 
     SendEmail 
    End If 

    Sleep 60*CLng(1000) 

    DoEvents 
Loop 

Sie auch eine grafische Benutzeroberfläche mit HTA konstruieren könnte, wenn Sie mit VBScript bleiben wollte.

+2

Eine andere Möglichkeit besteht darin, ein Makro so einzurichten, dass es bei jeder Änderung der Tabelle ausgeführt wird. –

+0

Ja, das ist eine bessere Lösung, um ehrlich zu sein, weil Sie hier immer noch eine Lock-up-Funktion für die Anwendung als Ergebnis des Schlafbefehls bekommen, denke ich. Ich schlage vor, Sie posten es als Antwort auf diese Frage - ich würde es aufheben :-). Das einzige Problem würde kommen, wenn keine Benutzerinteraktion stattfand, aber eine Mail gesendet werden musste. In diesem Fall, wenn der Befehl "sleep" nicht wirklich etwas takt, könnten Sie ihn auf 33ms oder etwas Nicht-Bemerkenswertes reduzieren. – Orphid

+0

@HolmesIV, siehe meine Antwort in den obigen Kommentaren. –

Verwandte Themen