E-Mail zerlegen und in Excel darstellen

  • Excel

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    E-Mail zerlegen und in Excel darstellen

    Guten Tag an alle,

    Vorweg muss ich sagen, ich bin absoluter Anfänger in VBA und daher wird das Problem, das ich habe, für viele hier wohl eher trivial sein.

    Ich habe eine Funktion in VBA Excel, die mir e-Mails aus einem Postfach zerlegt und "aufschlüsselt".
    Es geht darum, dass diese E-Mails zu bestimmten Projekten Statusinformationen bzw. Updates erhalten und in der Excel-Tabelle soll am Ende das Projekt mit den Informationen in einer Zeile stehen.
    Das funktioniert auch soweit, also zu einem Projekt wird z.B. eine Zeile bei Initiierung geschrieben und dahinter dann alle notwendigen Information. Es gibt aber zu dem Projekt laufend Updates und auch Rectifications, die natürlich aber erst Tage oder Wochen später kommen. Meine Funktion schreibt dann zwar für das Item eine Zeile für das Update oder die Rectifications, dann aber deutlich weiter unten in der Tabelle.
    Ich möchte also, dass erkannt wird, dass es sich um das selbe Projekt handelt und alle Statusinformationen mit Zeilenumbruch in dieselbe Zeile gepackt werden.
    Ich poste mal den Code und eine Beispielzeile, um das zu Veranschaulichen:

    VB.NET-Quellcode

    1. Sub Alles()
    2. 'Dim Datenspeicher() As String
    3. ActiveWorkbook.Connections("Abfrage - Mail").Refresh
    4. Dim Gesamttext_zerlegt() As String
    5. With Worksheets("Übersicht") ' Ermittlung Übersichtende
    6. Letzte2 = .Cells(.Rows.Count, "B").End(xlUp).Offset(1, 0).Row
    7. End With
    8. Worksheets("Übersicht").Range(Cells(2, 1), Cells(Letzte2, 10)).ClearContents
    9. With Worksheets("Rohdaten") 'Ermittlung Tabellenende
    10. Letzte1 = .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
    11. End With
    12. For iZelle1 = 2 To Letzte1 + 1 ' für jeden Eintrag in der Tabelle
    13. Gesamttext = Worksheets("Rohdaten").Cells(iZelle1, 6).Value
    14. Gesamttext_zerlegt = Split(Gesamttext, "//")
    15. LenArray = UBound(Gesamttext_zerlegt)
    16. For I = 0 To LenArray ' für jeden Eintrag im Array
    17. Worksheets("Details").Cells(iZelle1, I + 1).Value = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    18. 'Text = Gesamttext_zerlegt(I)
    19. If InStr(Gesamttext_zerlegt(I), "Von:") > 0 Then
    20. pos_trenn = InStr(Gesamttext_zerlegt(I), "Von:")
    21. If Len(Gesamttext_zerlegt(I)) > 4 Then
    22. Text = Right(Gesamttext_zerlegt(I), Len(Gesamttext_zerlegt(I)) - pos_trenn - 4)
    23. pos_trenn = InStr(Text, "Gesendet:")
    24. If pos_trenn > 0 Then
    25. Text = Left(Text, pos_trenn - 1)
    26. Text = WorksheetFunction.Clean(Replace(Text, "FGS ", ""))
    27. End If
    28. End If
    29. Worksheets("Übersicht").Cells(iZelle1, I + 1).Value = Text
    30. 'Datenspeicher(I) = Text
    31. ElseIf InStr(Gesamttext_zerlegt(I), "MSGID") > 0 Then
    32. pos_id = InStr(Gesamttext_zerlegt(I), "MSGID/")
    33. Text = Right(Gesamttext_zerlegt(I), Len(Gesamttext_zerlegt(I)) - pos_id - 5)
    34. Text = WorksheetFunction.Clean(Text)
    35. If InStr(Text, "Status") > 0 Then
    36. Worksheets("Übersicht").Cells(iZelle1, 5).Value = Text
    37. 'Datenspeicher(5) = Text
    38. ElseIf InStr(Text, "LOGREQ") > 0 Then
    39. Worksheets("Übersicht").Cells(iZelle1, 3).Value = Text
    40. 'Datenspeicher(3) = Text
    41. End If
    42. ElseIf InStr(Gesamttext_zerlegt(I), "REF/") > 0 Then
    43. If InStr(Gesamttext_zerlegt(I), "LOGREQ") > 0 Or InStr(Gesamttext_zerlegt(I), "IH") > 0 Then
    44. If Worksheets("Übersicht").Cells(iZelle1, 4).Value = "" Then
    45. ref_text = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    46. Worksheets("Übersicht").Cells(iZelle1, 4).Value = ref_text
    47. 'Datenspeicher(4) = Text
    48. Else
    49. If Worksheets("Übersicht").Cells(iZelle1, 4).Value Like Gesamttext_zerlegt(I) Then
    50. Else
    51. ref_text = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    52. test_text = Worksheets("Übersicht").Cells(iZelle1, 4).Value
    53. Worksheets("Übersicht").Cells(iZelle1, 4).Value = Worksheets("Übersicht").Cells(iZelle1, 4).Value & vbCrLf & ref_text
    54. 'Datenspeicher(4) = Worksheets("Übersicht").Cells(izelle1, 4).Value & vbCrLf & Text
    55. End If
    56. End If
    57. ElseIf InStr(Gesamttext_zerlegt(I), "Status") > 0 Then
    58. If Worksheets("Übersicht").Cells(iZelle1, 4).Value = "" Then
    59. ref_text = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    60. Worksheets("Übersicht").Cells(iZelle1, 4).Value = ref_text
    61. Else
    62. If Worksheets("Übersicht").Cells(iZelle1, 4).Value Like Gesamttext_zerlegt(I) Then
    63. Else
    64. ref_text = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    65. Worksheets("Übersicht").Cells(iZelle1, 4).Value = Worksheets("Übersicht").Cells(iZelle1, 4).Value & vbCrLf & ref_text
    66. 'Datenspeicher(4) = Worksheets("Übersicht").Cells(izelle1, 4).Value & vbCrLf & Text
    67. End If
    68. End If
    69. 'Datenspeicher(4) = Text
    70. End If
    71. ElseIf InStr(Gesamttext_zerlegt(I), "OPDEFDET") > 0 Then
    72. Worksheets("Übersicht").Cells(iZelle1, 6).Value = WorksheetFunction.Clean(Replace(Gesamttext_zerlegt(I), "OPDEFDET/", ""))
    73. Worksheets("Übersicht").Cells(iZelle1, 8).Value = WorksheetFunction.Clean(Replace(Gesamttext_zerlegt(I + 1), "GENTEXT/", ""))
    74. ElseIf InStr(Gesamttext_zerlegt(I), "OPDEF") > 0 Then
    75. OPDEF_text = WorksheetFunction.Clean(Gesamttext_zerlegt(I))
    76. If InStr(OPDEF_text, "REF/") > 0 Then
    77. 'Worksheets("Übersicht").Cells(iZelle1, 4).Value = OPDEF_text
    78. 'Datenspeicher(4) = OPDEF_text
    79. Else
    80. OPDEF_text = Replace(OPDEF_text, "OPDEF/", "")
    81. OPDEF_text = Replace(OPDEF_text, " ", "-")
    82. OPDEF_text = Replace(OPDEF_text, "Status", "")
    83. OPDEF_text = WorksheetFunction.Clean(OPDEF_text)
    84. Worksheets("Übersicht").Cells(iZelle1, 2).Value = OPDEF_text
    85. 'Datenspeicher(2) = OPDEF_text
    86. End If
    87. ElseIf InStr(Gesamttext_zerlegt(I), "Item2") > 0 Then
    88. Worksheets("Übersicht").Cells(iZelle1, 7).Value = WorksheetFunction.Clean(Replace(Gesamttext_zerlegt(I), "Item2/", ""))
    89. 'Datenspeicher(7) = OPDEF_text
    90. End If
    91. Next I
    92. Next iZelle1
    93. End Sub


    In Excel sehen Beispiel-Zeilen dann so aus:


    Nun möchte ich, dass die Initiierung von Projekt 1 und das spätere Update in derselben Zelle mit Zeilenumbruch angezeigt werden, sodass man am Ende für jedes Projekt über die gesamte Laufzeit nur eine Excel-Zeile hat.

    Für jede Hilfe wäre ich sehr dankbar!
    Was passiert denn in dieser Zeile

    Visual Basic-Quellcode

    1. ​ActiveWorkbook.Connections("Abfrage - Mail").Refresh

    Wird hier eine PowerQuery Abfrage aktualisiert? Was wird in der Abfrage gemacht?

    Ich denke, die Lösung könnte ggf. mit PowerPivot und der DAX-Funktion CONCETANTREX ohne VBA umgesetzt werden.


    Dein VBA-Code bedeutet doch, dass Du jedes mal alle Zellen neu schreiben musst oder?
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

    Riley schrieb:

    Meine Funktion schreibt dann zwar für das Item eine Zeile für das Update oder die Rectifications, dann aber deutlich weiter unten in der Tabelle.
    Ich möchte also, dass erkannt wird, dass es sich um das selbe Projekt handelt und alle Statusinformationen mit Zeilenumbruch in dieselbe Zeile gepackt werden.

    Variante 1: Du sortierst die Tabelle anschließend nach Projektnummer.
    Variante 2: Du suchst beim Eintrag nach der Projektnummer und wenn der Eintrag existiert, hängst du die Daten hinten dran.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Wird hier eine PowerQuery Abfrage aktualisiert? Was wird in der Abfrage gemacht?​


    Hier wird die Verbindung zum Mailserver aktualisiert und die Datenquelle (das Mailpostfach) abgefragt.

    ​Dein VBA-Code bedeutet doch, dass Du jedes mal alle Zellen neu schreiben musst oder?


    Die Rohdaten sind in einem Excelsheet, die Abfrage aktualisiert diese und fügt neue hinzu und dann wird daraus meine Übersicht generiert. Könnte man bestimmt besser lösen, aber wir reden hier nicht von allzu vielen Einträgen, von daher vernachlässigbar, denke ich.

    ​Variante 1: Du sortierst die Tabelle anschließend nach Projektnummer.

    Ist das in VBA zu realisieren? Zurzeit benutze ich einfach den Filter von Excel und sortiere damit, aber es wäre natürlich eleganter (da es auch andere benutzen sollen), wenn direkt sortiert wäre und eine Zeile pro Projekt

    Variante 2: Du suchst beim Eintrag nach der Projektnummer und wenn der Eintrag existiert, hängst du die Daten hinten dran.​


    Selbes Spiel, wie mache ich das in VBA? Das wäre auch meine Idee gewesen, das Array nach Dopplungen zu durchsuchen und dann wenn zwei mal oder öfter "ProjektXX" auftaucht, das in eine gemeinsame Zeile schreiben zu lassen. Ich weiß nur leider nicht, wie ich das realisiere.

    Riley schrieb:

    Ist das in VBA zu realisieren?
    Mit Range.Sort

    Riley schrieb:

    eine Zeile pro Projekt
    Das wird schon schwieriger, da du j a einzelne Zellinhalte verändern musst, um mehrere Zellen in eine zusammenfassen.

    Riley schrieb:

    das Array nach Dopplungen zu durchsuchen
    Da hilft dir Range.Find

    Dein Code ist relativ umständlich und schon gar nicht objektorientiert.
    Das schreckt mich ein wenig davor ab, dir direkte Änderungen an deinem Code vorzuschlagen.
    Wenn ich so was im Job zur Überarbeitung in die Hand bekomme, werfe ich es weg und schreibe es neu.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Vielen Dank für die Hilfe, ich werde dann wohl versuchen, zumindest die Projekte in einzelnen Zeilen untereinandergeschrieben hinzubekommen.
    Ich habe den Code auch so bekommen und leider wenig bis keine Ahnung von VBA, neu schreiben ist daher keine Option.

    Vollzitat entfernt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Mit Range.Sort​


    Habe rumprobiert, aber kriege nicht wirklich raus, wie ich damit die Projekte sortieren kann.
    Also die Initiierung, Update und Rectification fangen immer mit der Projektnummer_Jahr an, danach würd ich entsprechend gern sortieren. Dann wären zumindest die Projekte in Zeilen untereinander sortiert, das würde schon reichen.
    Kannst du mir sagen, wie ich das in meine Funktion einbauen könnte? Lasse ich meinen Code laufen, um die Tabelle zu bauen und mache danach dann Range.Sort auf die Spalte der Projektbezeichnung? Steige da leider nicht ganz durch, sorry.
    Auch wenn der Code wie du sagst nicht sonderlich schön ist, wäre das alles und das Makro würde seinen Zweck erfüllen. Objektorientiert und generell besser geschrieben übersteigt leider meine Fähigkeiten, auch wenn mir das natürlich lieber wäre.

    Gruß und vielen Dank für die Hilfe