populate an email with information from an access form, how to have the referrenced tables selected option show on email, not primary key number - vba

I've created a button within a form that will populate an email with certain fileds. some of these fields are drop down boxes which get their information from another table. In this example I have an field for the title (Mr, Mrs, etc), the form shows Mr but when this is written to an email the primary key is there in place of the actual title. "1" instead of "Mr.".
I've tried using what seems logical to get the info from the "TitleTBL"(name of table) but I don't seem to be getting it right. please see the VBA code below and let me know how to reference the actual Title and not the primary key of that option.
Thank You
Private Sub TransferDanR_Click()
Dim ID As Variant
Dim Title As Variant
Dim First As Variant
Dim Last As Variant
Dim Addr1 As Variant
Dim Addr2 As Variant
Dim Postcode As Variant
Dim HomePhone As Variant
Dim MobilePhone As Variant
Dim Insurer As Variant
Dim RenewalDate As Variant
Dim PolicyNotes As Variant
Dim ContactNotes As Variant
Dim LGAgent As Variant
Dim objOutlook As Object
Dim objEmail As Object
ID = Forms("DataToDialFRM").ID
Title = Forms("DataToDialFRM").Title
First = Forms("DataToDialFRM").First
Last = Forms("DataToDialFRM").Last
Addr1 = Forms("DataToDialFRM").Addr1
Addr2 = Forms("DataToDialFRM").Addr2
Postcode = Forms("DataToDialFRM").Postcode
HomePhone = Forms("DataToDialFRM").HomePhone
MobilePhone = Forms("DataToDialFRM").MobilePhone
Insurer = Forms("DataToDialFRM").Insurer
RenewalDate = Forms("DataToDialFRM").RenewalDate
PolicyNotes = Forms("DataToDialFRM").PolicyNotes
ContactNotes = Forms("DataToDialFRM").ContactNotes
LGAgent = Forms("DataToDialFRM").LGAgent
Set objOutlook = CreateObject("Outlook.Application")
Set objEmail = objOutlook.CreateItem(0)
With objEmail
.To = "emailaddress; emailaddress; emailaddress"
.Subject = ID & " " & Last & " from " & LGAgent & " (Automated Transfer Email)"
.HTMLBody = "<p>" & "Name: " & Title & ", " & First & ", " & Last & "<p>" & "Address: " & Addr1 & ", " & Addr2 & ", " & Postcode & "<p>" & "HomePhone: " & HomePhone & "<p>" & "MobilePhone: " & MobilePhone & "<p>" & "Insurer " & Insurer & "<p>" & "Renewal Date: " & RenewalDate & "<p>" & "Policy Notes: " & "<p>" & PolicyNotes & "<p>" & "Contact Notes: " & "<p>" & ContactNotes
.Display
End With
Set objEmail = Nothing
Set objOutlook = Nothing
End Sub

To retrieve the display value of a combobox you use the .Column property.
E.g. if your Title combobox has 2 columns with TitleID ("1") and Title ("Mr."), you need .Column(1) because the column index is zero-bound.
You can make your code better readable by using a With statement:
With Forms("DataToDialFRM")
ID = !ID
Title = !Title.Column(1)
First = !First
' ...
End With
Use bang ! to refer to form controls, not form recordsource values.

Related

Microsoft Access VBA code to send email to recipients with attachment based on results of query filtered on check date

