Liebe Access-Profis,
nun habe ich doch im alten Jahr noch ein Problem - die Hilfestellung kann aber gerne bis zum nächsten Jahr warten:
Mit folgendem Code generiere ich eine Mail mit vorgefertigtem Text; diese Mail wird in einem Windows-Ordner als .msg-Datei abgespeichert:
(...)
Set myOutlApp = New Outlook.Application
Set myMail = myOutlApp.CreateItem(olMailItem)
With myMail
.To = DLookup("[EIN_Mail]", "tbl_EINRICHTUNGEN", "EIN_PS =" & Forms!frm_SCHUELER03!EIN_FS)
.Subject = "Gutachten zu " & DLookup("[SuS_Name]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
.Body = [i]Vorgefertigter Text[/i]
' .Send
.Display
.SaveAs (strSoSPfad) & "\" & SuS_Name & " " & Format(CStr(DZ + 2), "00") & " Information Stammschule " & ".msg"
End With
(...)
Die Option .send habe ich auskommentiert, damit die Anwender den Text final begutachten können und diesen dann - ggf. verändert - bewusst manuell versenden müssen.
Sollte der Text letztlich geändert werden, ist diese Veränderung nicht in der .msg-Datei abgelegt.
Gibt es eine Möglichkeit - vielleicht mit If .send = true then - diese .msg-Datei erst nach dem Versand im obigen Pfad abzulegen?
Vielen Dank für Hilfen, Tipps und Anregungen
und einen guten Rutsch nach 2016!!
gromax
Hallo,
imo nein.
Aber ich würde einfach das Ansehen/Bearbeiten direkt innerhalb Access machen. Falls dies später stattfinden sollte einfach in eine spezielle Tabelle tblEmal (ID, From, To, Subject, Body, Headers, isSend) die Daten wegspeichern. Dann kann man später die Daten abrufen und einfach absenden.
Gruß Andreas
Hallo Andreas,
vielen Dank für Deine Anregung; diese Option ist mir auch schon in entsprechenden Nachschlagewerken begegnet, ich habe mir dieser Vorgehensweise aber noch nicht so richtig angenähert, zumal ich auch gelesen habe, dass man von Access aus Outlook sehr genau "steuern" könnte.
Vielleicht weiß ja jemand anderer, ob es auf diesem von mir angedeuteten Weg klappt; noch bleibt die Hoffnung!
Trotzdem vielen Dank
und alles Gute!
gromax
p.s.: Vielleicht kannst Du mir ja bei meinem nächsten Problem helfen? Wäre schön!
Hallo,
Zitatzumal ich auch gelesen habe, dass man von Access aus Outlook sehr genau "steuern" könnte.
Das ist schon annähernd richtig, nur gibt es Grenzen...
.Display hat den optionalen Parameter "Modal", der den (Access-) Code solange anhält, bis das Mail-Fenster (Inspector-Object) geschlossen oder die Mail versendet wird. Aber trotzdem ist das Mail-Objekt in diesem Fall nicht mehr gültig, wenn SaveAs zur Ausführung gelangt.
Die einfachste Methode ist tatsächlich, den kompletten EMail-Inhalt mit Access-Mitteln (Tabellen, Formulare) vollständig vorzubereiten (Erstellen, Ändern) und mit .Send direkt ohne weitere User-Interaktion mit Outlook zu versenden.
Als weitere (ungetestete) Methode könnte ich mir vorstellen, aus dem Ordner "gesendete Objekte", die gerade versendete Mail (sofern sie schon aus dem "Postausgang" verschoben wurde) auszulesen und nun erst deren Inhalt weiter zu verarbeiten..
Vielleicht (spekulativ) gibt es noch eine zusätzliche Methode, die darin besteht, das Ereignis "Senden" des Inspector-Objektes auszuwerten. Das erfordert aber sicherlich komplexere API-Aufrufe, wenn dieses Ereignis nicht als "Public" definiert sein sollte.
Hallo Franz,
auch Dir vielen Dank für die prompte Antwort und Deine Anmerkungen.
Die Vorbereitung in Access und der nachmalige Versand mit Outlook ist sicherlich der richtige Weg, den auch Andreas schon vermittelt hat. Ich werde da wohl nicht herumkommen, die DB zu erweitern und damit zu verbessern, wiewohl der bisher eingeschlagene Weg in der Mehrzahl der angewendeten Fälle gute Dienste verrichtet hat. Ich werde mit den Kollegen/innen nochmals hinsichtlich der Umstellung reden.
Inwiefern lohnt es sich, den von Dir zum Schluss aufgerufenen Weg über die Public-Definition weiter zu verfolgen; wäre der Weg denn weniger aufwendig, wenn dieses Ereignis als "Public" definiert wäre? Hier fehlt mir sicherlich die Sensibilität und der Durchblick; ist die "Public-Definition" denn sehr problematisch?
Viele Grüße
gromax
Hallo,
Public oder Private ist von den Outlook-Programmieren (da ein internes Ereignis von Outlook) festgelegt worden und wir haben auf eine Änderung keinen Zugriff. Insofern ist, wie angedeutet, diese Methode spekulativ (soll heißen, ich weiß es einfach nicht, ob das Ereignis "von außen her" abgegriffen werden kann).
Ansonsten ist der Weg, eine vorbereitete Email in Outlook direkt vor dem Senden noch irgendwie ändern zu können, nicht sehr "datensicher".
Ich würd es so machen, wie es in der Überschrift steht.
Nach dem Senden speichern.
Du musst einfach nur ein entsprechendes Event verwenden.
z.B. mailitem.send -> der Code wird dann in Access ausgelöst, sobald das Mail versendet wird und du musst es nur noch abspeichern.
Im Grunde sehr simpel, wenn man mit Events umgehen kann.
LG Markus
Hallo,
ZitatIm Grunde sehr simpel, wenn man mit Events umgehen kann.
Naja, dann zeig halt mal ein konkretes Beispiel...
ZitatNaja, dann zeig halt mal ein konkretes Beispiel...
Wozu, es steht genau da was zu tun ist.
Habs grade getestet. Es funktioniert einwandfrei.
In der Access Anwendung den Event Listener initialisieren, das Event deklarieren und mit Save reagieren.
Wenn diese drei Zeilen für gromax ein Problem darstellen, kann ich gern helfen.
Zuerst darf er aber selbst probieren, wo bleibt da sonst der Spaß am programmieren?
LG Markus
Hallo,
also, ich wäre schon an Deinem Code interessiert... und ich möchte nicht dumm sterben..
Mit 3 Zeilen Code komm ich auch nicht aus.
mailitem.send bringt immer Syntaxfehler "unbekannte Funktion" .
Feststellen, ob die geänderte Mail gesendet werden soll, kann ich auch nicht.. :(
"entsprechendes Event" Welches soll ich da nehmen?
Ich komm nicht weiter .... :'(
Zitatmailitem.send bringt immer Syntaxfehler "unbekannte Funktion"
du hast wohl meinen Kommentar nicht gelesen
ZitatIn der Access Anwendung den Event Listener initialisieren, das Event deklarieren
Send ist ein Event der Klasse MailItem, einfach nachsehen, da gibt es auch noch andere wichtige Events in diesem Zusammenhang.
So ich hoffe, jetzt sind alle Unklarheiten beseitigt.
Falls du es nicht schaffst so poste bitte den Code. Bin morgen Abend wieder am Rechner.
LG Markus
Hallo,
doch, doch, den Kommentar hab ich schon gelesen..
Zitat
In der Access Anwendung den Event Listener initialisieren, das Event deklarieren
das bekomm ich irgendwie nicht gebacken...
ZitatSend ist ein Event der Klasse MailItem, einfach nachsehen,
Wo soll ich denn nachsehen? und eine Klasse MailItem find ich auch nicht ... <verzweifel>
https://msdn.microsoft.com/en-us/library/office/ff865379.aspx (https://msdn.microsoft.com/en-us/library/office/ff865379.aspx)
Outlook Hilfe, www usw.
Aber damit du dich nicht anstrengen musst, anbei link mit Beispiel.
LG MARKUS
Hallo,
naja, anstrengen muss ich mich nur dabei, nicht zu viel zu grinsen.... ;D ;D
Hast Du wirklich geglaubt, ich verzweifel daran, auf ein Outlook-Event in Access zu reagieren?
ZitatIm Grunde sehr simpel, wenn man mit Events umgehen kann
hat mich ein bisschen "berührt" und wollte nur wissen, ob Du selber damit umgehen kannst. ;)
Nichtsdestotrotz löst das Send-Event nicht das Ausgangs-Problem, eine Mail erst nach evtl. manuellen Änderungen beim Versenden und
mit den Änderungen zu speichern.
Das ItemSend-Event dagegen schon.
Annähernd angepasst an den Code von gromax:
Option Compare Database
Option Explicit
Public WithEvents myOutlApp As Outlook.Application
Dim myMail, strSoSPfad As String, SuS_Name As String, DZ As Long
Private Sub btnSendMail_Click()
.
.
.
.
.
.
Set myOutlApp = New Outlook.Application
Set myMail = myOutlApp.CreateItem(olMailItem)
SuS_Name = DLookup("[SuS_Name]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
With myMail
.To = DLookup("[EIN_Mail]", "tbl_EINRICHTUNGEN", "EIN_PS =" & Forms!frm_SCHUELER03!EIN_FS)
.Subject = "Gutachten zu " & SuS_Name
.Body = "Vorgefertigter Text"
.Display
End With
End Sub
Private Sub myOutlApp_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim strMsgFile As String
If MsgBox("Soll die Mail gespeichert werden? " & Item.Subject & vbCrLf & vbCrLf & Item.Body & "?", vbYesNo + vbQuestion, "Access") = vbYes Then
strMsgFile = strSoSPfad & "\" & SuS_Name & " " & Format(CStr(DZ + 2), "00") & " Information Stammschule " & ".msg"
myMail.SaveAs strMsgFile
CurrentDb.Execute " Insert into tblSentMails (MS_MsgFile,MS_SendDate) Values ('" & strMsgFile & "',Now())"
End If
End Sub
Hallo Franz, hallo Markus,
vielen Dank für Eure Unterstützung; ich bin zur Zeit an einer "Erweiterung" für meine DB. Sollte ich dabei fertig sein, greife ich diese hier diskutierte Hilfestellung nochmals auf.
Ich melde mich dann auf alle Fälle zurück!!
Vielen Dank!
gromax
Zitat von: DF6GL am Januar 23, 2016, 19:57:13
naja, anstrengen muss ich mich nur dabei, nicht zu viel zu grinsen.... ;D ;D
Dann freue ich mich, dass du Deinen Spass hattest.
Zitat von: DF6GL am Januar 23, 2016, 19:57:13
Nichtsdestotrotz löst das Send-Event nicht das Ausgangs-Problem, eine Mail erst nach evtl. manuellen Änderungen beim Versenden und mit den Änderungen zu speichern.
Das ItemSend-Event dagegen schon.
Was du bei der Aussage gedacht hast, frage ich mich aber schon, zumal ich schon mitgeteilt habe, dass ich es getestet habe.
Ein Event startet einen Code und sonst gar nichts.
Zufällig handelt es sich um um und dasselbe Event von zwei verschiedenen Objekten ausgelöst.
Einmal von der Mail selbst und einmal von Outlook und daher hat man in beiden fällen den Zugriff auf das veränderte Mail um es zu speichern.
Die Erkenntnis, dass auch andere wissen wovon sie reden könnte helfen, sich nicht lächerlich zu machen.
LG
Hallo Franz,
nach geraumer Zeit und entsprechenden "Umbau-Maßnahmen" an meiner DB greife ich Deine Lösung zum Speichern der Mails nach dem Senden mit der Bitte um erneute Hilfestellung nochmals auf.
Ich habe Deinen Code eingefügt, angepasst und ausprobiert - aber es klappt nicht?!
Vorab zur Konfiguration des Mail-Aufrufs:
Im Formular frm_SCHUELER03 sind die Grund-Daten zum jeweiligen Schüler hinterlegt; im Unterformular frm_SCHUELER-ufoBearbeitung03 werden nun Daten eingegeben, die sich zusammen mit den Grunddaten in den Mails wiederfinden.
Jetzt wird bei Bedarf ein Formular geöffnet, das den Aufruf zweier Mails anstößt, eine an die Stammschule und eine an die beauftragte Schule (vgl. Anlage).
Private Sub opt_picFrist_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MailAufruf (1)
DoCmd.Close acForm, "frm_MailAuftrag_Auswahl"
End Sub
Private Sub opt_picNachfrist_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MailAufruf (2)
DoCmd.Close acForm, "frm_MailAuftrag_Auswahl"
End Sub
Private Sub opt_picWordInfo_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MailAufruf (3)
DoCmd.Close acForm, "frm_MailAuftrag_Auswahl"
End Sub
Sub MailAufruf(intEingabe As Integer)
If intEingabe = 1 Then
' Call Forms("frm_SCHUELER03").frm_Schueler_ufoBearbeitung03.Form.btn_OutlookBeauftragung_Click
Call btn_OutlookBeauftragung
End If
If intEingabe = 2 Then
' Call Forms("frm_SCHUELER03").frm_Schueler_ufoBearbeitung03.Form.cmd_nachFristOutlook_Click
Call cmd_nachFristOutlook
End If
If intEingabe = 3 Then
' Call Forms("frm_SCHUELER03").frm_Schueler_ufoBearbeitung03.Form.btn_WordInfo_Click
Call btn_WordInfo
End If
End Sub
Der Aufruf btn_OutlookBeauftragung ist in einem Modul mit 'Public Sub btn_OutlookBeauftragung()' abgelegt.
Jetzt weiß ich nicht, wo ich Deine Code-Beispiele einarbeiten muss; könntest Du mir da ein wenig in die Spur helfen?
Vielen Dank vorab!
Viele Grüße
gromax
p.s.: Alles Beispiel-Daten! Kein Grund zur Besorgnis!
Hallo,
am Besten zeigst Du den Code, mit dem die Mail generiert und angezeigt wird... (.Send, .Display)...
Hallo Franz,
mache ich natürlich gerne!
Public Sub btn_OutlookBeauftragung()
Dim strDatei As String
Dim myMail As Outlook.MailItem
Dim myOutlApp As Outlook.Application
Dim strText1 As String
Dim strText3 As String
Dim strSoSPfad As String
Dim db As DAO.Database
Dim RS As DAO.Recordset
Dim lngConnect As Long
Dim DZ As Long
Dim lng As Integer
Dim SuS_Name As String
Dim SuS_GebDat As String
Dim BEA_AntragSchule As Date
Dim BEA_AntragEltern As Date
SuS_Name = DLookup("[SuS_Name]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
SuS_GebDat = DLookup("[SuS_GebDat]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
BEA_AntragSchule = DLookup("[BEA_AntragSchule]", "tbl_BEARBEITUNG_SCH_VER", "BEA_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_PS)
BEA_AntragEltern = DLookup("[BEA_AntragEltern]", "tbl_BEARBEITUNG_SCH_VER", "BEA_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_PS)
Set db = CurrentDb
Set RS = db.OpenRecordset("SELECT DISTINCT database" _
& " FROM msysObjects" _
& " WHERE Type = 6", dbOpenDynaset)
lngConnect = RS.RecordCount
If lngConnect > 0 Then
strSoSPfad = CurrentDb.TableDefs("tbl_SCHUELER").Connect
strSoSPfad = Mid(strSoSPfad, 11)
strSoSPfad = Left(strSoSPfad, InStrRev(strSoSPfad, "\")) & "Bestand\"
Else
strSoSPfad = CurrentProject.Path & "\Bestand\"
End If
strSoSPfad = strSoSPfad & SuS_Name & " _ " & SuS_GebDat
strText3 = "Allgemeine Schule:"
If Not IsNull(Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_AntragSchule) And IsNull(Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_AntragEltern) Then
strText1 = "der Antrag der Allgemeinen Schule"
ElseIf Not IsNull(Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_AntragEltern) And IsNull(Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_AntragSchule) Then
strText1 = "der Elternantrag"
Else
strText1 = "der Antrag"
End If
''''''''''''''''''''''''''''''''''''''''''''''''''''Mail an die beauftragte Schule
Set myOutlApp = New Outlook.Application
Set myMail = myOutlApp.CreateItem(olMailItem)
If Dir(strSoSPfad, vbDirectory) = "" Then
Call MsgBox("Es besteht kein Ordner für diesen Schüler!" _
& vbCrLf & "Bitte richten Sie zuerst einen Ordner ein, so dass" _
& vbCrLf & "diese Mail dann auch gespeichert werden kann!", vbOKOnly + vbInformation, "Mail-Versand wird unterbrochen")
Exit Sub
End If
strDatei = Dir$(strSoSPfad & "\*.*")
Do While Len(strDatei) > 0
lng = lng + 1
strDatei = Dir$()
Loop
DZ = lng
With myMail
.To = DLookup("[EIN_Mail]", "qry_EINRICHTUNGEN_sortiert2", "SCH_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!BEA_AuftragSchule)
.Subject = "Gutachten zu " & DLookup("[SuS_Name]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
.Body = Textkörper
.Display
.SaveAs (strSoSPfad) & "\" & SuS_Name & " " & Format(CStr(DZ + 1), "00") & " Beauftragung SBBZ " & ".msg"
End With
Set myMail = Nothing
Set myOutlApp = Nothing
''''''''''''''''''''''''''''''''''''''''''''''''''''Mail an die Stammschule
Set myOutlApp = New Outlook.Application
Set myMail = myOutlApp.CreateItem(olMailItem)
With myMail
.To = DLookup("[EIN_Mail]", "tbl_EINRICHTUNGEN", "EIN_PS =" & Forms!frm_SCHUELER03!EIN_FS)
.Subject = "Gutachten zu " & DLookup("[SuS_Name]", "tbl_SCHUELER", "SuS_PS =" & Forms!frm_SCHUELER03!frm_Schueler_ufoBearbeitung03.Form!SuS_FS)
.Body = Textkörper
.Display
.SaveAs (strSoSPfad) & "\" & SuS_Name & " " & Format(CStr(DZ + 2), "00") & " Information Stammschule " & ".msg"
End With
Set myMail = Nothing
Set myOutlApp = Nothing
End Sub
Viele Grüße
gromax
Hallo,
na gut, habe ich hier doch beschrieben:
http://www.access-o-mania.de/forum/index.php?topic=20948.msg118731#msg118731
Hallo Franz,
vielen Dank; ich habe nicht genau hingeschaut - sorry! Werde am Wochenende diese Umsetzung in Angriff nehmen.
Ich melde mich dann wieder!
Viele Grüße
gromax