Adressverwaltung mit Outlook-Schnittstelle, Teil 2

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

André Minhorst, Duisburg

In Ausgabe 4/2003 von Access im Unternehmen haben Sie die Adressverwaltung mit Outlook-Schnittstelle kennen gelernt. Im vorliegenden Beitrag erfahren Sie, wie Sie der Adressverwaltung neben dem Import von Outlook-Adressen einen entsprechenden Export hinzufügen, wie die einzelnen Elemente der Menüleiste genau funktionieren und wie die Berichte zur Ausgabe von Adressenlisten und Stammblättern zu den einzelnen Einträgen der Adressdatenbank aussehen.

Hinweis

Auf der beiliegenden Heft-CD finden Sie die Beispieldatenbanken zu der vorliegenden Musterlösung unter den Dateinamen Adress97.mdb (Access 97) und Adress00.mdb (Access 2000 und Access XP).

Nachdem Sie im ersten Teil dieser Beitragsreihe erfahren haben, wie der Import von Outlook-Kontakten in eine Access-Datenbank funktioniert, lernen Sie nun den umgekehrten Weg kennen.

Hinweis

Die nachfolgend beschriebenen und auch in den Musterlösungen enthaltenen Prozeduren und Funktionen ändern durch den Export von Adressdaten nach Outlook gegebenenfalls bereits vorhandene Daten. Sichern Sie deshalb unbedingt die Datei Outlook.pst, bevor Sie die Beispieldatenbanken ausprobieren. Um sicherzugehen, testen Sie die Funktionalität nicht auf Produktivsystemen.

Beschreibung des Exports

Die Aufgabe beim Import bestand im Wesentlichen darin, eventuell vorhandene Unternehmensdaten herauszufiltern, in die relational verknüpfte Tabelle tblUnternehmen zu schreiben und im Feld UnternehmenID der Tabelle tblAdressen einen entsprechenden Wert für die Verknüpfung zum Unternehmensdatensatz anzulegen.

Beim Transport der Adressdaten in die andere Richtung gibt es zwei Besonderheiten: Erstens werden die mühselig aufgesplitteten Unternehmensdaten wieder direkt in die einzelnen Kontaktdatensätze geschrieben.

Die zweite Besonderheit ist, dass es in Outlook durchaus mehrere Ordner zur Speicherung von Kontakten geben kann. Dementsprechend ist vorher festzulegen, in welchem Ordner die zu exportierenden Kontakte gespeichert werden sollen.

Ein ähnliches Problem wie beim Import in die Datenbank ergibt sich auch beim Export, nämlich die überprüfung eventuell vorhandener Daten.

Da Outlook mit der EntryID einen eindeutigen Schlüssel für jegliche Objekte enthält, wird dieser beim Import in die Datenbank in der Tabelle tblAdressen gespeichert.

Beim Exportieren von Daten aus der Datenbank nach Outlook sollen zwei überprüfungen vorgenommen werden: Erstens nach der EntryID und zweitens nach der Kombination aus Vor- und Nachname des Kontakts. Wie auch beim Import sollen für den Fall des Vorhandenseins des Kontaktes drei Möglichkeiten vorgesehen werden:

Bild 1: Formular für den Export von Adressdaten nach Outlook

  • überschreiben des vorhandenen Datensatzes
  • Verwerfen des Exports für den aktuellen Datensatz
  • Synchronisation beziehungsweise Vergleich der beiden Datensätze
  • Eine weitere offene Frage ist, ob nur der Zielordner von Outlook nach Duplikaten durchsucht werden soll oder alle Ordner. Der letztere Fall zieht die Frage nach sich, ob bei einem Duplikat eines Kontaktes in einem anderen Ordner als dem Zielordner dieser gelöscht und der neue Kontakt im Zielordner angelegt werden oder ob der neue Kontakt den bestehenden Kontakt im ursprünglichen Ordner ersetzen soll.

    Da vermutlich der Großteil der Outlookanwender ohnehin nur einen Kontaktordner verwendet, soll diesen Fragen im vorliegenden Fall aus dem Weg gegangen werden, indem nur der Zielordner untersucht wird.

    Formular zur Steuerung des Exports

    Das Formular aus Bild 1 enthält die notwendigen Steuerelemente, um die Einstellungen für den Export vorzunehmen und den Export einzuleiten.

    Im oberen Bereich kann der Benutzer den Ordner festlegen, in dem die zu exportierenden Kontakte gespeichert werden sollen. Der zweite Bereich dient der Auswahl der zu exportierenden Adressen. Das Listenfeld ist für eine Mehrfachauswahl ausgelegt.

    Im dritten Bereich finden Sie die bereits vom Import bekannten drei Möglichkeiten, wie die Anwendung im Falle bereits vorhandener Kontakte reagieren soll. Mit einem Mausklick auf die Schaltfläche Exportieren wird der Export gestartet. Sofern dies nicht zu schnell geht, können Sie das Voranschreiten des Exports auf dem Fortschrittsbalken ablesen.

    Funktion desFormulars

    Die Auswahl des Zielordners sowie der zu exportierenden Kontakte beinhaltet keine Besonderheiten und soll daher an diese Stelle nicht weiter beschrieben werden.

    Private Function AdressenExportieren()
        Dim appOutlook As Object
        Dim olNamespace As Object
        Dim olOrdner As Object
        Dim Eintrag As Variant
        Dim ExportEntryID As String
        Dim i As Integer
        Dim AdressID As Integer
        Dim Breitenintervall As Single
        On Error GoTo AdressenExportieren_Err
        If Me.lstAdressen.ItemsSelected.Count = 0 Then
            MsgBox "Sie haben keine Kontakte ausgewählt.", vbOKOnly + vbExclamation, _
            "Fehlende Eingabe"
            Exit Function
        End If
        Set appOutlook = GetObject(, "Outlook.Application")
        On Error GoTo 0
        Set olNamespace = appOutlook.GetNamespace("MAPI")
        Set olOrdner = olNamespace.GetFolderFromID(Me.txtEntryID)
        i = 0
        Breitenintervall = Me!recLaenge.Width / Me!lstAdressen.ItemsSelected.Count
        For Each Eintrag In Me!lstAdressen.ItemsSelected
            AdressID = Me!lstAdressen.Column(6)
            i = i + 1
            Me!recFortschrittsbalken.Width = i * Breitenintervall
            If Me!lstAdressen.ItemData(Eintrag) = "" Then
                ExportEntryID = KontaktVorhandenName(Me!lstAdressen.Column(1), _
                    Me!lstAdressen.Column(2), olOrdner)
                If Not ExportEntryID = "" Then
                    If Me!ogrExport = 1 Then
                        AdresseExportieren AdressID, olOrdner, ExportEntryID, olNamespace
                    Else
                        If Me.ogrExport = 3 Then
                            If Synchronisieren(AdressID, ExportEntryID) = True Then
                                AdresseExportieren AdressID, olOrdner, ExportEntryID, _
                                    olNamespace
                            End If
                        End If
                    End If
                Else
                    AdresseExportieren AdressID, olOrdner
                End If
            Else
                ExportEntryID = KontaktVorhandenEntryID(Me!lstAdressen.Column(0), _
                    olNamespace, olOrdner)
                If ExportEntryID = "" Then
                    ExportEntryID = KontaktVorhandenName(Me!lstAdressen.Column(1), _
                        Me!lstAdressen.Column(2), olOrdner)

    Quellcode 1 (Teil 1)

    Auch die Anzeige des Fortschrittbalkens ist bereits aus dem ersten Teil dieser Beitragsreihe bekannt.

    Interessant ist die Funktion, die durch das Betätigen der Schaltfläche Exportieren aufgerufen wird (s. Quellcode 1).

    Die Funktion deklariert zunächst die benötigten Variablen und überprüft anschließend, ob der Anwender überhaupt mindestens einen Eintrag aus dem Listenfeld markiert hat. Falls nicht, gibt die Prozedur eine entsprechende Fehlermeldung aus.

                End If
                If Not ExportEntryID = "" Then
                    If Me!ogrExport = 1 Then
                        AdresseExportieren AdressID, olOrdner
                    Else
                        If Me.ogrExport = 3 Then
                            If Synchronisieren(AdressID, ExportEntryID) = True Then
                                AdresseExportieren AdressID, olOrdner
                            End If
                        End If
                    End If
                Else
                    AdresseExportieren AdressID, olOrdner
                End If
            End If
        Next Eintrag
        Me!cmdBeenden.Enabled = True
        Exit Function
    AdressenExportieren_Err:
        If Err.Number = 429 Then
            Set appOutlook = CreateObject("Outlook.Application")
            Resume Next
        End If
    End Function

    Quellcode 1 (Fortsetzung)

    Anderenfalls versucht die Funktion zunächst, auf eine bestehende Instanz von Outlook zu verweisen. Ist keine vorhanden, wird über die eigens für diesen Fall angelegte Fehlerbehandlung eine neue Instanz erzeugt.

    Die Variablen olNamespace und olFolder erhalten Verweise auf den Namespace MAPI beziehungsweise den im Formular ausgewählten Kontaktordner.

    Mit einer For Each-Schleife durchläuft die Funktion alle im Listenfeld markierten Einträge. Innerhalb der Schleife gibt es zwei Möglichkeiten: Entweder der Kontakteintrag hat bereits eine EntryID oder nicht. Falls nicht, durchsucht die Funktion den gewählten Kontaktordner in der Funktion KontaktVorhandenName nach einem Kontakt mit dem im Listenfeld angezeigten Vor- und Nachnamen.

    Ist eine EntryID für den Kontakt vorhanden, sucht die Funktion mit Hilfe der Funktion KontaktVorhandenEntryID nach dieser. Sollte dieser Kontakt nicht zuvor aus dieser Outlook.pst-Datei importiert worden sein, und die Funktion KontaktVorhandenEntryID findet keinen entsprechenden Kontakt, wird vorsichtshalber noch die Funktion KontaktVorhandenName verwendet, um nach eventuell vorhandenen Kontakten mit gleichem Vor- und Nachnamen zu suchen.

    Private Function KontaktVorhandenName(Nachname As String, Vorname As String, _
        olOrdner As Object) As String
        Dim olElement As Object
        Set olElement = olOrdner.Items.Find("[FirstName] = ''" & Vorname _
            & "'' AND [LastName] = ''" & Nachname & "''")
        If Not olElement Is Nothing Then
            KontaktVorhandenName = olElement.EntryID
        End If
    End Function

    Quellcode 2

    Private Function KontaktVorhandenEntryID(EntryID As String, olNamespace As Object, _
        olOrdner As Object) As String
        Dim olElement As Object
        Set olElement = olNamespace.GetItemFromID(EntryID)
        If olElement.Parent = olOrdner Then
            If Not olElement Is Nothing Then
                KontaktVorhandenEntryID = olElement.EntryID
            End If
        Else
            KontaktVorhandenEntryID = ""
        End If
    End Function

    Quellcode 3

    Der weitere Verlauf ist in beiden Teilen des If Then-Konstrukts gleich: Die Prozedur wertet die eingegebene Option bezüglich der Vorgehensweise bei vorhandenem Kontakt aus und verwendet die Funktion AdressenExportieren mit unterschiedlichen Parametern, um den Kontakt nach Outlook zu exportieren.

    Suchen von Kontakten nach Namen

    Wenn der zu exportierende Kontakt keinen Eintrag für das Feld EntryID hat, durchsucht die Funktion aus Quellcode 2 den Zielordner nach einem Kontakt mit dem gleichen Vor- und Nachnamen. Dabei werden als Parameter der Vor- und der Nachname sowie der Zielordner übergeben.

    Die Suche erfolgt über die Methode Find der Items-Auflistung des Zielordners. Die Syntax des Kriteriums entspricht der bei Access-Filtern verwendeten Syntax. Falls ein entsprechender Eintrag gefunden wird, gibt die Funktion dessen EntryID zurück.

    Suchen von Kontakten nach EntryID

    Wenn das Feld EntryID des zu exportierenden Kontaktes einen Wert enthält, ruft die Prozedur cmdExportieren_Click zunächst die Funktion KontaktVorhandenEntryID auf. Die Funktion erwartet als Parameter die EntryID, das Namespace-Objekt und den Zielordner. Sie verwendet die Methode GetItemFromID des Namespace-Objektes, um einen Verweis auf den gewünschten Kontakt herzustellen. Die Funktion durchsucht allerdings den gesamten Namespace und nicht nur den Zielordner (s. Quellcode 3).

    Daher überprüfen Sie noch, ob das Parent-Element des Kontaktes – in dem Fall der Ordner, in dem es sich befindet – mit dem übergebenen Zielordner identisch ist.

    Private Function AdresseExportieren(AdressID As Integer, olOrdner As Object, _
        Optional EntryID As String, Optional olNamespace As Object)
        Dim olElement As Outlook.ContactItem
        Dim db As Database
        Dim rstAdressen As Recordset
        If IsMissing(EntryID) Or EntryID = "" Then
            Set olElement = olOrdner.Items.Add(olContactItem)
        Else
            Set olElement = olNamespace.GetItemFromID(EntryID)
        End If
        Set db = CurrentDb
        Set rstAdressen = db.OpenRecordset("SELECT * FROM tblAdressen WHERE AdressID = " _
            & AdressID, dbOpenDynaset)
        olElement.Title = Nz(DLookup("Anrede", "tblAnreden", "AnredeID = " _
            & rstAdressen!AnredeID), "")
        olElement.FirstName = Nz(rstAdressen!Vorname, "")
        olElement.LastName = Nz(rstAdressen!Nachname, "")
        olElement.HomeAddressStreet = Nz(rstAdressen!Strasse, "")
        olElement.HomeAddressPostalCode = Nz(rstAdressen!PLZ, "")
        olElement.HomeAddressCity = Nz(rstAdressen!Ort, "")
        olElement.HomeTelephoneNumber = Nz(rstAdressen!Telefon, "")
        olElement.HomeFaxNumber = Nz(rstAdressen!Telefax, "")
        olElement.MobileTelephoneNumber = Nz(rstAdressen!Mobil, "")
        olElement.Email1Address = Nz(rstAdressen!EMail, "")
        olElement.WebPage = Nz(rstAdressen!Internetadresse, "")
        olElement.Gender = Nz(rstAdressen!GeschlechtID, 0)
        olElement.Categories = Nz(DLookup("Kategorie", "tblKategorien", "KategorieID = " _
            & Nz(rstAdressen!KategorieID, 0)), "")
        olElement.Birthday = Nz(rstAdressen!Geburtsdatum, 0)
        olElement.CompanyName = Nz(DLookup("Unternehmen", "tblUnternehmen", _
            "UnternehmenID = " & Nz(rstAdressen!UnternehmenID, 0)), "")
        olElement.Department = Nz(rstAdressen!Abteilung, "")
        olElement.JobTitle = Nz(DLookup("Position", "tblPositionen", "PositionID = " _
            & Nz(rstAdressen!PositionID, 0)), "")
        olElement.BusinessTelephoneNumber = Nz(rstAdressen!TelefonGeschaeftlich, "")
        olElement.BusinessFaxNumber = Nz(rstAdressen!TelefaxGeschaeftlich, "")
        olElement.Email2Address = Nz(rstAdressen!EMailGeschaeftlich, "")
        olElement.Save
        rstAdressen.Edit
        rstAdressen!EntryID = olElement.EntryID
        rstAdressen.Update
    End Function

    Quellcode 4

    Falls ja, wird die EntryID als Bestätigung an die aufrufende Prozedur zurückgegeben. Falls nein, erfolgt die Rückgabe einer leeren Zeichenkette.

    Exportieren der Kontaktdaten

    Die Funktion AdresseExportieren dient zum Exportieren eines einzelnen Eintrags der Tabelle tblAdressen in den ausgewählten Kontaktordner von Outlook (s. Quellcode 4).

    Sie wird von der Funktion AdressenExportieren aufgerufen (beachten Sie den feinen Unterschied der Benennung der Funktionen) und erwartet zwischen zwei und vier Parameter. Die beiden Parameter AdressID und olOrdner sind Pflicht. Sie geben an, welcher Adressdatensatz in welchen Outlookordner exportiert werden soll.

    Der Parameter EntryID wird nur übergeben, wenn der Datensatz eine EntryID enthält, die auch in Outlook bereits vorhanden ist. Damit die Funktion AdresseExportieren schnell auf diesen Eintrag zugreifen kann, wird das bereits gefüllte Namespace-Objekt olNamespace mit übergeben. über dessen Funktion GetItemFromID und die EntryID kann die Funktion schnell auf den zu überschreibenden Kontakt zugreifen.

    Nach dem Deklarationsteil überprüft die Funktion zunächst, ob der Parameter EntryID übergeben wurde. Falls ja, wird der entsprechende Eintrag des Outlookordners der Variablen olElement zugewiesen, falls nein, wird ein neuer Eintrag erzeugt.

    Zur Prüfung des Vorhandenseins des optional zu übergebenden Parameters wird die Funktion IsMissing verwendet.

    Anschließend öffnet die Funktion die Datensatzgruppe rstAdressen und weist ihr den Datensatz aus der Tabelle tblAdressen mit der übergebenen AdressID zu.

    Die nachfolgenden Anweisungen tragen alle Informationen des Adressdatensatzes in das Kontaktelement ein. Das Kontaktelement wird gespeichert, damit dem Element eine EntryID zugewiesen wird, falls noch keine vorhanden ist.

    Das ist vor allem für den nachfolgenden Schritt wichtig, in dem die EntryID des Adressdatensatzes der Datenbank der aktuellen EntryID des Kontaktes in Outlook angepasst wird.

    Auf diese Weise stellt die Funktion eine lose Verknüpfung zwischen dem Adressdatensatz der Tabelle und dem Kontaktelement in Outlook her.

    Die Anwendung enthält drei Berichte zur Ausgabe von Adressenlisten, Personen- und Unternehmendatenblättern.

    Bericht zur Ausgabe vonAdressenlisten

    Der erste Bericht dient der Ausgabe einer Adressenliste. Wenn der Bericht über den Menüeintrag Berichte/Adressenliste geöffnet wird, zeigt er die komplette Adressenliste an. Um nur die gewünschten Einträge der Adressenlisten anzuzeigen, kann das Formular frmAdressenliste verwendet werden. Dort können Sie zunächst nach den gewünschten Kriterien filtern und anschließend den Bericht mit der Schaltfläche Liste anzeigen öffnen.

    Eine Ausnahme liegt vor, wenn der Bericht über den Menüeintrag geöffnet wird, das Formular aber ebenfalls offen ist. In dem Fall werden trotzdem die in dem Formular festgelegten Kriterien verwendet.

    Alle oder nicht alle

    Der Bericht überprüft beim öffnen, ob das Formular frmAdressenliste geöffnet ist. Das geschieht mit der Prozedur aus Quellcode 5, die durch das Ereignis Beim öffnen des Berichtes ausgelöst wird. Wenn das Formular geöffnet wird, verwendet der Bericht nicht die voreingestellte Datenherkunft, sondern die Datenherkunft des Formulars frmAdressenliste.

    Aufbau des Berichts

    Der Bericht besteht aus drei Bereichen, dem Seitenkopf- und Fuß sowie dem Detailbereich.

    Private Sub Report_Open(Cancel As Integer)
        If IstFormularGeoeffnet("frmAdressenliste") Then
            Me.RecordSource = _
                Forms!frmAdressenliste!lstAdressen.RowSource
        End If
    End Sub

    Quellcode 5

    Der Seitenkopf enthält die Hauptüberschrift sowie die überschriften der einzelnen Spalten des tabellarischen Berichts.

    Der Seitenfuß enthält zwei Steuerelemente zur Anzeige von Datum und Seitenzahl. Das Textfeld txtDatum enthält den folgenden Ausdruck als Steuerelementinhalt:

    =Datum()

    Die Seitenzahl wird im Textfeld txtSeiten angezeigt:

    ="Seite " & [Seite] & "/" & [Seiten]

    Im Detailbereich befinden sich die für eine Adressenliste notwendigen Daten wie Name, Adressdaten sowie Telefonnummern, E-Mailadresse und Internetadresse (siehe Bild 2).

    Privat und geschäftlich

    SELECT AdressID, Bezeichnung, Strasse, PLZ, Ort, Typ, Typbezeichnung, Telefon, 
        Telefax, Mobil, EMail, '''' AS Internetadresse FROM qryPersonenGeschaeftlich
    UNION
    SELECT AdressID, Bezeichnung, Strasse, PLZ, Ort, Typ, Typbezeichnung, Telefon, 
        Telefax, Mobil, EMail, Internetadresse FROM qryPersonenPrivat
    UNION
    SELECT AdressID, Bezeichnung, Strasse, PLZ, Ort, Typ, Typbezeichnung, Telefon,
        Telefax, Mobil, EMail, Internetadresse FROM qryUnternehmen;

    Quellcode 6

    Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

    Testzugang

    eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

    diesen und alle anderen Artikel mit dem Jahresabo

    Schreibe einen Kommentar