Outlook VBA sleep - alternative oder Threaded?

Diskutiere Outlook VBA sleep - alternative oder Threaded? im Developer Network Forum im Bereich Hardware & Software Forum; Hoi Kollegen, ich hab eine Outlookmakro gebaut welches mir immer wieder eine Meldung ausgeben soll, also das Makro sollte alle XX Minuten einmal...
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #1
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
Hoi Kollegen,

ich hab eine Outlookmakro gebaut welches mir immer wieder eine Meldung ausgeben soll, also das Makro sollte alle XX Minuten einmal durchlaufen.

Ich wollte es über eine Schleife lösen, die jeweils für 10 min angehalten wird, wenn ich aber den Sleep von den kernel32.dll benutze, dann hängt das komplette Outlook. Gibt es hier alternativen?
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #2
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Ja, Alternativen gibts...
Hmmm... es gab die Möglichkeit eine externe Betriebssystem DLL anzuziehen mittels derer man die "Wartezeit" einstellen konnte, ohne den Thread komplett zu blockieren. War ne schöne und elegante Art das zu realisieren.
Muss mal nachschauen ob ich das auf die schnelle finde, ist schon ewig her dass ich das mal verwendet hatte. Kann Dir auf Anhieb auch leider nicht mehr sagen wie die dll hies, werde aber mal googlen, vielleicht finde ich sie.

Gruss
Sperber



//EDIT:
Eine meiner Meinung nach weniger schöne Möglichkeit wäre etwas in dieser Art und Weise, Code wurde einfach kopiert also den Feinschliff müsstest Du selbst übernehmen:
Public Sub Scrolling()
Label1.Left = Me.Width
Do
Sleep 100
DoEvents
Loop Until ???
End Sub

Ich finde es ..ähm...naja
Augenmerk gilt der DoEvents, nachzulesen in der MSDN ;)



//EDIT2
Finde es leider nicht auf die Schnelle. Könnte aber sein dass ich den Code noch im Geschäft habe, falls Interesse daran besteht könnte ich Montag oder Dienstag mal nachschauen?
Die Woche habe ich noch Urlaub :D
 
Zuletzt bearbeitet:
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #3
peterfido

peterfido

Bekanntes Mitglied
Dabei seit
16.02.2000
Beiträge
1.785
Reaktionspunkte
0
Ort
Berlin
Sleep hält die komplette Anwendung an, sodass keine Rechenzeit mehr dafür zur Verfügung steht, deswegen kann man sich den DoEvents sparen. Dieser ist nützlich in Endlosschleifen oder loops. Das wäre mein Ansatz:

gettickcounts merken in einer do loop Schleife vergleichen und bei Überschreitung weitermachen.

Bin grad nicht zu Hause also hier nur mal das Schema:

public Function pause(byval Zeit as long)

dim akttick as long
dim x as integer

akttick = gettickcount
do while gettickcount < akttick+zeit
x=x+1
if x >100 then
doevents
x=0
endif

loop
end function

die gettickcount declaration musst du dir noch raussuchen.
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #4
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
erstmal vielen vielen Dank!

@Sperber, das einzige was ich von der Windoof Apig gefunden habe war die kernel32.dll, welche eine Sleep methode stellt, welcher zwar keine Rechenzeit schluckt aber trozdem wird Outlook selber blockiert.
Wär super wenn du kurz und nach dem Src schaun könntest.
Es reicht nächste Woche noch allemal.

@peterfido
Über deine Lösung mach ich mich später noch schlau :)
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #5
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
peterfido:
Wo liegt der Unterschied zu meinem Beispiel??
Hab ja gesagt dass er die Sleep Methode richtig konfigurieren muss und der code lediglich reinkopiert wurde. Hab hier privat ebenfalls keine Entwicklungsumgebung...

