ahstax
Goto Top

Neue E-Mails in öffentlichem Ordner

Hallo,

ich versuche, einen Code zu schreiben, der erkennt, dass eine neue (neu eingegangene bzw. seit letztem Programmstart neu hinzugekommene) E-Mail in einem öffentlichen Ordner vorhanden sind.
Später sollen diese dann auch bearbeitet werden (gedruckt, organisiert).

(Outlook 2010, Exchange, Win7, VB 2010 Express)


Für eine normale Inbox scheine ich das (Copy & Paste) hinbekommen zu haben, Panel1 wird grün wenn eine E-Mail eingeht:

Public Class Form1

    Private WithEvents olInboxItems As Microsoft.Office.Interop.Outlook.Items
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Application_Startup()
    End Sub

    Private Sub Application_Startup()

        Dim objApp As Microsoft.Office.Interop.Outlook.Application = New Microsoft.Office.Interop.Outlook.Application()
        Dim objNS As Microsoft.Office.Interop.Outlook.NameSpace = objApp.GetNamespace("mapi")  
        olInboxItems = objNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox).Items
        objNS = Nothing

    End Sub
    Private Sub olInboxItems_ItemAdd1(ByVal Item As Object) Handles olInboxItems.ItemAdd
        Panel1.BackColor = Color.Green
    End Sub

    Private Sub cmdBtnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnReset.Click
        Panel1.BackColor = Color.Empty
    End Sub

    Private Sub cmdBtnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnClose.Click
        Me.Close()
    End Sub
End Class


Bei einem nem Öffentlichen Ordner klappt es (bis jetzt) nicht:

Public Class Form1

    Private WithEvents olInboxItems As Microsoft.Office.Interop.Outlook.Items
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Application_Startup()
    End Sub
    Private Sub Application_Startup()

        Dim objApp As Microsoft.Office.Interop.Outlook.Application
        Dim objNS As Microsoft.Office.Interop.Outlook.NameSpace
        Dim objPF As MAPIFolder
        Dim objAPF As MAPIFolder
        Dim objMKF As MAPIFolder

        objApp = New Microsoft.Office.Interop.Outlook.Application()
        objNS = objApp.GetNamespace("MAPI")  
        objPF = objNS.Folders("Öffentliche Ordner - " & objNS.AddressEntry.GetExchangeUser.PrimarySmtpAddress)  
        objAPF = objPF.Folders("Alle Öffentlichen Ordner")  
        objMKF = objAPF.Folders("Ordner_01")  

        olInboxItems = objNS.GetPublicFolder(objMKF).Items

    End Sub
    Private Sub olInboxItems_ItemAdd1(ByVal Item As Object) Handles olInboxItems.ItemAdd
        Panel1.BackColor = Color.Green
    End Sub

    Private Sub cmdBtnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnReset.Click
        Panel1.BackColor = Color.Empty
    End Sub

    Private Sub cmdBtnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnClose.Click
        Me.Close()
    End Sub
End Class


Woran könnte es liegen? Setze ich insgesamt vielleicht falsch an? Wäre ggf NewMail oder NewMailEx ein kleverer Ansatz?

Neugierige Grüße,
Andreas

Content-Key: 212883

Url: https://administrator.de/contentid/212883

Printed on: April 18, 2024 at 05:04 o'clock

Member: colinardo
colinardo Aug 02, 2013, updated at Aug 04, 2013 at 08:42:42 (UTC)
Goto Top
Hallo Andreas,
dein zweites Script kann in dieser Weise nicht funktionieren, da es das Event ItemAdd abfängt welches nur ausgelöst wird wenn du selber im Ordner ein Objekt erstellst.
Wie wäre es, wenn die Mails, die im öffentlichen Ordner auflaufen, automatisch an eine bestimmte Mailbox weitergeleitet werden die du dann mit dem "NewMailEx"-Ereignis abfängst und verarbeitest.

--edit--
alternativ wäre die Entwicklung eines Exchange-Transport-Agents der auf dem Exchange-Server läuft auch eine Lösung.

