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
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