gundelputz
Goto Top

EMail auslesen, verschieben und mit Excel ausgelesene Daten weiterverarbeiten

Hallo da draussen,
Ich habe mal wieder eine Problemstellung bei der ich eure Hilfe brauche.
Ich habe, in Outlook 2010, einen Ordner in dem ich generierte Emails empfange die immer den selben Inhalt haben. Hier stehen immer in der gleichen Zeile Informationen die ich zur Weiterverarbeitung benötige. Diese Informationen möchte ich in Excel importieren und vorzugsweise mit VBA weiterverarbeiten. Anschliessend soll die Email in einen Unterordner verschoben werden.
Ich bin mir nicht sicher ob das so möglich ist und bitte euch um eure Hilfe.

Content-ID: 236309

Url: https://administrator.de/contentid/236309

Ausgedruckt am: 25.11.2024 um 10:11 Uhr

colinardo
colinardo 24.04.2014 aktualisiert um 10:29:29 Uhr
Goto Top
Hallo gundelputz,
das ist grundsätzlich kein Problem. Wie sehen die Mails aus, sind diese im HTML oder Textfomat ? Wie sieht eine Beispielmail aus und wie sieht die Struktur der gewünschten zu extrahierenden Daten aus ?

Grüße Uwe
Gundelputz
Gundelputz 24.04.2014 um 10:31:08 Uhr
Goto Top
Hallo Uwe,
es handelt sich um eine Textnachricht die sich so gliedert:

folgendes Fehlerevent wurde ausgelöst:
Systemstatus
Benutzereingriff notwendig
am: 12.03.2014 07:06
Maschine
Seriennummer
Standort
IP Adresse
Geamtzähler: 35715
Farbzäler: -

zusätzlich unterscheiden sich die mails noch im Betreff was aber momentan noch drittrangig ist.
colinardo
colinardo 24.04.2014 aktualisiert um 10:36:35 Uhr
Goto Top
ja und welche Informationen willst du daraus extrahieren ? genaue Angaben von Zeilen wären hier von Vorteil (Code-Tags) und wohin Excelfile und in welchem Format sollen die Daten geschrieben werden ?

Ich mach dir dann mal ein Beispiel dazu ...
Gundelputz
Gundelputz 24.04.2014 um 11:14:41 Uhr
Goto Top
von den 10 Zeilen brauche ich nur die erste nicht.
Das ganze sind Emails bei dennen es sich um automatische Benachrichtigungen von Drucker zur Tonerbestellung handelt. Erreicht das Gerät einen Schwellwert wird eine Email verschickt. Das gleiche passiert auch bei Fehlermeldungen und Wartungsmeldungen. Die Emails werden mittels Regeln in einen Ordner geleitet wo ich jede einzelne dann sichten muss und dann entscheide um was es sich handelt und die entsprechenden Massnahmen einleite. Also einen Toner bestellen oder eine Reperatur durchführen. Anschliessend soll die Email dann in einen Unterordner in Outlook verschoben werden. Es ist nicht notwendig dies zu automatisiern(permanent zu überwachen) es reicht mir wenn ich das Event ein bis zwei mal am Tag auslöse und alle noch vorhandenen Mail in diesen Outlookordner bearbeite bis dieser geleert ist.
Ich benutze bereits Excel2010 und VBA für diese Aufgabe. Hier muss ich zwar nur die Seriennummer, den Zähler und das Event eintragen aber bei knapp 1000 Geräten kommt da ziehmlich schnell was zusammen. Anschliessend müssen dann noch die Mails verschoben weren.
Ich würde also gerne die Daten in die bestehende Exxceldatei importieren und dann dem entsprechenden Variablen zuweisen.
Ich habe mir das ungefähr so vorgestellt.
Outlookordner erste Mail öffnen und jede Zeile auslesen.
Zeile 1 ignorieren
Zeile 2 u. 3 auslesen und dem entsprechenden Event zuweisen
Zeile 4 Datum und Uhrzeit in Variable speichern
Zeile 6 seriennummer auslesen und mit dieser alle zu der Maschine gehörigen Daten aus Excel abrufen und mit Zeile 7 u. 8 vergleichen
Zeile 9 u. 10 die Zählerstände auslesen
anschlieesend Aktion starten(Bestellung oder Reparatur)
Email aus Ordner verschieben und näste Mail bearbeiten bis Ordner geleert ist.
colinardo
colinardo 24.04.2014, aktualisiert am 10.08.2021 um 10:47:10 Uhr
Goto Top
OK für das Beispiel habe ich mal ein Excel-File erstellt das so aussieht:

98f19bb3a196a689571cf971d6341d66