Dein Codebeispiel würde (wenn ich das richtig sehe) ziemlich viel CPU Leistung verbrauchen, es wäre somit entsprechend unelegant.
In meinem Beispiel müsste die Zeit entsprechend klein gewählt werden, somit wäre Outlook nicht vollends blockiert, sondern nur für die gewählte Dauer. Das könnten beispielsweis 200ms oder 500ms oder... sein, muss man halt etwas austesten... Dank der DoEvents hätten andere Threads/Prozesse alle 200 oder 500 ms Zeit Ihre Arbeit zu verrichten, was wiederum zu geringerem CPU Verbrauch führt. Immerhin soll Outlook nicht sämtliche CPU Resourcen aufbrauchen, andere Applikationen sollten ebenfalls noch arbeitsfähig sein :D

DAs von mir gepostete Beispiel ist nicht die komplette Lösung bzw. der Code den er exakt benötigt, es soll lediglich veranschaulichen wie man den Timer mit der DoEvents aufbauen müsste.

Ich möchte nochmal erwähnen... für wirklich schön halte ich das nicht.

@PsiTrax
Ich werde nächste Woche mal nachschauen... ist auch möglich dass es lediglich ne andere Methode der kernel32.dll war die man verwenden kann.
Auf jeden Fall war es bedeutend sauberer und eleganter gelöst.

Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #6
peterfido

peterfido

Bekanntes Mitglied
Dabei seit
16.02.2000
Beiträge
1.785
Reaktionspunkte
0
Ort
Berlin
Stimmt, im Ablauf gibt es keinen Unterschied. Aber es muss eine Lösung geben. Wenn man z.B. mal das Autosave AddIn von Excel analysieren könnte, welches ja auch nur alle x Minuten fragt, ob es speichern soll...

Vielleicht ist das hier http://www.excel-vba.de/3_1_1.htm hilfreich.
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #7
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Sehr interessant, ich denke damit kannst du recht einfach Deinen Timer realisieren.

Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

Private Declare Function
KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

Das Makro ist recht einfach... schau's Dir mal das erste Beispiel (Timer in VBA, Laufende Uhrzeit in Zelle) selbst an, es besitzt eigentlich fast alles wa Du benötigst und wenn was unklar ist, dann kannst Du detailliert nachfragen.

Du kannst den Zähler benutzen um herauszufinden wieviel Zeit verstrichen ist. (siehe Variable lngZaehler)

Wie definierst Du, wann das Makro starten soll?? Nach so und soviel Minuten??

Dann müsstest Du lediglich in der Methode "TimerAnzeige" im Excel Makro eine Abfrage einbauen, ob der Zähler dem von Dir definierten Kriterium entspricht und die entsprechend gewünschte Aktion/Funktionalität aufrufen (wozu auch immer Dein Makro dienen soll), den Timer anschliessend zurücksetzen.



Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #8
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
ich bin halt echt zu blöd für diesen microsoft scheiss
oder ich steh einfach nur am Schlauch.

Naja hier mal mein Code

Code:
Private Declare Function SetTimer Lib "user32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Const WM_TIMER = &H113 ' Timer-Ereignis trifft ein <-- kan plan was das auch immer is

