Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Mit Delphi auf MS-Outlook-Kontakte zugreifen


Achenbach - Di 08.04.03 13:37
Titel: Mit Delphi auf MS-Outlook-Kontakte zugreifen
Hallo zusammen...

Ich habe gehört, das man mit Hilfe der Servers Komponenten auf MS-Produkte (bei mir Outlook) zugreifen kann. Gibt es dazu eine Help-Datei? Hat jemand Erfahrungen sammeln können? Wie greife ich von Delphi aus auf diese Kontakte zu ?

Vielen Dank im voraus....

Grüße

Christian Achenbach


foxy - Di 08.04.03 13:40

hi und herzlich willkommen im board

wenn du hier [http://www.swissdelphicenter.ch/de/showcode.php?id=897] schaust

wird dir geholfen ;)


Tino - Mi 09.04.03 09:40

Hier der Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
{Author:  Mike Shkolnik (mshkolnik@scalabium.com)
 Homepage: http://www.scalabium.com

So how to read a collection of Contacts which are exist in MS Outlook? 
This task is very popular. For example, you want to develop a sample tool 
which will notify you about birthday for someone or you want to send 
messages to "mailing list". So you want to naviagte thru list of defined 
contacts and process any item.}
 

uses ComObj; 

procedure TForm1.Button1Click(Sender: TObject); 
const 
  olFolderContacts = $0000000A
var 
  outlook, NameSpace, Contacts, Contact: OleVariant; 
  i: Integer; 
begin 
  outlook := CreateOleObject('Outlook.Application'); 
  NameSpace := outlook.GetNameSpace('MAPI'); 
  Contacts := NameSpace.GetDefaultFolder(olFolderContacts); 
  for i := 1 to Contacts.Items.Count do 
  begin 
    Contact := Contacts.Items.Item(i); 
    {now you can read any property of contact. For example, full name and 
    email address}
 
    ShowMessage(Contact.FullName + ' <' + Contact.Email1Address + '>'); 
  end
  Outlook := UnAssigned; 
end

{if you need a birthday, you can retrieve it as DateToStr(Contact.Birthday) 
Any contact item have a lot of properties. See a list (alphabet): 
Birthday 
Business2TelephoneNumber 
BusinessAddress 
BusinessAddressCity 
BusinessAddressCountry 
BusinessAddressPostalCode 
BusinessAddressPostOfficeBox 
BusinessAddressState 
BusinessAddressStreet 
BusinessFaxNumber 
BusinessHomePage 
BusinessTelephoneNumber 
CompanyAndFullName 
CompanyMainTelephoneNumber 
CompanyName 
ComputerNetworkName 
Department 
Email1Address 
Email1AddressType 
Email1DisplayName 
Email2Address 
Email2AddressType 
Email2DisplayName 
Email3Address 
Email3AddressType 
Email3DisplayName 
FirstName 
FTPSite 
FullName 
FullNameAndCompany 
GovernmentIDNumber 
Hobby 
Home2TelephoneNumber 
HomeAddress 
HomeAddressCity 
HomeAddressCountry 
HomeAddressPostalCode 
HomeAddressPostOfficeBox 
HomeAddressState 
HomeAddressStree 
HomeFaxNumber 
HomeTelephoneNumber 
Initials 
ISDNNumber 
JobTitle 
Language 
LastName 
LastNameAndFirstName 
MailingAddress 
MailingAddressCity 
MailingAddressCountry 
MailingAddressPostalCode 
MailingAddressPostOfficeBox 
MailingAddressState 
MailingAddressStreet 
MiddleName 
NickName 
OfficeLocation 
OrganizationalIDNumber 
PersonalHomePage 
PrimaryTelephoneNumber 
Profession 
Suffix 
Title 
WebPage}


Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.


Achenbach - Mi 09.04.03 10:53
Titel: Wie kommt man zu diesen Informationen ?
Vielen Dank für das Listing! Woher bekommt man eine Beschreibung der Komponenten ? Gibt es eine Art Hilfedatei ?

Gruß

Christian


Ingo - So 20.04.03 21:30

Hallo Christian

Die Komponenten im Bereich Servers sind nur eiene Kapselung des Objektmodells der jeweiligen Programme. Hilfe zum Objektmodell findest du in der VBA-Hilfe des jweiligen Ms-Office Programms.


Gruß Ingo


mb - Di 22.04.03 18:09

Hallo!

Ich hab ja an anderer Stelle schon mal nach dem Zugriff auf Outlook gefragt. Allerdings möchte ich auf die E-Mails in einem Unterordner
(z.B. Persönlicher Ordner\Posteingang\Project abc\Test alpha) zugreifen. Und zwar sowohl auf die Absender-E-Mail-Adresse als auch *vor allem* auf den Mail-Body (Mailtext)...