Folgender Code extrahiert die Daten und schreibt sie in die Spalten für jede Mail in einem Ordner in Outlook, solange bis dieser keine Mails mehr enthält. Ist keine Mail im Ordner vorhanden wird dies gemeldet. Den Pfad zum Excel File gibst du in Zeile 6 an. Dann musst du noch in Zeile 9 und 11 die korrekten Ordner in Outlook referenzieren. In diesem Beispiel wird ein Ordner mit dem Namen Druckeralerts der im Root des Stores user@domain.net liegt gewählt. In diesem Ordner wird dann der Unterordner erledigt referenziert indem die bearbeiteten Mails landen.
back-to-topVBA Makro (zur Nutzung innerhalb von Outlook)
Sub ExtractPrinterAlerts()
    Dim fMails As Folder, mail As MailItem, txtContent As String, arrLines As Variant, objExcel As Object, wb As Object, sheet As Object, rngStart As Object, rngCurrent As Object, fErledigt as Object, txtStatus as String, txtTime as String, txtMessage as String, txtMachine as String, txtSN as String, txtIP as String, txtLocation as String, txtCountTotal as String, txtCountColor as String
    
    'Pfad zur Excel-Datei  
    Const EXCELFILE = "c:\PrinterAlerts.xlsx"  
    
    'Ordner in Outlook referenzieren  
    Set fMails = Application.Session.Stores("user@domain.net").GetRootFolder.Folders("Druckeralerts")  
    'Unterordner referenzieren in den die Mails verschoben werden wenn sie bearbeitet wurden  
    Set fErledigt = fMails.Folders("erledigt")  
    
    
    If fMails.Items.Count > 0 Then
        'Excel Objekt erzeugen  
        Set objExcel = CreateObject("Excel.Application")  
        objExcel.DisplayAlerts = False
        
        'Excelfile öffnen  
        Set wb = objExcel.Workbooks.Open(EXCELFILE)
        
        'Daten kommen in erstes Worksheet  
        Set sheet = wb.Worksheets(1)
        
        'Startzelle in Spalte A ermitteln  
        Set rngStart = sheet.Cells(sheet.Rows.Count,1).End(-4162).Offset(1, 0)
        Set rngCurrent = rngStart
        
        While fMails.Items.Count > 0
            
            'aktuelle Mail  
            Set mail = fMails.Items(1)
            
            'Body extrahieren  
            txtContent = mail.Body
            
            ' Zeilen in ein Array schreiben  
            arrLines = Split(txtContent, vbNewLine, -1, vbTextCompare)
            
            ' Zeilen den Variablen zuweisen  
            txtStatus = arrLines(1)
            txtMessage = arrLines(2)
            txtTime = Trim(Split(arrLines(3), ":", 2, vbTextCompare)(1))  
            txtMachine = arrLines(4)
            txtSN = arrLines(5)
            txtLocation = arrLines(6)
            txtIP = arrLines(7)
            txtCountTotal = Trim(Split(arrLines(8), ":", 2, vbTextCompare)(1))  
            txtCountColor = Trim(Split(arrLines(9), ":", 2, vbTextCompare)(1))  
            
            'Setze Werte im Sheet  
            With rngCurrent
                .Value = txtStatus
                .Offset(0, 1).Value = txtMessage
                .Offset(0, 2).Value = txtTime
                .Offset(0, 3).Value = txtMachine
                .Offset(0, 4).Value = txtSN
                .Offset(0, 5).Value = txtLocation
                .Offset(0, 6).Value = txtIP
                .Offset(0, 7).Value = txtCountTotal
                .Offset(0, 8).Value = txtCountColor
            End With
            'Excel Zeile eins nach unten verschieben  
            Set rngCurrent = rngCurrent.Offset(1, 0)
            
            ' Mail in den 'Erledigt' Ordner verschieben  
            mail.Move fErledigt
        Wend
        'Workbook speichern  
        wb.Save
        'Excel anzeigen  
        objExcel.Visible = True
        objExcel.DisplayAlerts = True
    Else
        MsgBox "Keine Mails zum Bearbeiten im Ordner", vbExclamation  
    End If
    
    Set objExcel = Nothing
    Set wb = Nothing
    Set sheet = Nothing
    Set mail = Nothing
End Sub
Weitere Kommentare befinden sich im Code...

Hoffe das bringt dich erst mal weiter...

- edit 31.03.2015 - Fehler in Zeile 25 korrigiert

Grüße Uwe
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
Gundelputz
Gundelputz 24.04.2014 um 11:49:12 Uhr
Goto Top
Respekt. Hast du das alles in einer knappen halben Stunde geschrieben? Ich bin mal wieder total begeistert von dir. Habe denn Code mal überflogen und glaube das dies genau das ist was ich brauche. Werde mich gleich mal beimachen und den Code anpassen und dann testen.
Aber schon mal vielen Dank.
colinardo
colinardo 24.04.2014 aktualisiert um 11:58:39 Uhr
Goto Top
Zitat von @Gundelputz:

Respekt. Hast du das alles in einer knappen halben Stunde geschrieben?
Yip, kein Problem ...
mal überflogen und glaube das dies genau das ist was ich brauche. Werde mich gleich mal beimachen und den Code anpassen und
dann testen.
Aber schon mal vielen Dank.
zur Info habe es gerade nochmal etwas optimiert umgeschrieben ...

Viel Erfolg ...

Grüße Uwe
Gundelputz
Gundelputz 24.04.2014 um 12:20:43 Uhr
Goto Top
Hi Uwe,
komme schon nicht über die deklarierung
Dim fMails As Folder
Fehlermeldung: "Benutzerdefinierter Typ nicht definiert"
colinardo
colinardo 24.04.2014 aktualisiert um 12:24:39 Uhr
Goto Top
Zitat von @Gundelputz:
komme schon nicht über die deklarierung
Dim fMails As Folder
Fehlermeldung: "Benutzerdefinierter Typ nicht definiert"
wo führst du das ganze denn aus ? in Outlook ? Das Script ist für die Ausführung innerhalb von Outlook angelegt... wenn es ein VBS werden soll oder du es in Excel nutzen willst muss man es umschreiben.
Gundelputz
Gundelputz 24.04.2014 um 12:28:19 Uhr
Goto Top
In Excel.
Habe in outlook noch nie mit vba gearbeitet. hört sich aber interssant an und interessiert mich brennent. Leider weiss ich nicht wie unser Outlookadmin dazu steht.
colinardo
Lösung colinardo 24.04.2014, aktualisiert am 10.08.2021 um 10:43:04 Uhr
Goto Top
Zitat von @Gundelputz:

In Excel.
Habe in outlook noch nie mit vba gearbeitet. hört sich aber interssant an und interessiert mich brennent. Leider weiss ich nicht wie unser Outlookadmin dazu steht.

habs dir mal an Excel angepasst (zur Verwendung in dem Excelfile wo auch die Daten landen, Formatierung siehe Grafik von oben):
Sub ExtractMailInfo()
    Dim fMails As Object, mail As Object, txtContent As String, arrLines As Variant, objExcel As Object, wb As Object, sheet As Object, rngStart As Object, rngCurrent As Object, objOL As Object, fErledigt as Object, txtStatus as String, txtTime as String, txtMessage as String, txtMachine as String, txtSN as String, txtIP as String, txtLocation as String, txtCountTotal as String, txtCountColor as String

    ' Outlook Object erzeugen  
    Set objOL = CreateObject("Outlook.Application")  
    
    'Ordner in Outlook referenzieren  
    Set fMails = objOL.Session.Stores.Item("user@domain.net").GetRootFolder.Folders.Item("Druckeralerts")  
    'Unterordner referenzieren in den die Mails verschoben werden wenn sie bearbeitet wurden  
    Set fErledigt = fMails.Folders("erledigt")  
    
    
    If fMails.Items.Count > 0 Then

        'Workbook setzen  
        Set wb = ActiveWorkbook
        
        'Daten kommen in erstes Worksheet  
        Set sheet = wb.Worksheets(1)
        
        'Startzelle in Spalte A ermitteln  
        Set rngStart = sheet.Cells(Rows.Count,1).End(xlUp).Offset(1, 0)
        Set rngCurrent = rngStart
        
        While fMails.Items.Count > 0
            
            'aktuelle Mail  
            Set mail = fMails.Items(1)
            
            'Body extrahieren  
            txtContent = mail.Body
            
            ' Zeilen in ein Array schreiben  
            arrLines = Split(txtContent, vbNewLine, -1, vbTextCompare)
            
            ' Zeilen den Variablen zuweisen  
            txtStatus = arrLines(1)
            txtMessage = arrLines(2)
            txtTime = Trim(Split(arrLines(3), ":", 2, vbTextCompare)(1))  
            txtMachine = arrLines(4)
            txtSN = arrLines(5)
            txtLocation = arrLines(6)
            txtIP = arrLines(7)
            txtCountTotal = Trim(Split(arrLines(8), ":", 2, vbTextCompare)(1))  
            txtCountColor = Trim(Split(arrLines(9), ":", 2, vbTextCompare)(1))  
            
            'Setze Werte im Sheet  
            rngCurrent.Value = txtStatus
            rngCurrent.Offset(0, 1).Value = txtMessage
            rngCurrent.Offset(0, 2).Value = txtTime
            rngCurrent.Offset(0, 3).Value = txtMachine
            rngCurrent.Offset(0, 4).Value = txtSN
            rngCurrent.Offset(0, 5).Value = txtLocation
            rngCurrent.Offset(0, 6).Value = txtIP
            rngCurrent.Offset(0, 7).Value = txtCountTotal
            rngCurrent.Offset(0, 8).Value = txtCountColor
            
            'Excel Zeile eins nach unten verschieben  
            Set rngCurrent = rngCurrent.Offset(1, 0)
            
            ' Mail in den 'Erledigt' Ordner verschieben  
            mail.Move fErledigt
        Wend
        'Workbook speichern  
        wb.Save
    Else
        MsgBox "Keine Mails zum Bearbeiten im Ordner", vbExclamation  
    End If
    
    Set objOL = Nothing
    Set wb = Nothing
    Set sheet = Nothing
    Set mail = Nothing
End Sub
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
Gundelputz
Gundelputz 24.04.2014 um 13:10:53 Uhr
Goto Top
Grossartig Uwe.
16min für eine Super Lösung.
Bin dafür das dein Chef dein Gehalt erhöht.
danke noch mal
colinardo
colinardo 24.04.2014 aktualisiert um 13:14:56 Uhr
Goto Top
Zitat von @Gundelputz:
16min für eine Super Lösung.
Fingerübung ...
Bin dafür das dein Chef dein Gehalt erhöht.
Gott sein Dank bin ich da mein eigener Chef - ich leite es aber ans Oberstübchen weiter face-smile mal sehen was das Konto so hergibt...
Acht85
Acht85 13.10.2014 aktualisiert um 15:33:10 Uhr
Goto Top
Dein Excel-Makro ist einfach klasse.
Ich habe nur eine kurze Frage. Wie kann ich noch einen Ordner "tiefer" gehen, als nur auf die Ordner unterhalb des Root-Ordners zuzugreifen?
Besteht denn auch die Möglichkeit E-Mails die alle in einem Ordner liegen auszulesen, auch wenn der Body unterschiedlich lang ist?
Vielleicht hast du ja einen Vorschlag oder ein Schlagwort damit ich das Makro anpassen könnte.
Schon einmal Danke
Gundelputz
Gundelputz 13.10.2014 um 16:11:43 Uhr
Goto Top
Der Dank gebürt einzig und allein Colinerdo.
Ich bin mir nicht ganz sicher was du meinst aber ich glaube du solltes einfach nur den untergeordneten Ordner referenzieren.
Die Anzahl der ausgelesenen Zeilen ist eh schon variabel da hier bis zum Ende(EOF) ausgelesen wird.
Man müsste hier warscheinlich nur die grösse des Array's ermitteln.
colinardo
colinardo 13.10.2014 aktualisiert um 18:22:12 Uhr
Goto Top
Hallo Acht85,
Zitat von @Acht85:
Dein Excel-Makro ist einfach klasse.
Ich habe nur eine kurze Frage. Wie kann ich noch einen Ordner "tiefer" gehen, als nur auf die Ordner unterhalb des
Root-Ordners zuzugreifen?
Welchen Root-Ordner meinst du ? Per Definition ist der Root-Ordner der oberste Store-Knoten.
Ich machs mal an zwei Beispielen klar:

Das hier selektiert einen Ordner namens Druckeralerts welcher direkt auf Root-Ebene des Stores liegt
Set fMails = objOL.Session.Stores.Item("user@domain.net").GetRootFolder.Folders.Item("Druckeralerts") 
Das hier einen Unterordner des Posteingangs mit dem Namen Test
Set fMails = objOL.Session.Stores.Item("user@domain.net").GetRootFolder.Folders.Item("Posteingang") .Folders.Item("Test")
usw., jetzt sollte das Prinzip klar sein. Jeder Ordner hat eine Folders-Eigenschaft welche die Unterordner eines Ordners enthält.

Besteht denn auch die Möglichkeit E-Mails die alle in einem Ordner liegen auszulesen, auch wenn der Body unterschiedlich lang ist?
Das musst du mal genauer Beschreiben, kann ich so nicht interprtieren. Wenn man mit Regular-Expressions arbeitet kann man so ziemlich alles aus dem Body extrahieren. Man muss nur ein einigermaßen nachvollziehbares Muster der zu extrahierenden Daten habe.

Grüße Uwe
Acht85
Acht85 14.10.2014 um 08:48:56 Uhr
Goto Top
Hallo Uwe,

das mit dem Unterordner innerhalb des Posteingang hat super funktioniert. Einfach genial. Genau das habe ich gemeint, Danke!!!

Nun zu meiner anderen Fragestellung. Ich habe mehrere E-Mails in einem Ordner, bei denen der Body verschieden lang ist. Ich hatte das Makro erweitert, damit auch immer mehr Zeilen aus der E-Mail in Excel übertragen werden. Mittlerweile bin ich bei ca. 20 Zeilen, die ausgelesen werden sollen.
Eine der E-Mails ist aber nur 19 Zeilen lang und deshalb bekomme ich nun die Fehlermeldung "Laufzeitfehler 9: Index außerhalb des gültigen Bereichs".
Ich hoffe, dass ich mein Problem etwas genauer beschreiben konnte.