Grüße Uwe
Member: ahstax
ahstax Aug 02, 2013 at 10:24:01 (UTC)
Goto Top
Hallo colinardo,

herzlichen Dank für Deine Antwort.

Ich habe es nach einiger Rumspielerei hinbekommen, dass mir neue E-Mails im öffentlichen Ordner angezeigt werden. Heißt dass, dass ich auf irgend eine mysteriöse Weise alle neuen Mails im öffentlichen Ordner erzeuge?

Imports System
Imports System.Collections.Generic
Imports Microsoft.Office.Interop.Outlook

Public Class Form1
    Public objApp As Microsoft.Office.Interop.Outlook.Application
    Public objNS As Microsoft.Office.Interop.Outlook.NameSpace
    Public objPF As MAPIFolder
    Public objAPF As MAPIFolder
    Public objMKF As MAPIFolder
    Public strPublicFolderPath As String
    Public strPrimarySmtpAddress As String


    Private WithEvents olInboxItems As Microsoft.Office.Interop.Outlook.Items
    

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblMailID.Text = ""  
        Application_Startup()
    End Sub


    Private Sub Application_Startup()

        Try
            objApp = New Microsoft.Office.Interop.Outlook.Application()
            objNS = objApp.GetNamespace("MAPI")  

            'MsgBox(objNS.CurrentUser.AddressEntry.GetExchangeUser().PrimarySmtpAddress)  

            objPF = objNS.Folders("Öffentliche Ordner - " & objNS.CurrentUser.AddressEntry.GetExchangeUser.PrimarySmtpAddress)  
            objAPF = objPF.Folders.Item("Alle Öffentlichen Ordner")  
            objMKF = objAPF.Folders.Item("Ordner 01")  

            'MsgBox(strPublicFolderPath)  

            olInboxItems = objMKF.Items

        Catch ex As System.Exception
            MsgBox(ex.Message)
        End Try
        
    End Sub


    Private Sub olInboxItems_ItemAdd1(ByVal Item As Object) Handles olInboxItems.ItemAdd
        Panel1.BackColor = Color.Green

        'hier irgendwas mit der lblMailID  

    End Sub


    Private Sub cmdBtnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnReset.Click
        Panel1.BackColor = Color.Empty
    End Sub

    Private Sub cmdBtnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBtnClose.Click
        Me.Close()
    End Sub

End Class