Wie bekomme ich das hin? Ich hab da irgendwie Probleme, überhaupt auf den Ordner zuzugreifen. Und ich habe es auch nicht einmal hinbekommen, auf den Text einer E-Mail im Posteingang zuzugreifen...

Hat jemand einen guten Tipp?


Jean-Christoph - Mo 29.03.04 16:21
Titel: Retrieve Outlook Posteingang

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
procedure RetrieveOutlookFolders(tvFolders: TTreeView);
procedure LoadFolder(ParentNode: TTreeNode; Folder: OleVariant);
var
  i,j : Integer;
  node: TTreeNode;
  Namespace,Inbox, MailItem: OleVariant;
  BroWin : TWebbrowser;
  httpcount : integer;
 
begin
  for i := 1 to Folder.Count do
  begin

    if Folder.Item[i].Name = ?DEINPOSTEINGANGSUNTERORDNER?  then
    begin
      for j := 1 to Folder.Item[i].Items.count do
      begin
         begin



             mailitem:= Folder.Item[i].Items[j];


             edit1. Text    := Mailitem.SenderName;
             Memo1.Text  := mailitem.Body oder mailitem.htmlbody
  
             Etc?

  
       
      end;
    end;
    LoadFolder(node, Folder.Item[i].Folders);
  end;
end;

var
  outlook, NameSpace: OLEVariant;
begin
  outlook := CreateOleObject('Outlook.Application');
  NameSpace := outlook.GetNameSpace('MAPI');
  LoadFolder(nil, NameSpace.Folders);
  outlook := UnAssigned;
end;


Der Aufruf der Procedure
RetrieveOutlookFolders(NIL);

Moderiert von user profile iconUGrohne: Delphi-Tags hinzugefügt


seddto - Mo 12.04.04 15:19

Gibt es auch eine Möglichkeit statt den Folder Name einzugeben einen Platzhalter zu benutzen, zum beispiel wenn ich die Sender Adresse aus dem Posteingang auslesen möchte. Der Ordner kann ja verschieden heissen und sogar umbenannt werden glaube ich....gibts da auch eine Möglichkeit?


Jean-Christoph - Mo 12.04.04 15:27
Titel: Folder Name
"DEINPOSTEINGANGSUNTERORDNER" aus dem obigen Beispiel kann auch eine Variable seinm die zur Laufzeit
zugewiesen wird. Einfach ausporbieren!


seddto - Mo 12.04.04 15:38

@Jean

Danke für die Antwort! Ja das ist mir klar ich möchte aber gerne das mein Email Programm Automatisch zum Beispiel Posteingang, Postausgang durchsucht ohne das der Benutzer extra den Ordner Namen eingeben muss. Da diese Ordner aber bei anders-sprachigen Outlook Versionen anders heissen würde ich gerne wissen ob es für Standart-Ordner wie Posteingang oder Postausgang oder gesendete Objekte vielleicht einen Platzhalter gibt...


Jean-Christoph - Mo 12.04.04 16:50

Die Constante Folderinbox hat den Wert 6 und soweit ich weis kann der Hauptordner Posteingang nicht umbenannt werden.

procedure TForm1.Button1Click(Sender: TObject);
var
MyOutlook : _Application;
MyNameSpace : _NameSpace;
MyFolder : MAPIFolder;
MyMail, MyReply : _MailItem;
MailRecipients, ReplyRecipients : Recipients;
emailadr, name : string;
MyContact : _ContactItem;
ARecipient : Recipient; // !! Item !!
i, j : Integer;
seMailAddress : String;
foldername : string;
datump : string;
begin
MyOutlook := CoOutlookApplication.Create;
Try
MyNameSpace := MyOutlook.GetNamespace('MAPI');
MyFolder := MyNameSpace.GetDefaultFolder(olFolderInBox);
For i := 1 to MyFolder.Items.Count do
Begin
foldername := MyFolder.Items.Application.Name;
if foldername = 'Wenn Du einen speziellen Unterordner meinst' then
begin
try
MyMail := (MyFolder.Items.Item(i) As _MailItem);
except
continue;
end;
MyReply := MyMail.Reply;
MailRecipients := MyMail.Recipients;
ReplyRecipients := MyReply.Recipients;