Grüße
Acht85
colinardo
colinardo 14.10.2014 aktualisiert um 08:59:30 Uhr
Goto Top
Zitat von @Acht85:
das Makro erweitert, damit auch immer mehr Zeilen aus der E-Mail in Excel übertragen werden. Mittlerweile bin ich bei ca. 20
Zeilen, die ausgelesen werden sollen.
Eine der E-Mails ist aber nur 19 Zeilen lang und deshalb bekomme ich nun die Fehlermeldung "Laufzeitfehler 9: Index
außerhalb des gültigen Bereichs".
Das ist kein Problem, folgender Befehl liefert die Anzahl der Elemente im Array (Bitte beachten das Array ist 0-Basiert, d.h. die Anzahl ist immer um eins kleiner als die Anzahl der Zeilen
UBound(arrLines)
Dann kannst du z.B. so die Anzahl der Zeilen prüfen:
<code >
if UBound(arrLines) > 19 then
' Nachricht hat mehr als 19 Zeilen
end if

oder direkt mit einer Schleife nur alle vorhandenen Zeilen durchlaufen:
for i = 0 to UBound(arrLines)
  ' Zeile verarbeiten, als Beispiel nur ausgeben  
  Msgbox arrLines(i)
  '.....  
Next
Grüße Uwe
Acht85
Acht85 15.10.2014 um 08:45:24 Uhr
Goto Top
Vielen Dank für deine Ansätze, ich habe die Schleife eingebaut und in der Message Box werden nun auch tatsächlich alle Zeilen durchlaufen. Leider habe ich meine Probleme damit die Schleife nun so in das Script einzubauen, dass alle Zeilen in Excel geschrieben werden. :o( Das blicke ich noch nicht so ganz, da muss ich noch einiges rum probieren.

Seit dem ich jetzt die for-Schleife drin habe, bekomme ich direkt nach dem Ausführen eine Meldung "Ein Programm versucht auf ihr Outlook Adressinformationen zuzugreifen...." Diese Meldung muss ich mit "Erteilen" für jede einzelnen E-Mail bestätigen. Hast du vielleicht eine Ahnung, ob man diese Abfrage umgehen kann bzw. beim Ausführen immer den Zugriff erteilen will.
Ich weiß, dass ist ne Menge Zeug das ich dich hier Frage, aber leider war ich schon so lange auf der Suche nach solch einem Script das ich mich an dich "klammer".

Danke schon einmal für all deine Hilfe.

Viele Grüße
Acht85
colinardo
colinardo 15.10.2014 um 09:06:50 Uhr
Goto Top
Zitat von @Acht85:
Leider habe ich meine Probleme damit die Schleife nun so in das Script einzubauen, dass alle Zeilen in
Excel geschrieben werden. :o( Das blicke ich noch nicht so ganz, da muss ich noch einiges rum probieren.
Du musst Zeile 60 des obigen Scripts in deine Schleife verschieben
Set rngCurrent = rngCurrent.Offset(1, 0) 
damit wird bei jedem Durchlauf in Excel die aktuelle Zeile eins nach unten verschoben. rngCurrent ist dann immer die neue Leere Zelle in die du deine Werte schreiben kannst.

Seit dem ich jetzt die for-Schleife drin habe, bekomme ich direkt nach dem Ausführen eine Meldung "Ein Programm versucht
auf ihr Outlook Adressinformationen zuzugreifen...." Diese Meldung muss ich mit "Erteilen" für jede einzelnen
E-Mail bestätigen. Hast du vielleicht eine Ahnung, ob man diese Abfrage umgehen kann bzw. beim Ausführen immer den
Zugriff erteilen will.
Siehe: VBA - automatischer Mailversand (Sicherheitsprüfung umgehen)

Grüße Uwe
Acht85
Acht85 15.10.2014 um 11:06:18 Uhr
Goto Top
So, die Fehlermeldung ist nun verschwunden und es werden alle Zeilen aus den E-Mails in Excel geschrieben. :o)
Meine Schleife sieht nun so aus:

For i = 0 To UBound(arrLines)
' Zeile verarbeiten
rngCurrent.Value = arrLines(i)
Set rngCurrent = rngCurrent.Offset(1, 0)
Next

Doch leider werden jetzt alle E-Mail Zeilen in Spalte A geschrieben. :o( Vorher wurden dich die Zeilen nebeneinander geschrieben und eine neue E-Mail bekam eine neue Zeile. Wenn ich Offset auf (0,1) werden alle E-Mails in nebeneinander in eine Zeile geschrieben. Ich stehe gerade echt auf dem Schlauch...
colinardo
colinardo 15.10.2014 aktualisiert um 11:14:21 Uhr
Goto Top
Zitat von @Acht85:
Doch leider werden jetzt alle E-Mail Zeilen in Spalte A geschrieben. :o( Vorher wurden dich die Zeilen nebeneinander geschrieben
und eine neue E-Mail bekam eine neue Zeile. Wenn ich Offset auf (0,1) werden alle E-Mails in nebeneinander in eine Zeile
geschrieben. Ich stehe gerade echt auf dem Schlauch...
Wie du in meinem Code oben sehen kannst wird mit dem Offset festgelegt in welcher Spalte welcher Wert eingetragen wird:
rngCurrent selber ist immer die Spalte A, wenn du nun Spalte B der aktuellen Zeile ansprechen willst gibst du einen Spaltenoffset von 1 an (zweiter Parameter)
rngCurrent.Offset(0,1).Value = "Wert für Spalte B"  
rngCurrent.Offset(0,2).Value = "Wert für Spalte C"  
rngCurrent.Offset(0,3).Value = "Wert für Spalte D"  
' usw...  
Die Teile der jeweiligen Zeile in der Mail musst du natürlich vorher z.B. mit *Split()** aufsplitten wie auch in meinem Code oben zu sehen ist.
Was bei dir zum trennen der Spalten in der Nachricht verwendet werden kann, kennst leider nur du face-wink da ich den Inhalt der Nachricht nicht kenne.

Bitte weitere Kommentare via PM damit wir hier den Thread und den TO nicht vollsauen. Danke.

Grüße Uwe
kohlerqh
kohlerqh 23.10.2014 aktualisiert um 12:23:37 Uhr
Goto Top
Hallo,

sowas habe ich gesucht. Habe das Script in eine Exceltabelle als Makro eingefügt.
Jetzt bekomme ich eine Fehlermeldung "Fehler beim Kompilieren: Variable nicht definiert", Cursor spring dabei auf Zeile 11 fErledigt.
Habe nur ich das Problem?
was ahbe ich falsch gemacht?

Gruß
Andreas
colinardo
colinardo 23.10.2014 aktualisiert um 12:32:07 Uhr
Goto Top
Zitat von @kohlerqh:
Jetzt bekomme ich eine Fehlermeldung "Fehler beim Kompilieren: Variable nicht definiert", Cursor spring dabei auf Zeile
11 fErledigt.
was ahbe ich falsch gemacht?
Hallo kohlerqh,
lösch mal oberhalb des Codes die Zeile Option Explicit, oder kopiere den Code nochmal, hatte eine Dim-Deklaration der Variable fErledigt as Object vergessen ... sorry, ist oben korrigiert.

Grüße Uwe
kohlerqh
kohlerqh 23.10.2014 um 12:39:57 Uhr
Goto Top
Hallo Uwe,

Danke für die schnelle Antwort. Wenn ich die Zeile Option Explicit lösche wirft er mir einen Laufzeitfehler raus

Laufzeitfehler '-2147221233 (8004010f)'

Automatisierungsfehler


Gruß
Andreas
colinardo
colinardo 23.10.2014 aktualisiert um 12:43:23 Uhr
Goto Top
Zitat von @kohlerqh:
Danke für die schnelle Antwort. Wenn ich die Zeile Option Explicit lösche wirft er mir einen Laufzeitfehler raus

Laufzeitfehler '-2147221233 (8004010f)'
Dann hast du den Code nicht komplett an deine Umgebung angepasst, ohne Anpassungen läuft der Code natürlich nicht out-of-the-box !
Bitte weitere Fragen via Personal Message sonst müllen wir den Thread hier mit VBA-Anfängerfragen zu ...Danke.
KasparG
KasparG 11.12.2014 um 14:14:25 Uhr
Goto Top
Hallo,

auch für mich war der Code schon sehr hilfreich.

Nun habe ich nur das Problem, dass ich nur die Mails mit einem bestimmten Betreff aus dem Posteingang auslesen und in einen Unterordner verschieben möchte. Hintergrund ist, dass es sich um einen Gemeinschaftspostfach handelt, auf das keine Filterregeln angewendet werden dürfen.

Gibt es da eine Möglichkeit die Ausleseschleife auf die Mails mit bestimmten Betreff zu beschränken?

Vielen Dank!
Kaspar
colinardo
colinardo 11.12.2014, aktualisiert am 10.08.2021 um 10:45:03 Uhr
Goto Top
Hallo Kaspar, Willkommen auf Administrator.de!
Zitat von @KasparG:
Gibt es da eine Möglichkeit die Ausleseschleife auf die Mails mit bestimmten Betreff zu beschränken?
Selbstverständlich ist das möglich face-smile
Auf Basis des obigen Codes sähe das dann so aus
Sub ExtractMailInfo()
    Dim fMails As Object, mail As Object, txtContent As String, arrLines As Variant, objExcel As Object, wb As Object, sheet As Object, rngStart As Object, rngCurrent As Object, objOL As Object, fErledigt As Object, colMove As New Collection, strSubject As String, mailItems As Object

    ' Outlook Object erzeugen  
    Set objOL = CreateObject("Outlook.Application")  
    
    'Ordner in Outlook referenzieren  
    Set fMails = objOL.Session.Stores.Item("user@domain.det").GetRootFolder.Folders.Item("Druckeralerts")  
    'Unterordner referenzieren in den die Mails verschoben werden wenn sie bearbeitet wurden  
    Set fErledigt = fMails.Folders("erledigt")  
    
    'Subject nach dem gefiltert wird  
    strSubject = "Dein Subject das du suchst"  
    
    If fMails.Items.Count > 0 Then

        'Workbook setzen  
        Set wb = ActiveWorkbook
        
        'Daten kommen in erstes Worksheet  
        Set sheet = wb.Worksheets(1)
        
        'Startzelle in Spalte A ermitteln  
        Set rngStart = sheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
        Set rngCurrent = rngStart
        
        'Mails nach Subject filtern  
        Set mailItems = fMails.Items.Restrict("@SQL=""http://schemas.microsoft.com/mapi/proptag/0x0037001f"" like '%" & strSubject & "%'")  
        
        If Not mailItems Is Nothing Then
            For Each mail In mailItems
                
                'Body extrahieren  
                txtContent = mail.Body
                
                'Zeilen in ein Array schreiben  
                arrLines = Split(txtContent, vbNewLine, -1, vbTextCompare)
                
                'Zeilen den Variablen zuweisen  
                txtStatus = arrLines(1)
                txtMessage = arrLines(2)
                txtTime = Trim(Split(arrLines(3), ":", 2, vbTextCompare)(1))  
                txtMachine = arrLines(4)
                txtSN = arrLines(5)
                txtLocation = arrLines(6)
                txtIP = arrLines(7)
                txtCountTotal = Trim(Split(arrLines(8), ":", 2, vbTextCompare)(1))  
                txtCountColor = Trim(Split(arrLines(9), ":", 2, vbTextCompare)(1))  
                
                'Setze Werte im Sheet  
                rngCurrent.Value = txtStatus
                rngCurrent.Offset(0, 1).Value = txtMessage
                rngCurrent.Offset(0, 2).Value = txtTime
                rngCurrent.Offset(0, 3).Value = txtMachine
                rngCurrent.Offset(0, 4).Value = txtSN
                rngCurrent.Offset(0, 5).Value = txtLocation
                rngCurrent.Offset(0, 6).Value = txtIP
                rngCurrent.Offset(0, 7).Value = txtCountTotal
                rngCurrent.Offset(0, 8).Value = txtCountColor
                
                'Excel Zeile eins nach unten verschieben  
                Set rngCurrent = rngCurrent.Offset(1, 0)
                
                ' Mail zur Collection hinzufügen  
                colMove.Add mail
            Next
            'Mails verschieben  
            For Each m In colMove
                m.Move fErledigt
            Next
        End If
        'Workbook speichern  
        'wb.Save  
    Else
        MsgBox "Keine Mails zum Bearbeiten im Ordner", vbExclamation  
    End If
    
    Set objOL = Nothing
    Set wb = Nothing
    Set sheet = Nothing
    Set mail = Nothing
    Set mailItems = Nothing
    set colMail = Nothing
End Sub
Im Beispiel wird mit like gesucht (Zeile 28), d.h. das was vor und nach dem String kommt kann dann variieren.

Grüße Uwe
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
KasparG
KasparG 11.12.2014 um 15:37:26 Uhr
Goto Top
Hey Uwe,

Danke fürs Willkommen und vor allem für die Hilfe. Es rennt.

Gruß
Kaspar
KasparG
KasparG 12.12.2014 aktualisiert um 14:20:01 Uhr
Goto Top
Hey Uwe,

wie schon geschrieben läuft der Code einwandfrei. Nun habe ich aber noch ein klitzekleines Problem. Die Mail, die den entsprechenden Betreff enthalten werden in scheinbar zufälliger Reihenfolge abgearbeitet. Im Ideal würde aber erst, die älteste Mail in das Worksheet geschrieben, dann die zweitälteste ...

Geht sowas?

Vielen Dank und Gruß
Kaspar
colinardo
colinardo 12.12.2014 aktualisiert um 14:27:33 Uhr
Goto Top
Zitat von @KasparG:

Hey Uwe,

wie schon geschrieben läuft der Code einwandfrei. Nun habe ich aber noch ein klitzekleines Problem. Die Mail, die den
entsprechenden Betreff enthalten werden in scheinbar zufälliger Reihenfolge abgearbeitet. Im Ideal würde aber erst, die
älteste Mail in das Worksheet geschrieben, dann die zweitälteste ...

Geht sowas?
Ja, du fügst zwischen Zeile 30 und 31 des Codes noch folgende Zeile ein:
mailItems.Sort "[ReceivedTime]",False
Grüße Uwe
KasparG
KasparG 12.12.2014 um 14:40:40 Uhr
Goto Top
Vielen Dank!

Gruß
Kaspar
tangokom
tangokom 14.04.2015 um 16:04:43 Uhr
Goto Top
Hallo colinardo, vielen Dank für Dein gut dokumentiertes Script. Weitgehend verstehe ich es, aber ich habe Probleme damit, es auf meinen Anwendungsfall zu übertragen. Meine Daten liegen leider nicht hübsch in den Zeilen separiert vor, sondern sie verstecken sich im Fließtext:

0 Guten Tag, xxx yyy!
1
2 Die Batterieaufladung Ihres Fahrzeuges mit der Fahrgestellnummer VF1AGVYA123456789 begann an 25/12/2014 23:57.
3 Der aktuelle Batterie-Ladestatus beträgt 80 %, was einer geschätzten Fahrleistung von 103.0 km entspricht.
4
5 Bis bald im Renault-Portal.
6 Ihr Renault-Team Sie können im Renault-Portal einstellen, ob Sie solche E-Mail-Benachrichtigungen erhalten.
7 Bitte antworten Sie nicht auf diese E-Mail. Dieses Postfach wird nur für den Versand verwendet – wir würden Ihre Antwort nicht erhalten. Wenn Sie Hilfe benötigen, wenden Sie sich bitte an den Renault-Kundendienst.

Die Daten, die mich interessieren liegen in den Zeilen 2 und 3: Fahrgestellnummer, Datum-Uhrzeit, Batterieladestatus (ohne das %), Fahrleistung
(ohne Punkt und Nachkomma).

Die Mail wird als HTML versendet und hat noch einige Grafiken und auch eine Tabelle drin. Die Zeilennummerierung habe ich bekommen, nachdem ich die Mail von Hand in TXT umgewandelt habe.

Bin leider kein VBA-Profi, wird wohl ne Text-Handling-Frage sein.
Danke für die Hilfe!
colinardo
colinardo 15.04.2015 aktualisiert um 15:45:12 Uhr
Goto Top
Hallo tangokom, Willkommen auf Administrator.de!
Die Daten, die mich interessieren liegen in den Zeilen 2 und 3: Fahrgestellnummer, Datum-Uhrzeit, Batterieladestatus (ohne das %), Fahrleistung (ohne Punkt und Nachkomma).
Für solche Fälle gibt es Regular Expressions mit der sich solche Textfragmente gezielt extrahieren lassen:
Beispiel für dein Textfragment und deinen gewünschten Daten
Set regex = CreateObject("vbscript.regexp")  
regex.Global = False: regex.IgnoreCase = True: regex.MultiLine = False
regex.Pattern = "Fahrgestellnummer ([^\s]*) begann an ([^.]*)[\s\S]*?Batterie-Ladestatus beträgt (\d+)[\s\S]*? Fahrleistung von (\d+)"  
set matches = regex.Execute(txtContent)
if matches.count > 0 then
   strFarhgestellnummer = matches(0).submatches(0)
   strDatum = matches(0).submatches(1)
   strBatterieLadestatus = matches(0).submatches(2)
   strFahrleistung = matches(0).submatches(3)
End if
Für eine Dokumentation zu Regular Expressions siehe das Regular Expressions Tutorial
Weitere Hilfe kannst du mich gerne via PM anschreiben damit der Thread hier nicht zugemüllt und die anderen User nicht weiter belästigt werden. Danke.

Grüße Uwe
colinardo
colinardo 15.04.2015, aktualisiert am 04.07.2015 um 15:44:48 Uhr
Goto Top
back-to-topWICHTIGER HINWEIS FÜR KÜNFTIGE FRAGESTELLER
Für alle zukünftigen Fragesteller die eine Anpassung des Scripts an Ihre persönliche Situation benötigen, bitte ich sich direkt an mich über eine persönliche Nachricht zu wenden. Dann können die Details und ein Preis für eine Anpassung verhandelt werden. Danke.

Weitere Fragen in diesem Thread zu persönlichen Anpassungen werden von mir nicht beantwortet..

Grüße @colinardo
Willi-Zorn
Willi-Zorn 12.06.2015 um 12:30:19 Uhr
Goto Top
Hallo Zusammen,

habe mich hier soeben eingetragen, da ich hoffe, daß ihr mein Problem am schnellsten lösen könnt.

Da meine Zielsetzung fast identisch ist zu der hier aufgelisteten und ich schon die Hoffnung hatte, es ginge alles jetzt ganz schnell, hänge ich mein Idee hier mal dran:

Unter Office 2007 will ich
die Email die ein bestimmter User mit einer feststehenden Beschreibung bekommt erkennen - findet täglich statt
die Email hat einen Anhang
der Anhang (Zip Datei) soll genommen werden, entzippt werden - dann ist es eine Textdatei - und in die erste Tabelle einer Exceldatei eingelesen werden 1 zu 1 keine Änderungen o.ä.
Email in einen anderen Ordner schieben -> z.B. Gelöschte Dateien

Es kann, muß aber keine Zwischenspeicherung der Zip/TXT Datei stattfinden
Die Mail kann, muß aber nicht als gelesen gekennzeichnet werden

Die Version von Colinardo sieht super aus und ich habe sie entsprechend meiner Bedürfnisse angefangen zu verändern, hänge aber schon in Zeile 8

Set fMails = objOL.Session.Stores.Item("user@domain.det").GetRootFolder.Folders.Item("Druckeralerts") <- habe hier den Empfängeruser eingetragen und Druckeralerts ist Posteingang.

mit dem Fehler

Laufzeitfehler '-2147221233(8004010f)':
Der Vorgang konnte nicht ausgeführt werden. Ein Objekt wurde nicht gefunden.

!! Ach ja: die Mail wird in einem Unter- Unterordner abgelegt. Die dazu hier stehende Syntax wird von meinem System ebenfalls bemeckert. Sch...eibenkleister !!!

Liegt das an unterschiedlichen Office Versionen?

Hoffe auf Eure Hilfe und sage schon mal Danke im Voraus.
TurDur55
TurDur55 03.07.2015 aktualisiert um 14:16:54 Uhr
Goto Top
Hallo Liebe Programmierer,

habe den Code so übernommen. Funktionieren tut es auch soweit sehr gut, allerdings müssen paar Sachen nach meinen Bedürfnissen angepasst werden.

Benötige einen VBA Code mit dem ich meine Mails in Excel importieren kann.

1. Den Code oben habe ich soweit angepasst, nur möchte ich nun, dass in der Zeile 29 meiner Mail nur das 4 Wort (ist eine Zahl) übernommen wird in Excel. Mit Trim(Split bekomme ich es irgendwie nicht hin.
2. Bei der Übernahme der Zeile 30 (E-Mail-Adresse) wird in Excel dieser Text (E-Mail: HYPERLINK "mailto:test@gmx.de"test@gmx.de) eingetragen. Hier soll nur die Mail Adresse übertragen werden.
3. letzte Zelle in der Arbeitsmappe-Tabelle8 soll das heutige Datum eingetragen werden.
4. Es sollen nur die Mails importiert werden die den Absender test@gmx.de haben.


Hoffe ich konnte mich ordentlich Ausdrücken. bin leider kein Fachmann des VBA´s.
stocki260714
stocki260714 04.01.2018 um 13:14:04 Uhr
Goto Top
Hallo colinardo,
bei der Suche nach einer Lösung für ein ähnlich gelagertes Problem bin ich auf dieses Forum aufmerksam geworden.
Bevor ich ins Detail gehe, würde ich gerne fragen, ob das von Dir erstellte Makro auch auf das komische mail-Programm
DAVID (statt Outlook) anpassbar wäre..

Ich freue mich auf Dein Feedback!
Gruß!
stocki260714
colinardo
colinardo 04.01.2018 aktualisiert um 13:34:24 Uhr
Goto Top
Servus @stocki260714,
Zitat von @stocki260714:
Bevor ich ins Detail gehe, würde ich gerne fragen, ob das von Dir erstellte Makro auch auf das komische mail-Programm
DAVID (statt Outlook) anpassbar wäre..
Keine Ahnung, und wenn dann bestimmt nicht nur anpassen sondern komplett neu schreiben.
Von DAVID habe ich k.A. und kann dir deswegen keinen Support anbieten, sorry.

Du solltest dir die Powershell-Beispiel von mir hier im Forum ansehen die direkt auf ein Postfach (via IMAP/POP) zugreifen und die Mails so direkt auslesen, ohne einen Client wie Outlook oder DAVID.
Wie z.B. E-Mail Client für Kommandozeile

Grüße Uwe
stocki260714
stocki260714 04.01.2018 um 13:51:37 Uhr
Goto Top
Hallo Uwe,

vielen Dank für Deine schnelle Antwort und den Tipp! Schaue ich mir später mal genauer an!

Beste Grüße und guten Jahresstart!
Sven
isasophie
isasophie 10.10.2018 um 11:54:04 Uhr
Goto Top
Hallo Uwe,

ich versuche auch derzeit ein solches Programm zu basteln. Ich habe bisher kaum Erfahrungen mit VBA gemacht und versuche mir gerade sehr viel anzulesen. Im Prinzip verstehe ich das Programm als solches , allerdings hapert es bei bestimmten Methoden..

Ich habe (glaube ich) alle nötigen Anpassungen vorgenommen, allerdings habe ich einen Laufzeitfehler durch die Zeile
Set fMails =Application....
Ich habe dort meinen Outlook Account ergänzt und den Unterordner XY vom Posteingang.
Die Beschreibung vom Laufzeitfehler lautet: Der versuchte Vorgang konnte nicht ausgeführt werden. Ein Objekt wurde nicht gefunden.

Woran kann das liegen? Muss ich noch bestimmte Einstellungen vornehmen?

Ich würde mich über eine Antwort sehr freuen.

Viele Grüße
Sophie
Gorbi1312
Gorbi1312 10.08.2021 um 09:10:04 Uhr
Goto Top
Hallo,

ich benötige momentan genau so ein Programm nur ohne das Verschieben von den Emails.
Wenn ich nur dein Programm probiere auszuführen, sagt er mir das "arrLines" nicht deklariert ist, nach dem deklarieren muss ich auch noch "txtStatus" bis "txtCountColor" deklarieren und danach vertragen sich die Deklarationen nicht?