VBA Outlook Makro funktioniert nur nach manuellem Anstarten

...komplette Frage anzeigen

3 Antworten

Kann es sein, dass das Makro bei

MkDir Foldername

mit einer Fehlermeldung aussteigt?


Die Reihenfolge, in der die Elemente bei einem For Each durchlaufen werden, ist offiziell nicht festgelegt, inoffiziell läuft der Index von 0 bis (Anzahl-1) bzw. bei VBA anscheinend auch schon mal von 1 bis Anzahl. In jedem Fall ist es ungeschickt, innerhalb der Schleife die Auflistung, über die iteriert wird, zu ändern (hier per Delete).

In solchen Fällen nehme ich immer eine Abwärts-Zählschleife, da kann man Elemente löschen, ohne Probleme zu kriegen:

For i = Liste.Anzahl - 1 To 0 Step -1
    'Hier wird ein bisschen was mit Liste.Item(i) gemacht
    Liste.RemoveItem i
Next 'i = Liste.Anzahl - 1 To 0 Step -1

Hallo Herr Wolff,

vielen Dank für Ihre Antwort. Das Skript läuft ohne Probleme durch und macht auch das was es soll, allerdings nur wenn ich es manuell anstarte.

Das Anlegen des Folder habe ich aber auch bereits rausgenommen.

Können Sie das Beispiel mit der Schleife auf mein Skript übertragen? Ich verstehe das mit dem Next 'i nicht.

Vielen Dank für Ihre Hilfe!

0
@paulschen2006
For i = objIn.Items.Count To 1 Step -1 'Ich vermute mal, dass hier von 1 bis Anzahl gezählt wird, sonst müsste man vor und nach dem To jeweils 1 abziehen
    Set objNewMail = objIn.Items(i)
    With objNewMail
        ...
        ... 'Hier steht der Code von oben
        ...
    End With 'objNewMail
    objNewMail.Delete 'Ginge wohl auch innerhalb des With-Blocks, aber ich habe mir angewöhnt, Objekte innerhalb eines With-Blocks grundsätzlich nicht als Ganzes anzufassen
Next 'i = objIn.Items.Count To 1 Step -1
0
@paulschen2006

Das mit dem Next ist einfach deshalb, weil ein Next ohne Erwähnung der Variablen ausreicht.

Äquivalent wäre

Next i '= objIn.Items.Count To 1 Step -1

Ich schreibe die Grenzen der Zählvariablen gern in einen Kommentar, weil ich es übersichtlicher finde.

Die Form mit dem Variablennamen außerhalb des Kommentars hat einen Vorteil: man kann sich einfacher den aktuellen Wert anzeigen lassen, wenn man das Programm schrittweise ausführen lässt.

0
@paulschen2006

Noch ein Kommentar:

Outlook "feuert" ein Ereignis, wenn neue Mails hereinkommen oder wenn ein Ordner geöffnet wird. Wenn bei das Makro bei solch einer Gelegenheit automatisch ausgeführt werden soll, muss es in der betreffenden Ereignisprozedur aufgerufen werden.

0
@PWolff

Und das mache ich wie? Tut mir Leid, auf diesem Gebiet bin ich kein Crack.

Vielen Dank aber für die vielen Antworten.

0
@PWolff

Ahhh, verstehe. Es sollte nur ein Kommentar sein. Sorry, ich stand auf dem Schlauch :D

0
@paulschen2006

Sorry, gestern hab ich dauernd einen 404er gekriegt ("Webseite vorübergehend nicht erreichbar" - bei gutefrage.net dargestellt mit der Frage "Hoppla, steht da etwa eienr auf der Leitung?" und dem netten weißen Elefanten).

Im Programmcodefenster solltest du oben zwei Auswahllisten haben - die linke für die Objekte, für die Ereignisse überwacht werden können, und die rechte, für die überwachbaren Ereignisse des links ausgewählten Objekts.

Leider kenne ich Outlook nicht, aber ich vermute mal, dass du dort auch in den "Entwurfsmodus" schalten kannst. Dann sollte die Inbox im Kontextmenü einen Punkt "Code anzeigen" haben. Wenn du darauf klickst, landest du im Programmcodefenster, und die Inbox ist mit dem am häufigsten überwachten Ereignis schon ausgewählt. Wähle rechts "öffnen" oder ähnlich und schreib in die Sub (müsste ähnlich wie Inbox_Open oder Inbox_Show heißen) den Namen des Makros aus der Frage.