for j := 1 to MailRecipients.Count do
Begin
ARecipient := MailRecipients.Item(j);
seMailAddress := ARecipient.Address;
if myMail.Subject= 'Deine spezielle Betreffangabe' then
begin
list.Append;
list.edit;
list.FieldByNAme('address').AsString := seMailaddress;
list.FieldByNAme('name').AsString := foldername;
list.FieldByNAme('subject').AsString := myMail.Subject;
list.FieldByNAme('message').AsString := myMail.Body;
list.FieldByNAme('categorie').AsString := myMail.Categories;
list.FieldByNAme('datum').AsString := datetimetostr(myMail.ReceivedTime);
list.post;
end;

End;
end;

// List ist bei mir eine Datenbank, in die ich die Werte einschreibe und das können natürlich auch Standardvariablen sein. Jedenfalls stehst du sofort auf dem Haupt Posteimgangsordner. Ich hoffe ich konnte dir helfen.


seddto - Di 13.04.04 11:24

Danke für die Antwort :) Klappt! Funktioniert das denn bei allen Outlook-Versionen, also zb auch bei Outlook Express und bei älteren Outlook Versionen?


seddto - Di 13.04.04 12:35

Ich hab gleich noch eine Frage:

die property SenderName (...wie oben von Jean-Christoph benutzt) liefert nur den angezeigten Name der Mail zurück. In vielen Fällen ist das zwar die Absender Adresse (wenn der Absender keinen Namen eingetragen hat) aber wenn ein Name eingetragen wurde, wird dort nicht die email Adresse sondern der Name angezeigt (zb. "Hubert Schmidt") Weiss jemand wie ich auch an die Email Adresse des Absenders komme?

Danke & LG Seddto


seddto - Di 13.04.04 18:40

Weiss denn wirklich niemand eine Antwort? Wäre für Tips echt dankbar :)


mb - Mi 29.12.04 17:06

Also ich muss gestehen: Bei mir funktioniert das ganze noch gar nicht.

Für die Lösung meines Problems wären mir beide Wege Recht:
1. Über die Server-Komponenten (Office XP-Komponenten) von D7
2. Über OLE/API

Also, noch mal das Problem ganz knapp:
Ich möchte auf alle Mails in einem Ordner von Outlook 2003 zugreifen.

Außer der OutlookApplication-Komponente funktioniert bei mir nix - "nicht registriert", etc. Liegt das daran, dass es XP-Komponenten sind?

Na ja, jedenfalls funktionieren die Code-Schnipsel in diesem Thema auch nicht. Ich bekomme nie die ganzen Ordner. Mit dem Beispiel von Jean-Christoph bekomme ich etwa ein Dutzend mal "Outlook" zurück, nicht aber die Ordner. Wobei es mir auch komisch vorkommt, was da im Sourcecode drin steht. (Sorry)

Hätte jemand ein ganz einfaches Code-Schnipsel für mich, das einfach von allen Mails in einem Ordner (den ich gerne festlegen können möchte) ausliest (die Mail-Bodys, Inhalt) reicht und z.B. hintereinander in eine Text-Datei oder ein Memo-Feld schreibt?

Das wäre echt total super. Denn meine Versuche sind heute alle gegen die Wand gefahren - entweder Registrierungsprobelme von Komponenten/Objekten oder einfach falsche Ergebnisse.

Ich weiß schlicht nicht, wie ich von einem Outlook-Application-Objekt bis zu den Mail-Items komme bzw. wie ich die verschiedenen Server-Komponenten zusammenhängend einsetzen kann.

Hiiiilfeeee.. :cry:


r4id3n - Mi 29.12.04 17:24

Eigentlich sieht das ganz richtig aus ... Allerdings solltest du deine _Application ... mal in IApplication umbenennen .... Aber IMAPI ist der richtige weg! Anders gehts leider nicht1


wulfskin - Mi 29.12.04 18:04

Hallo,

hab auch mal eine Frage zur Importierung der Outlook-Kontakte: Ich habe diesen Quelltext auch mal in einem Projekt benutzt und festgestellt, dass die Kontakt bei der Importierung nicht immer vollständig sind, es fehlen also neu hinzugefügte Kontakte.

Jemand eine Idee an was das liegen könnte?

Gruß Hape!


mb - Do 30.12.04 19:35

Wollte eigentlich noch mal ein Problem schildern, aber als ich dann noch ne Zeile aus dem Code posten wollte, kompilierte und funktionierte es plötzlich ... klingt wie vom DAU, ist aber so... Komisch. :oops:

Na ja, ich greife nun auf den gewünschten Ordner über     MyFolder := MyNameSpace.PickFolder;
zu. Das ist nicht optimal, weil interaktiv, aber funktioniert.

Wie kann ich den Ordner im Code festlegen? Mit der Abfrage if foldername = 'Wenn Du einen speziellen Unterordner meinst' then hat es jedenfalls nicht funktioniert.

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.