I've commented out the section to add the attachment because I know it works, but the files currently aren't present to be attached. I'm new to VBA and am missing something. My data is simply employee number, check date (send_checkdt), check number, name, etc. The query has no parameters, which is why I'm doing the select based on the form date defined in strSQL.
When I run it I immediately get an over and it exits. Previously I was only able to send the email to the first person in the query and the record didn't advance. The email part is working correctly, I'm just not processing the data correctly.as
What am I missing?
Private Sub Command1_Click()
Dim Msg As String
Dim F_attach As String
Dim O As Outlook.Application
Dim M As Outlook.MailItem
Dim DT As String
DT = Forms!Form1!frmCheckDt
Dim strSQL As String
strSQL = "SELECT * FROM qryMailList Where send_checkdt=" & DT
Dim dbs As DAO.Database
Dim Mlist As DAO.Recordset
'Dim Mfiltered As DAO.Recordset
Set dbs = CurrentDb
Set Mlist = dbs.OpenRecordset(strSQL, dbOpenDynaset)
Set O = New Outlook.Application
Set M = O.CreateItem(olMailItem)
Mlist.MoveFirst
Do Until Mlist.EOF
Msg = "Dear " & Mail_FullName & "," & vbCrLf & vbCrLf & _
"Your payroll check number " & Send_CheckNo & " was deposited on " & _
send_checkdt & " for " & Format(Send_NetPay, "Currency") & "." & vbCrLf & vbCrLf & _
"Sincerely," & vbCrLf & Send_CoName
F_attach = "f:\archives\CK" & Mail_emp & "_" & Send_CheckNo & ".pdf"
With M
.BodyFormat = olFormatPlain
.Body = Msg
.To = Mail_Email
.Subject = "Direct Deposit " & send_checkdt
' .Attachments.Add F_attach
.Display
End With
Mlist.MoveNext
Loop
DoCmd.Close
Set M = Nothing
Set O = Nothing
Set Mlist = Nothing
Set dbs = Nothing
Set qdf = Nothing
Set Mfiltered = Nothing
End Sub
I moved
set O=New Outlook.Application and
set M=O.CreateItem(olMailItem)
to be below
Do Until Mlist.EOF and it works correctly.
I also had to further identify my data fields by adding Mlist! to each. Without identifying Mlist it prodcued the correct number of emails but no data was filled in. Thank you to everyone that offered comments.

Search FlagRequest for single or multiple text combinations

In my inbox there are emails where the sender communicates either single or multiple seminars or event codes.
For example, AI-G167 and/or HR-T245. I flag those emails with category and flag request and this helps me add functionality in my code.
My filter only works when FlagRequest has a single event code and fails when I mark FlagRequest with a delimited value, e.g "AI-G167, HR-T245".
Category_Filter = "[Categories] = 'Seminars' And [FlagRequest] = " & EventCode
Is there any way, my filter could work in this scenario? It means that email would serve my purpose even if there are two different events to be held on a single day at different times.
If Restrict does not support like for .FlagRequest there is InStr.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub FlagRequest_multiple_values()
Dim oItems As Items
Dim oItemsRes As Items
Dim Category_Filter As String
Dim Category_Flag_Filter As String
Dim EventCode As String
Dim i As Long
Dim resItemsCount As Long
Dim matchCount As Long
Set oItems = Session.GetDefaultFolder(olFolderInbox).Folders("FlagRequestTest").Items
EventCode = "AI-G167"
'EventCode = "HR-T245"
Debug.Print
Debug.Print "EventCode......: " & EventCode
' with single quotes added to variable
Category_Flag_Filter = _
"[Categories] = 'Seminars' And [FlagRequest] = " & "'" & EventCode & "'"
Debug.Print
Debug.Print "Category_Flag_Filter......: " & Category_Flag_Filter
Set oItemsRes = oItems.Restrict(Category_Flag_Filter)
Debug.Print "Category_Flag_Filter count: " & oItemsRes.Count
Category_Filter = "[Categories] = 'Seminars'"
Debug.Print
Debug.Print "Category_Filter......: " & Category_Filter
Set oItemsRes = oItems.Restrict(Category_Filter)
Debug.Print "Category_Filter count: " & oItemsRes.Count
If oItemsRes.Count > 0 Then
resItemsCount = oItemsRes.Count
For i = 1 To resItemsCount
With oItemsRes(i)
Debug.Print i & " Subject......: " & .Subject
Debug.Print " FlagRequest: " & .FlagRequest
If InStr(.FlagRequest, EventCode) > 0 Then
matchCount = matchCount + 1
Else
Debug.Print " *** No match ***"
End If
End With
Next
End If
Debug.Print matchCount & " matches of " & resItemsCount
End Sub

Search by Email address with urn:schemas

