Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Anzeige
Inhaltsverzeichnis

Outlook Verteiler Makro

Forumthread: Outlook Verteiler Makro

Outlook Verteiler Makro
01.04.2025 01:04:49
Tob1as
Liebe Excel Begeisterte,

ich sitze nun einige Stunden an folgendem Problem. Also völliger VBA Anfänger eine echt schwierige Sache! Folgende Situation:

Ich habe ein Blatt mit allen möglichen Daten zu Personen, die in den Zeilen 5 bis 71 zu finden sind. In Spalte A sind die Vornamen, in B die Nachnamen, in J die Mailadressen. Es gibt auch leere Zeilen in dieser Tabelle. Die sollen dann natürlich nicht mit aufgenommen werden.
Ziel ist es, einen E-Mail-Verteiler und einzelne Kontakte aus diesen Daten zu erstellen. Die Kontakte und der Verteiler sollen den Namen "Verteiler Test" haben und unter folgendem Mailkonto in Outlook gespeichert werden: test@outlook.de

Die Schwierigkeit besteht jetzt darin, noch folgende Dinge zu berücksichtigen:
  • in Spalte J sind teilweise mehrere Mailadresse eingetragen. Beispiel: franz@outlook.de; franzspam@outlook.de. Beide Mailadressen sollen dem Verteiler so hinzugefügt werden, sodass Mails, die über den Verteiler gesendet werden, an beide Adressen gesendet werden. Am besten wäre es natürlich, wenn diese unter einem Kontakt gespeichert werden. Ist das aber möglich?

  • in Spalte J werden manchmal Mailadressen doppelt aufgeführt. Natürlich sollen Kontakte und Einträge im Verteiler nur einmal vorkommen. Jedoch sollen die Namen der Personen dann kombiniert im Kontaktkärtchen auftauchen (Beispiel: Peter Klug - klug@outlook.de | Heinrich Klug - klug@outlook.de | wird dann zu "Peter Klug & Heinrich Klug"). Das müsste also ebenfalls berücksichtigt werden.

  • in meinem Outlook Kontakten sind bereits einige der Mailadressen aufgeführt. Ich möchte verhindern, dass, bspw. auch bei mehrmaligem Betätigen des Makros, Kontakte in mehrfacher Ausführung vorhanden sind. Gibt es eine Möglichkeit, dass Kontakte, die mit einer der Mailadressen aus der Exceldatei versehen sind, durch den neu erstellten Kontakt ersetzt werden?


  • Eine Reihe an Bedingungen/Wünschen... Ich hoffe, jemand kann mir beistehen und mir weiterhelfen.

    Vielen Dank und herzliche Grüße
    Tobias
    Anzeige

    10
    Beiträge zum Forumthread
    Beiträge zu diesem Forumthread

    Betreff
    Datum
    Anwender
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 09:17:10
    MCO
    Moin!

    Bevor du so gar nix anbietest, hättest du ja wenigstens schonmal deine Test-Excel-Datei einbringen können.
    Auch ein Ansatz von Projekt hättest du schon haben können: nimm deinen Anfrage-Text und schieb ihn Chatgpt zu. Da wird keine 100%ige Lösung rauskommen, aber ne verwertbare Grundlage oder wenigsten eine Richtung!

    Ohne alles ist alles nix :-(

    Gruß, MCO
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 10:59:37
    Alwin Weisangler
    Hallo Tobias,

    da du uns nur Text anbietest, bekommst du natürlich auch nur Text zum selbst ausprobieren.

    Zur Frage mehrere Email Adressen in einer Zelle der Spalte J:
    nimm die Funktion Split(expression, [delimiter]) und weise dies einer Variant Variable zu.

    Ohne Doppelte Email Adressen einlesen in ein Array kann man mit z.B. einer Zuweisung als Key eines Dictionary Objektes.
    Ansonsten braucht es nur noch in ein entsprechendes Merkmal deiner Wahl um ein Array mit den passenden Email Adressen zu füllen.
    Das kann dann via Join(sourcearray, [ delimiter ]) mit dem passenden Delimiter versehen werden um das Mail zu versenden.
    Wenn dies dir nicht hilft lade bitte anonymisiert eine adäquate Beispieldatei hoch.

    Gruß Uwe
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 11:53:58
    Tob1as
    Hallo zusammen,

    vielen Dank, das hat mich bereits etwas weiter gebracht. Da ich von programmieren nicht viel verstehe und mich bisher mit chatgpt durchgekämpft habe, habe ich versucht deine Ansätze einzubauen:

    Sub ErstelleOutlookVerteiler()
    
    Dim olApp As Object
    Dim olNamespace As Object
    Dim olFolder As Object
    Dim olDistList As Object
    Dim olContact As Object
    Dim dictEmails As Object
    Dim dictContacts As Object
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim vorname As String, nachname As String, email As String
    Dim emails As Variant, key As Variant, fullName As String

    ' Outlook-Objekte initialisieren
    Set olApp = CreateObject("Outlook.Application")
    Set olNamespace = olApp.GetNamespace("MAPI")
    Set olFolder = olNamespace.Folders("test@outlook.de").Folders("Contacts")

    ' Dictionary zum Speichern von eindeutigen E-Mail-Adressen
    Set dictEmails = CreateObject("Scripting.Dictionary")
    Set dictContacts = CreateObject("Scripting.Dictionary")

    ' Arbeitsblatt festlegen
    Set ws = ThisWorkbook.Sheets("Teilnehmer")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' Bestehende Kontakte durchsuchen und in Dictionary speichern
    Dim olItems As Object, olItem As Object
    Set olItems = olFolder.Items
    For Each olItem In olItems
    If TypeName(olItem) = "ContactItem" Then
    If Not dictEmails.exists(LCase(olItem.Email1Address)) Then
    dictEmails.Add LCase(olItem.Email1Address), olItem
    End If
    End If
    Next olItem

    ' Daten aus Excel durchgehen
    For i = 2 To lastRow
    vorname = Trim(ws.Cells(i, 1).Value)
    nachname = Trim(ws.Cells(i, 2).Value)
    email = Trim(ws.Cells(i, 10).Value) ' Spalte J = 10

    If vorname > "" And nachname > "" And email > "" Then
    emails = Split(email, ";")
    Dim e As Variant
    For Each e In emails
    e = Trim(e)
    key = LCase(e)
    If key > "" Then
    If dictEmails.exists(key) Then
    fullName = dictEmails(key).FullName & " & " & vorname & " " & nachname
    dictEmails(key).FullName = fullName
    dictEmails(key).Save
    Else
    Set olContact = olFolder.Items.Add("IPM.Contact")
    olContact.FullName = vorname & " " & nachname
    olContact.Email1Address = e
    olContact.Save
    dictEmails.Add key, olContact
    End If
    End If
    Next e
    End If
    Next i

    ' Verteilerliste erstellen
    Set olDistList = olFolder.Items.Add(7) ' 7 = olDistributionList
    olDistList.DLName = "Verteiler Test"
    Dim Recipients As Object
    Set Recipients = olDistList

    Dim k As Variant
    For Each k In dictEmails.keys
    Set olContact = dictEmails(k)
    olDistList.AddMember olContact
    Next k

    olDistList.Save
    MsgBox "Outlook-Kontakte und Verteiler wurden erfolgreich erstellt!", vbInformation

    ' Objekte freigeben
    Set olDistList = Nothing
    Set olContact = Nothing
    Set olFolder = Nothing
    Set olNamespace = Nothing
    Set olApp = Nothing
    End Sub


    Hier auch eine Beispiel Excel: https://www.herber.de/bbs/user/176522.xlsx

    Vielen Dank für eure Hilfe!
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 12:29:56
    Alwin Weisangler
    Hallo Tobias,

    das sollte dir weiterhelfen:
    
    
    Option Explicit
    Dim MailListe$

    Sub AdressenAuflisten()
    Dim tmp, i&, zelle As Range, objDic As Object
    Set objDic = CreateObject("Scripting.Dictionary")
    For Each zelle In Tabelle1.Range("Tabelle2[Email]")
    tmp = Split(zelle.Value, ";")
    For i = LBound(tmp) To UBound(tmp)
    objDic(tmp(i)) = 0
    Next i
    Next
    MailListe = Join(objDic.keys, ", ")
    End Sub

    Die Variable MailListe enthält den aufbereiteten String den du an .CC übergeben kannst.

    Gruß Uwe
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 12:33:29
    Alwin Weisangler
    Noch zur Ergänzung:

    Wenn Adressaten aus dem Rundmail ausgeschlossen werden sollen, braut es eine weitere Spalte in der Tabelle, wo dies eindeutig erkennbar ist. Diese Spalte fehlt in der Beispieldatei.

    Gruß Uwe
    AW: Outlook Verteiler Makro
    01.04.2025 12:48:49
    Alwin Weisangler
    anbei noch mit selekierter Auswahl und Beispielversand.
    https://www.herber.de/bbs/user/176524.xlsm

    Gruß Uwe
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 14:31:21
    Tob1as
    Hallo!
    Ich habe nun hin und her probiert und bei zwei Problemen komme ich nicht weiter:
    1. Die Einträge aus der Excel werden mittlerweile gut in die Kontaktliste in Outlook übertragen. Allerdings wird der Verteiler nicht mit Mitgliedern gefüllt und bleibt immer leer. Ich finde den Fehler nicht.
    2. Bei mehrmaligem Ausführen des Makros passiert nach dem ersten Mal nichts mehr, da ja auch keine Änderungen vorgenommen wurden. Ändere ich jetzt aber ein Feld auf dem Blatt "Teilnehmer", auf dem die Mailadressen und Namen stehen, so wird ein bestimmter Eintrag unerklärlicherweise wieder als Kontakt hinzugefügt, obwohl dieser bereits besteht und ich dieses Feld nicht verändert habe. Es handelt sich dort um folgende Situation: Zeile 21: Anton Friedrich - papa.friedrich@test.de; mama.friedrich@test.de | Zeile 22: Fridulin Friedrich - papa.friedrich@test.de; mama.friedrich@test.de
    Für die zweite Mailadresse wird der Kontakt dann mehrmals erstellt, für die erste funktioniert das Makro wie gewünscht. An einer anderen Stelle habe ich ebenfalls den Fall, dass mehrere Mailadressen in verschiedenen Zeilen vorkommen (Teilnehmer sind Geschwister). Dort wird kein Kontakt mehrmals erstellt. Wo liegt der Fehler?

    Ich komme einfach nicht dahinter, was falsch ist. Dafür kenne ich mich einfach nicht gut genug aus.

    Folgenden Code habe ich bisher:
    Sub OutlookVerteiler()
    
    Dim olApp As Object
    Dim olNamespace As Object
    Dim olFolder As Object
    Dim olDistList As Object
    Dim olContact As Object
    Dim dictEmails As Object
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim vorname As String, nachname As String, email As String
    Dim emails As Variant, key As Variant, fullName As String
    Dim addedContacts As Long ' Zählt die hinzugefügten Kontakte
    Dim olDistLists As Object
    Dim existingDistList As Object
    Dim distListName As String
    Dim olContactItem As Object

    distListName = "Verteiler Test" ' Der Name des Verteilers

    ' Outlook-Objekte initialisieren
    Set olApp = CreateObject("Outlook.Application")
    Set olNamespace = olApp.GetNamespace("MAPI")
    Set olFolder = olNamespace.GetDefaultFolder(10) ' 10 = olFolderContacts

    ' Dictionary zum Speichern von eindeutigen E-Mail-Adressen
    Set dictEmails = CreateObject("Scripting.Dictionary")

    ' Arbeitsblatt festlegen
    Set ws = ThisWorkbook.Sheets("Teilnehmer") ' Tabellenblatt "Teilnehmer"
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row

    ' Bestehende Kontakte durchsuchen und in Dictionary speichern
    Dim olItems As Object
    Set olItems = olFolder.Items
    For Each olItem In olItems
    If TypeName(olItem) = "ContactItem" Then
    If Not dictEmails.exists(LCase(olItem.Email1Address)) Then
    dictEmails.Add LCase(olItem.Email1Address), olItem
    End If
    End If
    Next olItem

    ' Daten aus Excel durchgehen (nur Zeile 2 bis 71)
    For i = 2 To 71 ' Zeilen 2 bis 71
    vorname = Trim(ws.Cells(i, 1).Value)
    nachname = Trim(ws.Cells(i, 2).Value)
    email = Trim(ws.Cells(i, 10).Value) ' Spalte J = 10

    If vorname > "" And nachname > "" And email > "" Then
    emails = Split(email, ";")
    Dim e As Variant
    For Each e In emails
    e = Trim(e)
    key = LCase(e)
    If key > "" Then
    ' Wenn Kontakt bereits existiert, Name aktualisieren
    If dictEmails.exists(key) Then
    fullName = dictEmails(key).fullName
    ' Prüfen, ob der Name bereits vorhanden ist
    If InStr(fullName, vorname & " " & nachname) = 0 Then
    dictEmails(key).fullName = fullName & " & " & vorname & " " & nachname
    dictEmails(key).Save
    End If
    Else
    ' Neuen Kontakt erstellen
    Set olContact = olFolder.Items.Add("IPM.Contact")
    olContact.fullName = vorname & " " & nachname
    olContact.Email1Address = e
    olContact.Save
    dictEmails.Add key, olContact
    addedContacts = addedContacts + 1 ' Zählen der hinzugefügten Kontakte
    End If
    End If
    Next e
    End If
    Next i

    ' Überprüfen, ob der Verteiler bereits existiert
    Set olDistLists = olFolder.Items
    On Error Resume Next ' Fehler ignorieren, falls kein Verteiler gefunden wird
    Set existingDistList = Nothing
    For Each olItem In olDistLists
    If TypeName(olItem) = "DistListItem" Then
    If olItem.DLName = distListName Then
    Set existingDistList = olItem
    Exit For
    End If
    End If
    Next olItem
    On Error GoTo 0 ' Fehlerbehandlung zurücksetzen

    ' Falls der Verteiler existiert, löschen
    If Not existingDistList Is Nothing Then
    existingDistList.Delete
    End If

    ' Verteilerliste erstellen
    Set olDistList = olFolder.Items.Add(7) ' 7 = olDistributionList
    olDistList.DLName = distListName

    ' Alle eindeutigen E-Mail-Adressen zum Verteiler hinzufügen
    Dim k As Variant
    For Each k In dictEmails.keys
    Set olContact = dictEmails(k)

    ' Erstelle einen Recipient-Objekt für jedes Kontaktmitglied
    Dim olRecipient As Object
    Set olRecipient = olApp.CreateItem(0) ' 0 = olMailItem
    olRecipient.Recipients.Add olContact.Email1Address

    ' Füge den Kontakt zur Verteilerliste hinzu
    olDistList.AddMember olRecipient
    Next k

    olDistList.Save

    ' Erfolgsnachricht mit der Anzahl der hinzugefügten Kontakte
    MsgBox addedContacts & " Kontakte wurden erfolgreich zum Verteiler hinzugefügt!", vbInformation

    ' Objekte freigeben
    Set olDistList = Nothing
    Set olContact = Nothing
    Set olFolder = Nothing
    Set olNamespace = Nothing
    Set olApp = Nothing
    End Sub


    Kann mir jemand weiterhelfen?

    Viele Grüße
    Tobias
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 15:50:26
    Alwin Weisangler
    Hallo Tobias,

    dass du den Verteiler von Outlook nutzen willst habe ich jetzt erst gesehen/verstanden.

    Du musst in einer Schleife die Adressliste abarbeiten und in dieser Schleife eine 2. Schleife anlegen, welche prüft, ob die Email Adressen schon verarbeitet wurde.
    Die verarbeiteten Email Adressen kannst du in einem String einlesen und anfügen und via Instr() prüfen ob diese Adresse bereits verarbeitet ist.
    Was über diesen Weg passieren kann, wenn du den Namen ausliest, dass logischerweise dann nicht mehrere Namen mit dieser einen gleichen Mailadresse mehr im Verteiler erscheinen.
    Falls dies aber zwingend nötig ist und trotzdem jede Email Adresse nur einmalig im Verteiler gesetzt sein soll, musst du die Namen welche zu einer Emailadresse gehören in einem String sammeln und dann in den Verteiler (via Item.Add) schreiben.

    Gruß Uwe
    Anzeige
    AW: Outlook Verteiler Makro
    01.04.2025 19:30:59
    Alwin Weisangler
    Hallo Tobias,

    ich habe jetzt mal entsprechend MS Hilfe die Übergabe der Members in die Memberliste angeschaut.
    Da scheint es so, dass MS die Funktion .AddMembers abgeschaltet hat.

    Auf jeden Fall erfolgt keine Übernahme der Members, welche in Recipients gesammelt wurden mehr zu funktionieren. Zumindest passiert dies in O2019.

    Gruß Uwe
    Anzeige
    AW: Outlook Verteiler Makro
    02.04.2025 00:33:56
    Tob1as
    Hallo Uwe,

    ich habe es nun nach Ewigkeiten des Probierens mithilfe von chatgpt geschafft.

    Danke für deine Hilfe!

    Viele Grüße
    Tobias

    Hier der finale Code, der bisher gut funktioniert hat:


    Option Explicit
    

    Sub OutlookVerteiler()
    Dim olApp As Object
    Dim olNamespace As Object
    Dim olFolder As Object
    Dim olDistList As Object
    Dim olRecipient As Object
    Dim dictEmails As Object
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim vorname As String, nachname As String, email As String
    Dim emails As Variant, key As Variant
    Dim olItems As Object
    Dim olItem As Object
    Dim olDistLists As Object
    Dim existingDistList As Object
    Dim distListName As String
    Dim dictContacts As Object
    Dim contactExists As Boolean
    Dim updatedContacts As Long

    distListName = "NAME VERTEILER"

    ' Outlook-Objekte initialisieren
    On Error Resume Next
    Set olApp = CreateObject("Outlook.Application")
    If Err.Number > 0 Then
    MsgBox "Fehler: Outlook konnte nicht gestartet werden.", vbCritical
    Exit Sub
    End If
    On Error GoTo 0

    Set olNamespace = olApp.GetNamespace("MAPI")
    Set olFolder = olNamespace.Folders("beispiel@email.de").Folders("Kontakte") ' Kontakte-Ordner des spezifischen Postfachs

    ' Dictionary für E-Mail-Adressen und zugehörige Namen
    Set dictEmails = CreateObject("Scripting.Dictionary")
    Set dictContacts = CreateObject("Scripting.Dictionary") ' Speichert Kontakte mit Name-Email-Zuordnung

    ' Arbeitsblatt festlegen
    Set ws = ThisWorkbook.Sheets("TABELLENBLATT")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row

    ' Daten aus Excel durchgehen
    For i = 2 To lastRow
    vorname = Trim(ws.Cells(i, 1).Value)
    nachname = Trim(ws.Cells(i, 2).Value)
    email = Trim(ws.Cells(i, 10).Value) ' Spalte J = 10

    ' Stelle sicher, dass nur gültige Zeilen verarbeitet werden
    If vorname > "" And nachname > "" And email > "" And InStr(email, "@") > 0 Then
    emails = Split(email, ";")
    Dim e As Variant
    For Each e In emails
    e = LCase(Trim(e))

    ' Falls E-Mail noch nicht existiert, hinzufügen
    If Not dictEmails.exists(e) Then
    dictEmails.Add e, vorname & " " & nachname
    Else
    ' Falls gleiche Mailadresse für Geschwister, Namen zusammenführen
    If InStr(dictEmails(e), vorname & " " & nachname) = 0 Then
    dictEmails(e) = dictEmails(e) & " & " & vorname & " " & nachname
    End If
    End If
    Next e
    End If
    Next i

    ' Bestehende Verteilerlisten durchsuchen
    Set olDistLists = olFolder.Items
    If olDistLists Is Nothing Then
    MsgBox "Fehler: Outlook-Kontakte konnten nicht geladen werden.", vbCritical
    Exit Sub
    End If

    Set existingDistList = Nothing
    On Error Resume Next
    For Each olItem In olDistLists
    If Not olItem Is Nothing Then
    If TypeName(olItem) = "DistListItem" Then
    If olItem.DLName = distListName Then
    Set existingDistList = olItem
    Exit For
    End If
    End If
    End If
    Next olItem
    On Error GoTo 0

    ' Falls der Verteiler existiert, löschen
    If Not existingDistList Is Nothing Then
    existingDistList.Delete
    End If

    ' Neuen Verteiler erstellen
    Set olDistList = olFolder.Items.Add(7) ' 7 = olDistributionList
    olDistList.DLName = distListName

    ' Mitglieder zum Verteiler hinzufügen
    For Each key In dictEmails.keys
    Set olRecipient = olApp.Session.CreateRecipient(key)
    olRecipient.Resolve
    If olRecipient.Resolved Then
    olDistList.AddMember olRecipient
    Else
    Debug.Print "Fehler: Konnte " & key & " nicht hinzufügen."
    End If
    Next key

    olDistList.Save

    ' Kontakte in Outlook hinzufügen oder aktualisieren
    Dim addedContacts As Long
    addedContacts = 0
    updatedContacts = 0

    For Each key In dictEmails.keys
    contactExists = False
    ' Bestehenden Kontakt suchen
    For Each olItem In olFolder.Items
    If TypeName(olItem) = "ContactItem" Then
    If LCase(Trim(olItem.Email1Address)) = key Or LCase(Trim(olItem.Email2Address)) = key Or LCase(Trim(olItem.Email3Address)) = key Then
    ' Falls der Name oder die Anzeige geändert werden muss
    If olItem.FullName > dictEmails(key) Or olItem.Email1DisplayName > dictEmails(key) Then
    olItem.FullName = dictEmails(key)
    olItem.Email1DisplayName = dictEmails(key)
    olItem.Save
    updatedContacts = updatedContacts + 1
    End If
    contactExists = True
    Exit For
    End If
    End If
    Next olItem

    ' Falls der Kontakt nicht existiert, neuen Kontakt anlegen
    If Not contactExists Then
    Dim olContact As Object
    Set olContact = olFolder.Items.Add("IPM.Contact")
    olContact.FullName = dictEmails(key)
    olContact.Email1Address = key
    olContact.Email1DisplayName = dictEmails(key)
    olContact.Save
    addedContacts = addedContacts + 1
    End If
    Next key

    ' Erfolgsnachricht
    MsgBox addedContacts & " Kontakte wurden erfolgreich hinzugefügt!" & vbCrLf & _
    updatedContacts & " Kontakte wurden erfolgreich aktualisiert!" & vbCrLf & _
    "Der Verteiler wurde aktualisiert!", vbInformation

    ' Objekte freigeben
    Set olDistList = Nothing
    Set olRecipient = Nothing
    Set olFolder = Nothing
    Set olNamespace = Nothing
    Set olApp = Nothing
    End Sub
    Anzeige

    Forumthreads zu verwandten Themen

    Anzeige
    Anzeige