(gerade sehe ich, dass Sie mich hier gestern mit "Sie" angeredet haben; ich habe hier wieder das in Internetforen üblichere "Du" verwendet.)

0

Wie bereits “PWolff“ anmerkte, stach auch mir sogleich der Durchlauf einer Auflistung und das Ändern der Auflistung mit...

objNewMail.Delete

...in die Augen. Spätestens am Delete wird die ForEach-Schleife mit einem Fehler verlassen. Im Ergebnis ist nur eine Mail bearbeitet worden, so wie es beschrieben wird. Das betrifft nicht das weitere Problem, dass es manuell gestartet werden muss, ist aber schon ein kritischer Punkt, der das Script nicht durchlaufen lässt.

Ein Durchlauf mit einer einfachen For-Schleife ändert daran nichts. Ich würde alles Durchlaufen, wie mit der ForEach bereits vorhanden, und darin die IDs betroffener Mails in eine Liste übernehmen und auf diese Weise merken. In einer anfolgenden Schleife würde ich jede Mail löschen, deren ID in der Liste gemerkt wurde. Auf diese Weise wird verhindert, dass eine Auflistung verändert wird, während sie durchlaufen wird. Dergleichen Problematik habe ich desöfteren in C# und löse es wie beschrieben.

Was das problematische Ausführen des Scripts betrifft, weiss ich hier keinen Rat, zumal ich Outlock nicht verwende, hoffe aber, hierzu weiss jemand anderes noch einen Tipp.

Hallo Toraka,

vielen Dank für deine Antwort. Ich hab deine Antwort leider nicht ganz verstanden. Du meinst jetzt das das Delete an dem manuell anstarten liegt, oder nicht?

Ich kann das Delete auch gerne rausnehmen, da es nur für die kosmetische Tour war. Ich möchte einfach das mein Skript alle Nachrichten durchläuft die im Posteingang liegen und ungelesen sind.

Hast du dafür vielleicht einen konkreten Ansatz? Ist das objNewMail vielleicht einfach nicht dafür geeignet?

0
@paulschen2006

Klammere das Delete doch mal aus, also zum Kommentar machen, indem du vor das erste Zeichen ein Hochkomma ' setzt. Ich meine, in VB war es das Hochkomma, alternativ geht auch REM, um aus einer Befehlzeile ein Kommentar zu machen, die Zeile damit zu deaktivieren. Führe es anschließend aus. Es sollte alles wie gewünscht ablaufen, nur dass die Mail nicht gelöscht wird. Sollte es komplett durch alle Mails durchlaufen, wird das Delete aus einer Auflistung das Problem gewesen sein. Das kannst du dann wie bereits beschrieben verwirklichen, die IDs der Mails merken und die entsprechemden Mails in einem gesonderten Durchlauf, der die gemerkten IDs durchwandert (nicht Mails), bei Übereinstimmung der ID löschen.

0
@paulschen2006

Auskommentieren in VB:

'objNewMail.Delete

Oder...

REM objNewMail.Delete
0

Ich habe vor langer Zeit ähnlich gehandelt, mir eine Routine gesucht und angepasst. Ich vermute mal, Du hast Dein Makro nicht im Ordner "Diese Outlook-Sitzung" liegen. Das wird der Grund sein, weshalb das Makro nicht startet. Und vielleicht probierst Du es mal mit meinem Makro (nur den Verzeichnispfad anpassen)

Dim WithEvents objInbox As Outlook.Items

Private Sub Application_Startup()
   Set objInbox = Session.GetDefaultFolder(olFolderInbox).Items
End Sub

Private Sub objInbox_ItemAdd(ByVal Item As Object)
   If Item.Class = olMail Then
      If Item.Attachments.Count > 0 Then
         Dim objAttachments As Outlook.Attachments
         Set objAttachments = Item.Attachments
         For Each objAttach In objAttachments
            ' Does not handle duplicate filename scenarios
            objAttach.SaveAsFile "c:\temp\" & objAttach.FileName
         Next
         Set objAttachments = Nothing
      End If
   End If
End Sub

Was möchtest Du wissen?