I found this code from Ricardo Diaz. It runs through.
I would like to search for the latest email I received or sent to a specific email address as opposed to search by subject.
I replaced
searchString = "urn:schemas:httpmail:subject like '" & emailSubject & "'"
with
searchString = "urn:schemas:httpmail:to like '" & emailSubject & "'"
The search returns an empty object.
What is the urn:schemas to search for the email address of the sender and receiver in my Outlook Inbox and Sent Items?
This is the code I am trying to run:
In a VBA module:
Public Sub ProcessEmails()
Dim testOutlook As Object
Dim oOutlook As clsOutlook
Dim searchRange As Range
Dim subjectCell As Range
Dim searchFolderName As String
' Start outlook if it isn't opened (credits: https://stackoverflow.com/questions/33328314/how-to-open-outlook-with-vba)
On Error Resume Next
Set testOutlook = GetObject(, "Outlook.Application")
On Error GoTo 0
If testOutlook Is Nothing Then
Shell ("OUTLOOK")
End If
' Initialize Outlook class
Set oOutlook = New clsOutlook
' Get the outlook inbox and sent items folders path (check the scope specification here: https://learn.microsoft.com/en-us/office/vba/api/outlook.application.advancedsearch)
searchFolderName = "'" & Outlook.Session.GetDefaultFolder(olFolderInbox).FolderPath & "','" & Outlook.Session.GetDefaultFolder(olFolderSentMail).FolderPath & "'"
' Loop through excel cells with subjects
Set searchRange = ThisWorkbook.Worksheets("Sheet1").Range("A2:A4")
For Each subjectCell In searchRange
' Only to cells with actual subjects
If subjectCell.Value <> vbNullString Then
Call oOutlook.SearchAndReply(subjectCell.Value, searchFolderName, False)
End If
Next subjectCell
MsgBox "Search and reply completed"
' Clean object
Set testOutlook = Nothing
End Sub
In a class module named clsOutlook:
Option Explicit
' Credits: Based on this answer: https://stackoverflow.com/questions/31909315/advanced-search-complete-event-not-firing-in-vba
' Event handler for outlook
Dim WithEvents OutlookApp As Outlook.Application
Dim outlookSearch As Outlook.Search
Dim outlookResults As Outlook.Results
Dim searchComplete As Boolean
' Handler for Advanced search complete
Private Sub outlookApp_AdvancedSearchComplete(ByVal SearchObject As Search)
'MsgBox "The AdvancedSearchComplete Event fired."
searchComplete = True
End Sub
Sub SearchAndReply(emailSubject As String, searchFolderName As String, searchSubFolders As Boolean)
' Declare objects variables
Dim customMailItem As Outlook.MailItem
Dim searchString As String
Dim resultItem As Integer
' Variable defined at the class level
Set OutlookApp = New Outlook.Application
' Variable defined at the class level (modified by outlookApp_AdvancedSearchComplete when search is completed)
searchComplete = False
' You can look up on the internet for urn:schemas strings to make custom searches
searchString = "urn:schemas:httpmail:to like '" & emailSubject & "'"
' Perform advanced search
Set outlookSearch = OutlookApp.AdvancedSearch(searchFolderName, searchString, searchSubFolders, "SearchTag")
' Wait until search is complete based on outlookApp_AdvancedSearchComplete event
While searchComplete = False
DoEvents
Wend
' Get the results
Set outlookResults = outlookSearch.Results
If outlookResults.Count = 0 Then Exit Sub
' Sort descending so you get the latest
outlookResults.Sort "[SentOn]", True
' Reply only to the latest one
resultItem = 1
' Some properties you can check from the email item for debugging purposes
On Error Resume Next
Debug.Print outlookResults.Item(resultItem).SentOn, outlookResults.Item(resultItem).ReceivedTime, outlookResults.Item(resultItem).SenderName, outlookResults.Item(resultItem).Subject
On Error GoTo 0
Set customMailItem = outlookResults.Item(resultItem).ReplyAll
' At least one reply setting is required in order to replyall to fire
customMailItem.Body = "Just a reply text " & customMailItem.Body
customMailItem.Display
End Sub
The cells A2:A4 in Sheet1 contain email address such as rainer#gmail.com for instance.
You can get to what appears to be "urn:schemas:httpmail:to" another way.
Read MAPI properties not exposed in Outlook's Object Model
The usefulness is still to be proven as the values from the the address-related properties are either not available or trivial.
Option Explicit
' https://www.slipstick.com/developer/read-mapi-properties-exposed-outlooks-object-model/
Const PR_RECEIVED_BY_NAME As String = "http://schemas.microsoft.com/mapi/proptag/0x0040001E"
Const PR_SENT_REPRESENTING_NAME As String = "http://schemas.microsoft.com/mapi/proptag/0x0042001E"
Const PR_RECEIVED_BY_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0076001E"
Const PR_SENT_REPRESENTING_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0065001E"
Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001E"
Sub ShowPropertyAccessorValue()
Dim oItem As Object
Dim propertyAccessor As outlook.propertyAccessor
' for testing
' select an item from any folder not the Sent folder
' then an item from the Sent folder
Set oItem = ActiveExplorer.Selection.item(1)
If oItem.Class = olMail Then
Set propertyAccessor = oItem.propertyAccessor
Debug.Print
Debug.Print "oItem.Parent......................: " & oItem.Parent
Debug.Print "Sender Display name...............: " & oItem.Sender
Debug.Print "Sender address....................: " & oItem.SenderEmailAddress
Debug.Print "PR_RECEIVED_BY_NAME...............: " & _
propertyAccessor.GetProperty(PR_RECEIVED_BY_NAME)
Debug.Print "PR_SENT_REPRESENTING_NAME.........: " & _
propertyAccessor.GetProperty(PR_SENT_REPRESENTING_NAME)
Debug.Print "PR_RECEIVED_BY_EMAIL_ADDRESS......: " & _
propertyAccessor.GetProperty(PR_RECEIVED_BY_EMAIL_ADDRESS)
Debug.Print "PR_SENT_REPRESENTING_EMAIL_ADDRESS: " & _
propertyAccessor.GetProperty(PR_SENT_REPRESENTING_EMAIL_ADDRESS)
Debug.Print "PR_SENDER_EMAIL_ADDRESS...........: " & _
propertyAccessor.GetProperty(PR_SENDER_EMAIL_ADDRESS)
End If
End Sub
Example format from Filtering Items Using a String Comparison
Private Sub RestrictBySchema()
Dim myInbox As Folder
Dim myFolder As Folder
Dim propertyAccessor As propertyAccessor
Dim strFilter As String
Dim myResults As Items
Dim mailAddress As String
' for testing
' open any folder not the Sent folder
' then the Sent folder
Set myFolder = ActiveExplorer.CurrentFolder
Debug.Print "myFolder............: " & myFolder
Debug.Print "myFolder.items.Count: " & myFolder.Items.Count
mailAddress = "email#somewhere.com"
Debug.Print "mailAddress: " & mailAddress
' Filtering Items Using a String Comparison
' https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering-items-using-a-string-comparison
'strFilter = "#SQL=""https://schemas.microsoft.com/mapi/proptag/0x0037001f"" = 'the right ""stuff""'"
'Debug.Print "strFilter .....: " & strFilter
' Items where PR_RECEIVED_BY_EMAIL_ADDRESS = specified email address
' This is the To
' No result from the Sent folder
' Logical as the item in the Sent folder could have multiple receivers
Debug.Print
Debug.Print "PR_RECEIVED_BY_EMAIL_ADDRESS"
strFilter = "#SQL=" & """" & PR_RECEIVED_BY_EMAIL_ADDRESS & """" & " = '" & mailAddress & "'"
Debug.Print "strFilter .....: " & strFilter
Set myResults = myFolder.Items.Restrict(strFilter)
Debug.Print " myResults.Count.....: " & myResults.Count
' Items where PR_SENT_REPRESENTING_EMAIL_ADDRESS = specified email address
Debug.Print
Debug.Print "PR_SENT_REPRESENTING_EMAIL_ADDRESS"
strFilter = "#SQL=" & """" & PR_SENT_REPRESENTING_EMAIL_ADDRESS & """" & " = '" & mailAddress & "'"
Debug.Print "strFilter .....: " & strFilter
Set myResults = myFolder.Items.Restrict(strFilter)
Debug.Print " myResults.Count.....: " & myResults.Count
' Items where SenderEmailAddress = specified email address
Debug.Print
Debug.Print "SenderEmailAddress"
strFilter = "[SenderEmailAddress] = '" & mailAddress & "'"
Debug.Print "strFilter .....: " & strFilter
Set myResults = myFolder.Items.Restrict(strFilter)
Debug.Print " myResults.Count.....: " & myResults.Count
' Items where PR_SENDER_EMAIL_ADDRESS = specified email address
Debug.Print
Debug.Print "PR_SENDER_EMAIL_ADDRESS"
strFilter = "#SQL=" & """" & PR_SENDER_EMAIL_ADDRESS & """" & " = '" & mailAddress & "'"
Debug.Print "strFilter .....: " & strFilter
Set myResults = myFolder.Items.Restrict(strFilter)
Debug.Print " myResults.Count.....: " & myResults.Count
End Sub

Access 2007 VBA SQL Select Error "Item not found in this collection"

Returning after fixing errors and now a new one. I have created an SQL Statement using VBA in Access 2007 and I am getting the error "Item not found in this collection" The fields do exist in the tables and are spelled correctly. I even copied the SQL statement into a query and it worked. I'm assuming the error is with this part of the code
Dim strCMCID As Long ' (it's a Key field AutoNumber)
strCMCID = Me!CMCID_Txt
and
"WHERE Commitments_Tbl.CMCID = " & strCMCID & ""
Full code posted below. This is my first time putting an SQL Statement in using VBA. What I am trying to do is get the SQL Statement to pull two email addresses from a specific record from the current Form.
Public Sub SendConfirm()
On Error GoTo Err_SendConfirm_Click
Dim Borrower As String, LOEmail As String, ProcEmail As String, ClsEmail As String, Caution As String, LNumber As Long, TheFile As String, TheName As String
'SQL Statement to get Processor and Closer email
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Dim strCMCID As Long 'AutoNumber
Dim strMWS As String
Dim strProcEM As String
Dim StrClsEM As String
strCMCID = Me!CMCID_Txt 'AutoNumber
strSQL = "SELECT Commitments_Tbl.CMCID, Status_Tbl.MWStatus, DBUsers_Tbl.EMail, DBUsers_Tbl_1.EMail " & _
"FROM ((Commitments_Tbl LEFT JOIN Status_Tbl ON Commitments_Tbl.LoanNumber = Status_Tbl.LoanNumber) LEFT JOIN DBUsers_Tbl AS DBUsers_Tbl_1 ON Status_Tbl.Processor = DBUsers_Tbl_1.MWName) LEFT JOIN DBUsers_Tbl ON Status_Tbl.Closer = DBUsers_Tbl.MWName " & _
"WHERE Commitments_Tbl.CMCID = " & strCMCID & ""
Set dbs = CurrentDb
Set rst = CurrentDb.OpenRecordset(strSQL)
strMWS = rst!MWStatus
strProcEM = Nz(rst!DBUsers_Tbl.EMail, "John.Doe#CWork.com")
StrClsEM = Nz(rst!DBUsers_Tbl_1.EMail, "John.Doe#Work.com")
'Message Box
Dim Msg, Style, Title, Response
LOEmail = Me!OrigID_Cbo.Column(3)
Borrower = Me!BorrNameL_Txt
LNumber = Nz(Me!LoanNumber_Txt, 0)
Msg = "Do you want to send an e-mail to Set_up?"
Style = vbYesNo
Title = "Cancel Set-Up E-Mail"
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
GoTo line3
Else
GoTo line4
End If
line3:
TheName = "" & Borrower & " " & LNumber & ""
TheFile = "P:\mortgage\prodcenters\LOAN ITEMS (SW)\_RateLocks_and_Changes\" & TheName & ".rtf"
DoCmd.OutputTo acOutputReport, "Confirmation_Email2", acFormatRTF, TheFile, False
If Nz(Me!InvestorID_Cbo, "Blank") = "Blank" Then
DoCmd.SendObject , , , "CommerceMortgage#CommerceBank.com", , , "New Lock: " & Borrower & ": " & LNumber, "A rate lock confirmation has been saved down to the server at P:\mortgage\prodcenters\LOAN ITEMS (SW)\_RateLocks_and_Changes as a word document with the same name and loan number as that is the subject line of this email. Please upload it into the GDR.", -1
Else
DoCmd.SendObject , , , "CommerceMortgage#CommerceBank.com", , , "Term Change" & ": " & Borrower & ": " & LNumber, "A rate lock confirmation has been saved down to the server at P:\mortgage\prodcenters\LOAN ITEMS (SW)\_RateLocks_and_Changes as a word document with the same name and loan number as that is the subject line of this email. Please upload it into the GDR.", True
End If
line4:
ClsEmail = Nz(StrClsEM, "John.Doe#Work.com")
ProcEmail = Nz(strProcEM, "John.Doe#Work.com")
If Me!RateExpDate_Txt <= Date + 8 Then
Caution = "STOP Terms Finalized:"
ElseIf strMWS = "Closing" And Me!RateExpDate_Txt >= Date + 8 Then
Caution = "STOP:"
Else
Caution = ""
End If
If Me!InvestorID_Cbo = "" Then
DoCmd.SendObject acSendReport, "Confirmation_Email", "SnapshotFormat(*.snp)", LOEmail, ProcEmail & ";" & ClsEmail, , Caution & "New Lock: " & Borrower & ": " & LNumber, , True
Else
DoCmd.SendObject acSendReport, "Confirmation_Email", "SnapshotFormat(*.snp)", LOEmail, ProcEmail & ";" & ClsEmail, , Caution & " " & "Term Change" & ": " & Borrower & ": " & LNumber, , True
End If
rst.Close
Set rst = Nothing
Set dbs = Nothing
Exit_SendConfirm_Click:
Exit Sub
Err_SendConfirm_Click:
MsgBox Err.Description
Resume Exit_SendConfirm_Click
End Sub
If we create a query in Access that pulls two fields with the same name from two different tables then Access will name the resulting columns Table1.Field and Table2.Field to disambiguate. When referring to those fields in the Recordset using "bang (!) notation" you must put square brackets around the entire field name. In your case, for example, you would need to use
rst![DBUsers_Tbl.EMail]
instead of
rst!DBUsers_Tbl.EMail