Sub doCheck(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
MsgBox("hallo")
End Sub

' Startet den Timer
Public Function EnableTimer(ByVal msInterval As Long)
  If hEvent <> 0 Then Exit Function
  hEvent = SetTimer(0&, 0&, msInterval, AddressOf doCheck)
End Function


' Beendet den Timer
Public Function DisableTimer()
  If hEvent = 0 Then Exit Function
  KillTimer 0&, hEvent
  hEvent = 0
End Function
Sub Application_Startup()
	EnableTimer 1000
End Sub

Also Application_Startup() wird aufgerufen sobald ich mein Outlook öffne
dann soll bis es geschlossen wird alle paar Min das Fenster aufpoppen.

Wenn ich das aber so starte wie oben gepostet, dann passiert einfach garnix.

Vielen Dank für eure Mühen!!!
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #9
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Code:
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

'Intervall festlegen (Millisekunden; 1000 ms = 1 s):
Private Const lngIntervall As Integer = 5000

Private lngTimer As Long
Private lngZaehler As Long

Dim blnTimerActive As Boolean


Private Sub stopTimer()
	' stop timer und reset "timer aktiv"
	Call KillTimer(0, lngTimer): blnTimerActive = False
End Sub

Private Function startTimer() As Long
	' Timer starten und Methode executeAction ausführen sobald der Timer intervall erreicht wurde
	startTimer = SetTimer(0, 0, lngIntervall, AddressOf executeAction): blnTimerActive = True
End Function



'Festlegen, was im festgelegten Intervall passieren soll:
Private Sub executeAction(ByVal hWnd&, ByVal Msg&, ByVal idEvent&, ByVal dwTime&)

	' hier die geweünschte Aktion ausführen, Popup oder ...
	Debug.Print lngZaehler
	lngZaehler = lngZaehler + 1

End Sub


' beim Outlook Start den Timer aktivieren
Sub outlookStart()
	
	' Timer start falls nicht bereits aktiv
	If blnTimerActive = True Then
		stopTimer
	End If
	' Timer starten
	lngTimer = startTimer()

End Sub

' beim Outlook beenden oder bei... den Timer zerstören, Resourcen freigeben
Sub outlookEnd()
	If blnTimerActive = True Then
		stopTimer
		lngZaehler = 0
	End If
End Sub

Alles klar? Kurz und rudimentär... sollte aber Deine Frage beantworten.

Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #10
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
Vielen Dank Sperber!!!

Aber leider muss ich mitteilen, dass einfach nix passiert.
Also der ruft die Sub executeAction einfach net auf :(
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #11
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Der Code der outlookStart muss Du dort verwenden, wo Du das Ganze starten willst. Also dort, wenn Du Dein Marko oder was auch immer das erste mal startest/anstösst.

Der Code der outlookEnd musst Du dort einbauen wo Du das Ganze beenden/stoppen willst.

In der executeAction musst Du das implementieren, was bei Ablauf der Timerzeit bzw. des Intervalls geschehen soll, zum Beispiel Öffnen eines Popups oder ...

Derzeit ist ein Intervall von 5 Sekunden eingestellt, den Wert muss Du entsprechend Deinen Wünschen korrigieren

Das Ganze habe ich in einem Excelsheet getestet da der dortige Script Editor zuhause meine einzige Entwicklungsumgebung ist und es funktioniert einwandfrei ;) .

Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #12
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Ergänzung:
Um das nochmal deutlich zu formulieren:
Du rufst die Methode executeAction NICHT manuell auf, das wird vom Timer selbst erledigt.
Du musst lediglich dafür Sorgen dass der Timer gestartet wird (Siehe Code in der Methode outlookStart() )

Was auch immer geschehen soll, muss in executeAction() implementiert werden oder es muss dort eben die Methode aufgerufen werden, die das Popup oder... öffnet

Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #13
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
ja soweit hab ich das verstanden.
wenn ich debugge läuft der auch den timer-start ab nur wird eben nach den 5 sek die executeAction() nicht aufgerufen.

kannst du es vllt doch noch in outlook probiern?
vielleicht sind die VBA-APIs ja doch unterschiedlich ?!?
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #14
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Ich habe das Outlook 2002 und da funktioniert es.
Hab den Code 1:1 reinkopiert, bis auf eine kleine Modifikation, woraufhin die Methoden outlookStart und outlookEnd als ausführbare Makros auftauchen

Anschliessend habe ich "von Hand" die outlookStart ausgeführt ... und später mit outlookEnd beendet.

Die Modifikation
Ich habe den Interall auf 10 Sekunden eingestellt und in executeAction() ne Messagebox eingebaut damit ich überhaupt was sehe.
Funktioniert einwandfrei, alles Andere hätte ehrlich gesagt verwundert zumal wir hier sowieso kein outlookspezifisches API verwenden sondern ein Externe DLL.

Kontrolliere mal die Sicherheitsstufe Deiner Makros. Wenn die auf Hoch steht, dann blockierst Du automatische eine Ausfürhung.

Kopiere weiterhin mal den Code 1:1 wie Du ihn verwendest (falls es nicht zuviel ist) und poste ihn hier
Alternativ kannst Du den Code in eine/mehrere Textdateien kopieren, zippen und hier posten

Gruss
Sperber
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #15
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
ich bin echt überfordert

Code:
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

'Intervall festlegen (Millisekunden; 1000 ms = 1 s):
Private Const lngIntervall As Integer = 2000

Private lngTimer As Long
Private lngZaehler As Long

Dim blnTimerActive As Boolean


Private Sub stopTimer()
	' stop timer und reset "timer aktiv"
	Call KillTimer(0, lngTimer): blnTimerActive = False
End Sub

Private Function startTimer() As Long
	' Timer starten und Methode executeAction ausführen sobald der Timer intervall erreicht wurde
	startTimer = SetTimer(0, 0, lngIntervall, AddressOf executeAction): blnTimerActive = True
End Function



'Festlegen, was im festgelegten Intervall passieren soll:
Private Sub executeAction(ByVal hWnd&, ByVal Msg&, ByVal idEvent&, ByVal dwTime&)

	MsgBoc ("hallo")
	' hier die geweünschte Aktion ausführen, Popup oder ...
	Debug.Print lngZaehler
	lngZaehler = lngZaehler + 1

End Sub


' beim Outlook Start den Timer aktivieren
Sub outlookStart()
	
	' Timer start falls nicht bereits aktiv
	If blnTimerActive = True Then
		stopTimer
	End If
	' Timer starten
	lngTimer = startTimer()

End Sub

' beim Outlook beenden oder bei... den Timer zerstören, Resourcen freigeben
Sub outlookEnd()
	If blnTimerActive = True Then
		stopTimer
		lngZaehler = 0
	End If
End Sub

Genau so steht der Code in meinem Modul3
Ich starte die outlookStart() und es passiert nix eifach.

Ich hab Version 2003 und Makro-Sicherheit auf Niedrig
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #16
Sperber

Sperber

Bekanntes Mitglied
Dabei seit
11.03.2003
Beiträge
3.845
Reaktionspunkte
0
Ort
CH
Lass die Makro Sicherheit auf Mittel, nicht auf niedrig!!
Dann wirst Du zwar jedesmal gefragt ob Du das Makro aktivieren willst, aber wenigstens hast Du eine gewisse Sicherheit und lässt nicht ALLES zu.

Ich habe den Code soeben im Geschäft unter Outlook 2003 getestet

Zwei kleine Korrekturen:
Tippfehler bei Dir MsgBoc
.. korrigiert in MsgBox
Weiterhin den Intervall auf 10000 (=10 Sekunden erhöht)

Resultat: Funktioniert

Nach dem Du die Sicherheitsstufe auf Mittel gestellt hast, Outlook beenden und neu starten. Dann Extras->Makro ... und jetzt sollte die Frage kommen ob Du das Makro aktivieren möchtest. Das bestätigst Du mit "Marko aktivieren" Button. Anschliessend die outlookStart ausführen.


Gruss
Sperber

//EDIT
Mach mal nen grundlegenden Test. Lade das Musterbeispiel runter, siehe das von Dir verlinkte Beispiel HIER (Quelle http://www.excel-vba.de)
Im Excel Marko Sicherheit ebenfalls auf Mittel und Teste das Beispiel, wenn der Zähler läuft ist alles i.O. und das Beispiel sollte auch im Outlook funktionieren
 
  • Outlook VBA sleep - alternative oder Threaded? Beitrag #17
PsiTrax

PsiTrax

Bekanntes Mitglied
Dabei seit
29.10.2003
Beiträge
547
Reaktionspunkte
0
Ort
Nürnberg
aha!
das Musterbeispiel funzt auch nicht
meine User32.dll hat die Version 5.1.2600.1106 wobei ich glaube, dass das irgendwie an der office installation liegt

ich werde es morgen mal noch annem andern PC ausprobiern.

aber vielen vielen dank Sperber!!!
hast was gut bei mir
 
Thema:

Outlook VBA sleep - alternative oder Threaded?

ANGEBOTE & SPONSOREN

https://www.mofapower.de/

Statistik des Forums

Themen
213.180
Beiträge
1.579.174
Mitglieder
55.879
Neuestes Mitglied
stonetreck
Oben