Ich würde nun gerne in lblMailID.Text (Zeile 50) die MailID der Mail ausgeben, die das ItemAdd-Event ausgelöst hat. (Das ist nur ein Zwischenschritt, ich möchte später mal die Mail speichern und dann weiterver- und -bearbeiten. Das geht vermutlich nur mit NewMailEx? Damit hatte ich bis jetzt noch keinen Erfolg... Wo kann ich denn vernünftige Infos dazu finden, die ich selbst vielleicht noch nicht gefunden haben?

Neugierige Grüße,
Andreas
Member: colinardo
colinardo Aug 02, 2013 at 10:39:15 (UTC)
Goto Top
Heißt dass, dass ich auf irgend eine mysteriöse Weise alle neuen Mails im öffentlichen Ordner erzeuge?
Sorry war mein Fehler, hatte diesbezüglich was anderes im Hinterkopf...
Ich würde nun gerne in lblMailID.Text (Zeile 50) die MailID der Mail ausgeben
Ich denke du meinst mit MailID die EntryID der Mail. Auf das Objekt was hinzugefügt wurde kannst du mit Item zugreifen. Dieses Object wird dem Event ja als Parameter übergeben (Private Sub olInboxItems_ItemAdd1(ByVal Item As Object))
Die EntryID fragst du also so ab:
Item.EntryID
Du solltest aber später noch überprüfen ob das Objekt tatsächlich ein MailItem-Objekt war das übergeben wurde, dies kann mit der Eigenschaft .Class des Objektes tun.

Welche Eigenschaften und Methoden für Outlook-Objekte existieren kannst du entweder Online im MSDN oder in der VBA-Hilfe des VBA-Editors in Outlook nachlesen.

Grüße Uwe
Member: ahstax
ahstax Aug 02, 2013 at 10:44:56 (UTC)
Goto Top
Ja, natürlich... EntryID... Entschuldigung.

Ich probier es gleich aus und werde wieder berichten...! face-wink
Member: ahstax
ahstax Aug 02, 2013 at 11:11:04 (UTC)
Goto Top
hmm....

einfach mit

Private Sub olInboxItems_ItemAdd(ByVal Item As Object) Handles olInboxItems.ItemAdd

        Panel1.BackColor = Color.Green

        Try
            Dim strEntryID As String = Item.EntryID
            lblEntryID.Text = strEntryID
            MsgBox(Item.sendername)
        Catch ex As System.Exception
            MsgBox(ex.Message)
        End Try

    End Sub

funktioniert es leider nicht.
Fehlermeldung:
"ungültiger threadübergreifender Vorgang: Zugriff auf das Steuerelement lblEntryID erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."

Allerdings, wenn ich dir EntryID in einer MsgBox ausgebe, gehts. Tut vermutlich nichts zur (eigentlichen) Sache, ist aber (für mich) verwunderlich...
Member: colinardo
colinardo Aug 02, 2013 at 12:43:52 (UTC)
Goto Top
Das ist klar, du versuchst aus dem Outlook-Prozess (das ItemAdd-Event gehört auch zu Outlook) ein Steuerelement in einem anderen Prozess (deine Anwendung) zu verändern - das scheitert natürlich weil dies ein illegaler Cross-Thread-Call ist. Dies lässt sich mit Delegates lösen oder du erlaubst in deiner Anwendung Cross-Thread-Calls was aber nicht zum guten Programmier-Stil gehört:
Im Initializer deiner Form dazu folgendes eintragen
Control.CheckForIllegalCrossThreadCalls = false
Member: ahstax
ahstax Aug 02, 2013 at 16:02:23 (UTC)
Goto Top
Wenn das Pfui ist, mach ich es nicht...! face-wink
Kann man den Wert irgendwie sauber übergeben?

Abgesehen davon:
Bis hierher läufts.

Die neue Mail wird auch schon in nen Ordner gespeichert.
Von dem aus will ich die dann ausdrucken lassen. Mail und Anhänge separat. Und wenn es Anhänge sind, deren Format unbekannt ist, soll ein Ersatzblatt erzeugt werden.
Darf ich mich ggf. wieder melden?

Herzlichen Dank einstweilen!!!!
Member: colinardo
colinardo Aug 03, 2013, updated at Aug 04, 2013 at 08:37:31 (UTC)
Goto Top
OK das mit den Delegates ist für Anfänger nicht einfach zu verstehen aber hier für dich ein Beispiel für dein Vorhaben:
zuerst deklarierst du den Delegaten(Stellvertreter/Bevollmächtigter) und eine zusätzliche Variable die nachher das neue MailItem enthält in deiner Form-Klasse.
Public Delegate Sub setLabelInfoDelegate()
Public newIncomingMail As Object = Nothing
dann schreibst du im Item_Add-Ereigniss folgendes hinein:
newIncomingMail = Item
Dim myDelegate As setLabelInfoDelegate
myDelegate = AddressOf setLabelInfo
Invoke(myDelegate)
zusätzlich erstellst du noch folgende Sub in deiner Klasse:
Private Sub setLabelInfo()
      Try
          If Not newIncomingMail Is Nothing Then
             lblMailID.Text = newIncomingMail.EntryID
          End If
         Catch ex As SystemException
            MsgBox(ex.Message)
       End Try
End Sub
In dieser Prozedur wird die eigentliche Arbeit in deiner Form gemacht (sie ist quasi die Worker-Prozedur des Delegaten). In dieser kannst du auch noch andere Dinge erledigen die Änderungen an deiner Form setzen müssen.

Klar wenn Probleme auftauchen, einfach melden .. dann wird dir geholfen face-smile

Grüße Uwe
Gelöste Beitrage bitte auch als solche markieren.Danke.