My outlook VBA code drops the odd email

I put together some VBA code for Outlook 2007 which has been working predominantly fine.
Its basically designed to check incoming messages and store the subject, body etc into a database and the attachment into a folder. In general, it works fine, but out of 100 messages or so, it drops the odd email.
I previously had a problem where some emails were not being processed and stored in the database, but then discovered there was an issue with illegal characters, which i have solved now, so that cant be it. I've compared the emails being dropped to the one's that arent, in terms of message header, content to and from fields and i cant see any difference between the two emails at all, so am completely perplexed as to why they're being dropped. When i copy the content of the email and forward it back to the system again, the VBA code processes it fine.
I am pasting the code below (the code links to some modules which are used for checking illegal characters or concatenating strings)
Sub SaveIncomingEmails(Items As Outlook.MailItem) ' enable this to run macro inbound emails
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
' ================================================================
' Open a Connection using an ODBC DSN named "Delphi".
' ================================================================
cnn.Open "MyDB", "MyUsername", "MyPassword"
' ================================================================
' Constants declaration
' ================================================================
Const olFolderInbox = 6
Const olTxt = 0
' ================================================================
' variable declaration
' ================================================================
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim SenderName As String
Dim i As Integer
Dim strSQLquery As String
Dim strSQLquery1 As String
Dim strSQLGTDResourceQuery As String
Dim MessageHeader As String
Dim strCommandQuery As String
Dim strGTDIdQuery As String
Dim AttachmentStr As String
Dim strFailedRcp As String
Dim strSubject As String
Dim hasattachment As String
Dim AttachmentType As String
Dim SenderAuthorised As String
Dim strToEmail As String
Dim strFromEmail As String
Dim strBody As String
Dim strSentDate As String
Dim strReceivedDate As String
Dim StrUniqueID As String
Dim strCommandDate As String
Dim strDomain As String
Dim strBodyStripped As String
Dim strSubjectStripped As String
Dim rs As Object
Dim strGoalId As String
Dim strFile As String
Dim strSenderAccountDescription As String
Dim strContentType As String
Dim strMimeVersion As String
Dim strReceived As String
' ================================================================
' Intializing variables
' ================================================================
i = 0
Set objItem = Items
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
Set colMailItems = objFolder.Items
Set Item = objItem
strToEmail = Items.To
strFromEmail = Items.SenderEmailAddress
strSubject = Items.Subject
strBody = Items.Body
strSentDate = Items.SentOn
strReceivedDate = Items.ReceivedTime
'Initialize variables in a given format
StrUniqueID = Format(Items.ReceivedTime, "ddmmyyyyhhnnss") & Items.SenderEmailAddress
strCommandDate = Format(Items.ReceivedTime, "mm/dd/yyyy_hh:nn:ss")
' Grab the sender domain by stripping the last portion of the email address using the getdomain function
strDomain = Module2.GetDomain(Items.SenderEmailAddress)
' Strip the body of illegal characters and replace with legal characters for insertion into SQL
strBodyStripped = Module3.RemoveIllegalCharacters(Items.Body)
strSubjectStripped = Module4.RemoveIllegalCharacters(Items.Subject)
AttachmentStr = "images/no_attachment.png"
' ================================================================
' ================================================================
' ================================================================
' =====================================================
' Check list of authorised senders for xsCRM commands.
' Populate email addresses here
' =====================================================
If (InStr(strFromEmail, "AuthorisedSender1#email.com") > 0) Or (InStr(strFromEmail, "AuthorisedSender2#email.com") > 0) Or (InStr(strFromEmail, "AuthorisedSender3#email.com") > 0) Then
SenderAuthorised = "true"
End If
' ======================================================
' ======================================================
' ======================================================
' ================================================================
' check if subject holds a command
' ================================================================
'check to see if email sender is authorised
If SenderAuthorised = "true" Then
' Check if the subject line contains the string xs4crm is true
If InStr(strSubject, "xs4crm") > 0 Then
'If its true then do this
strCommandQuery = "INSERT INTO XSCRMEMAILCOMMAND (" & vbCrLf & _
"FromEmail," & vbCrLf & _
"command," & vbCrLf & _
"date," & vbCrLf & _
"Body" & vbCrLf & _
") VALUES ('" & strFromEmail & "','" & strSubject & "',GETDATE(),'" & strBody & "')"
Set rs = cnn.Execute(strCommandQuery)
'Look for a GTDID string so that we can save data to resources table
If InStr(strSubject, "gtdid=") > 0 Then
'Set the hasattachment variable to zero since we only want to run this loop if there are no attachments
hasattachment = "0"
'Set the variable to 1 so that we that our next if statement can only run if there are no attachments
For Each Atmt In Item.Attachments
hasattachment = "1"
Next Atmt
If hasattachment = "0" Then
'Grab the GTDId so we know which goal this resource belongs too.
strGoalId = Module5.GetHeaderProperty(strSubject, "gtdid=", ";", 5)
'Save data to table
strGTDIdQuery = "INSERT INTO XSCRMGTDRESOURCES (" & vbCrLf & _
"GoalId," & vbCrLf & _
"insertdatetime" & vbCrLf & _
") VALUES ('" & strGoalId & "',GETDATE())"
Set rs = cnn.Execute(strGTDIdQuery)
End If
End If
End If
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Create folders for atttachments
' ================================================================
' Save any attachments found
For Each Atmt In Item.Attachments
AttachmentStr = "images/attachment.png" 'because it has gone into attachment loop the icon is now required.
'Create the subfolder for the attachment if it doesnt exist based on sender domain
Dim fso
Dim fol As String
fol = "c:\OLAttachments\" & strDomain
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' save attachments
' ================================================================
FileName = "C:\OLAttachments\" & strDomain & "\" & _
Format(Item.CreationTime, "ddmmyyyy-") & Items.SenderEmailAddress & "-" & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
strFile = Atmt.FileName
strSQLquery1 = "INSERT INTO XSCRMEMAILSATTACHMENTS (" & vbCrLf & _
"FileSavedIn," & vbCrLf & _
"ActualFileName," & vbCrLf & _
"UniqueIdentifier," & vbCrLf & _
"SendersEmail" & vbCrLf & _
") VALUES ('" & FileName & "','" & StrUniqueID & "','" & strFile & "','" & strFromEmail & "')"
Set rs = cnn.Execute(strSQLquery1)
'If there is a GTDCommand, then grab the GTDId so we know which goal this resource belongs too.
If InStr(strSubject, "gtdid=") > 0 Then
strGoalId = Module5.GetHeaderProperty(strSubject, "gtdid=", ";", 5)
End If
AttachmentType = ""
'If the attachment is png or jpg set attachment type string to image
If (InStr(Atmt.FileName, ".png") > 0) Or (InStr(Atmt.FileName, ".jpg") > 0) Then
AttachmentType = "image"
End If
'If attachment is .mov set attachment type string to video
If InStr(Atmt.FileName, ".mov") > 0 Then
AttachmentType = "video"
End If
'If the attachment is mp3 or m4a set attachment type string to audio
If (InStr(Atmt.FileName, ".mp3") > 0) Or (InStr(Atmt.FileName, ".m4a") > 0) Then
AttachmentType = "audio"
End If
'check to see if email sender is authorised
If SenderAuthorised = "true" Then
'If attachment type is an image, audio or video as per extensions above then populate the xscrmgtdresource table with following fields
If (InStr(Atmt.FileName, ".png") > 0) Or (InStr(Atmt.FileName, ".jpg") > 0) Or (InStr(Atmt.FileName, ".mov") > 0) Or (InStr(Atmt.FileName, ".m4a") > 0) Or (InStr(Atmt.FileName, ".mp3") > 0) Then
strSQLGTDResourceQuery = "INSERT INTO XSCRMGTDRESOURCES (" & vbCrLf & _
"GoalId," & vbCrLf & _
"Title," & vbCrLf & _
"Type," & vbCrLf & _
"insertdatetime," & vbCrLf & _
"ResourcePath," & vbCrLf & _
"UniqueIdentifier" & vbCrLf & _
") VALUES ('" & strGoalId & "','" & Atmt.FileName & "','" & AttachmentType & "',GETDATE(),'" & FileName & "','" & StrUniqueID & "')"
End If
Set rs = cnn.Execute(strSQLGTDResourceQuery)
End If
Next Atmt
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Setting up to work with the Email Message Header
' ================================================================
'This accesses the message header property and sets the variable MessageHeader
Const PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E"
MessageHeader = objItem.PropertyAccessor.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS)
If MessageHeader <> "" Then
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Accessing the message header and collecting specific info for database tables
' ================================================================
strSenderAccountDescription = Module5.GetHeaderProperty(MessageHeader, "From:", "<", 5)
strContentType = Module5.GetHeaderProperty(MessageHeader, "Content-Type:", ";", 13)
strMimeVersion = Module5.GetHeaderProperty(MessageHeader, "MIME-Version:", vbNewLine, 13)
strReceived = Module5.GetHeaderProperty(MessageHeader, "Received:", "(", 9)
'As the x-failed-recipients property does not appear in ALL messageheaders, we have to first check if it is present
If InStr(MessageHeader, "X-Failed-Recipients:") > 0 Then
'Get the MessageHeader Property value
strFailedRcp = Module5.GetHeaderProperty(MessageHeader, "X-Failed-Recipients:", vbNewLine, 20)
'Else set the variable value to blank so that we still have something to supply to the SQL query
Else
strFailedRcp = ""
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Save Email into the database DeplphiDude and table xsCRMEmails for attachment based emails and without attachments
' ================================================================
If InStr(strSubject, "xs4crm") = 0 Then 'only insert if the emails is not a command
strSQLquery = "INSERT INTO XSCRMEMAILS (" & vbCrLf & _
"XFailedRecipients," & vbCrLf & _
"Received," & vbCrLf & _
"MimeVersion," & vbCrLf & _
"ContentType," & vbCrLf & _
"SendersAccountDescription," & vbCrLf & _
"FromEmail," & vbCrLf & _
"ToEmail," & vbCrLf & _
"Subject," & vbCrLf & _
"Body," & vbCrLf & _
"SentDate," & vbCrLf & _
"ReceivedDate," & vbCrLf & _
"UniqueIdentifier," & vbCrLf & _
"Status," & vbCrLf & _
"AttachmentIcon," & vbCrLf & _
"AssignedToUser," & vbCrLf & _
"EmailHeader" & vbCrLf & _
") VALUES ('" & strFailedRcp & "','" & strReceived & "','" & strMimeVersion & "','" & strContentType & "','" & strSenderAccountDescription & "', '" & strFromEmail & "','" & strToEmail & "','" & strSubjectStripped & "','" & strBodyStripped & "','" & strSentDate & "','" & strReceivedDate & "','" & StrUniqueID & "','EmailStatus_New','" & AttachmentStr & "','','" & Module4.RemoveIllegalCharacters(MessageHeader) & "')"
Set rs = cnn.Execute(strSQLquery)
End If
' ================================================================
' final steps
' ================================================================
'Delete email
objItem.Delete
Set objItem = Nothing
Set Atmt = Nothing
' ================================================================
' close connection to the sql server and end the program
' ================================================================
cnn.Close
End Sub
You should add some logging to help track down the problem.
I haven't used this personally, but maybe give it a go: Log4VBA
Also, you should add error handling:
Error Handling and Debugging Tips for Access 2007, VB, and VBA
Error Handling In VBA
First you do not say which part of your process is not working. You have showed a routine that does not fire by itself, it must be called by something else. This something else must have some conditions attached to it to call your routine. What are they? Can you show the workings of this.
If you are using a rule then could you show the conditions of the rule. Further what about if instead of a rule we code for the event in the VBEditor so that you can maybe see this event happening as well? Here is what I am talking about and there is example code there on how to do it MSDN Application_New_MAIL
Next I agree with everyone else that you need some logging, there is so much going on and it is impossible to tell where you cod is falling over. If I were you I would get an email that does not work and send it to yourself and have a break point right at the beginning of your code so that you can see a. That your code is actually being called and then where it is failing.