Many people access the material from this web site daily.
Most just take what they want and run. That's OK, provided they
are not selling on the material as their own; however if your
productivity gains from the material you have used, a donation
from the money you have saved would help to ensure the continued
availability of this resource. Click the appropriate button
above to access PayPal.
Add a Reference Number to Outgoing Outlook Messages
A user in a VBA forum requested a process to add a reference
number to the top of all outgoing messages, but was unclear about
where the reference numbers were to be logged, so I thought it worth
using Excel both to create the numbers and to record what messages
they applied to.
The macro also creates the workbook if not already present
and sets the start number of the first record to 1 (though you
can change that to any number you wish)
For this to be a useful process it should happen
transparently, so much of the work is done using ADO to access
the workbook without opening it in Excel, which would prolong
the process. Once the workbook is created and the first number
applied, which takes a few moments, subsequent additions are
imperceptible to the user.
The macro uses event processing to intercept the Send function
and process the outgoing message, so the code should be added to the
'ThisOutlookSession' module of the Outlook VBA editor.
The code is annotated where appropriate and employs a number
of my standard functions to establish whether files and folders
exist and to create new ones as required.
The macro takes the message in the first illustration and
adds the line of text in the second
The messages and their reference numbers are stored in the
log:
Option Explicit
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As
Boolean)
'Graham Mayor 07 June 2015
'Macro goes in the 'ThisOutlookSession' module
'A process to add a reference number to the start of all
outgoing messages and
'record the messages in an Excel log file.
'The name and path of the log
Const strWorkbook As String = "C:\MessageLog\MessageLog.xlsx"
'The workbook to store the data
'The folder in which the log is saved.
Const strPath As String = "C:\MessageLog\" 'The folder to store
the data
'The Excel fields used to record the data
Const strFields As String = "RefNo|Date|Time|MessageTo|Subject"
'The fields to store the data
Dim olInsp As Outlook.Inspector
Dim wdDoc As Object
Dim oRng As Object
Dim strValues As String
Dim iStartNum As Long
Dim strSubject As String
Dim strDate As String
Dim strTime As String
Dim strRecipient As String
'Establish whether the folder exists and if not create it.
If Not FileExists(strWorkbook) Then
CreateFolders strPath
xlCreateBook strWorkbook, strFields
'It's a new file so start the numbering for the first record
iStartNum = 0 ' One less than the first number to record.
Else
'It's an existing log so get the last used reference number
iStartNum = xlGetLastNum(strWorkbook)
End If
'Set the data and time formats
strDate = Format(Date, "dd/MM/yyyy")
strTime = Format(Time, "HH:MM:SS")
'Process the outgoing message
With Item
strSubject = .Subject
strRecipient = Replace(.To, "'", "")
'Access the message body
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
'Set a range to the start of the message body
Set oRng = wdDoc.Range(0, 0)
'And add the date, time and add one to the last used reference
number
oRng.Text = "Date: " & strDate & _
", Time: " & strTime & _
", Our Ref: " & _
CStr(iStartNum + 1) & vbCr & vbCr
'Record the values added to a string
strValues = CStr(iStartNum + 1) & "', '" & _
strDate & "', '" & _
strTime & "', '" & _
strRecipient & "', '" & _
strSubject
'Save the message
.Save
'Use ADO to write the values to the Excel log
WriteToWorksheet strWorkbook, "Sheet1", strValues
End With
lbl_Exit:
'Clean up
Set olInsp = Nothing
Set wdDoc = Nothing
Set oRng = Nothing
Exit Sub
End Sub
Private Function WriteToWorksheet(strWorkbook As String, _
strRange As String, _
strValues As String)
'Graham Mayor
'A Process to write the data to a workbook without opening it in
Excel
'strWorkbook is the fullname of the workbook to process
'strRange is the name of the worksheet
'strValues is a list of the values separated by "', '"
Dim CN As Object
Dim ConnectionString As String
Dim strSQL As String
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strWorkbook & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"
strSQL = "INSERT INTO [" & strRange & "$] VALUES('" & strValues
& "')"
Set CN = CreateObject("ADODB.Connection")
Call CN.Open(ConnectionString)
Call CN.Execute(strSQL, , 1 Or 128)
CN.Close
Set CN = Nothing
lbl_Exit:
Exit Function
End Function
Private Function xlGetLastNum(strWorkbook As String) As Long
'Graham Mayor
'A Process to read the last used number from the workbook
without opening
'it in Excel
'strWorkbook is the fullname of the workbook to process
Dim RS As Object
Dim CN As Object
Const strWorksheetName As String = "Sheet1$]"
Set CN = CreateObject("ADODB.Connection")
CN.Open ConnectionString:="Provider=Microsoft.ACE.OLEDB.12.0;" &
_
"Data Source=" & strWorkbook & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Set RS = CreateObject("ADODB.Recordset")
RS.Open "SELECT * FROM [" & strWorksheetName, CN, 2, 1
With RS
.MoveLast
xlGetLastNum = .Fields(0)
End With
If RS.State = 1 Then RS.Close
Set RS = Nothing
If CN.State = 1 Then CN.Close
Set CN = Nothing
lbl_Exit:
Exit Function
End Function
Private Sub xlCreateBook(strWorkbook As String, strTitles As
String)
'Graham Mayor
'Create a new workbook with the required fields for the process
'strWorkbook is the fullname of the new workbook
'strTitles is a list of the field names separated by the '|'
(pipe) symbol
Dim vValues As Variant
Dim xlApp As Object
Dim xlWB As Object
Dim bStarted As Boolean
Dim i As Long
vValues = Split(strTitles, "|")
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Set xlApp = CreateObject("Excel.Application")
bStarted = True
End If
On Error GoTo 0
Set xlWB = xlApp.Workbooks.Add
With xlWB.Sheets(1)
For i = 0 To UBound(vValues)
.Cells(1, i + 1) = vValues(i)
Next i
End With
xlWB.SaveAs strWorkbook
xlWB.Close 1
If bStarted Then
xlApp.Quit
Set xlApp = Nothing
Set xlWB = Nothing
End If
lbl_Exit:
Exit Sub
End Sub
Private Function CreateFolders(strPath As String)
'Graham Mayor
'A function to create a named path if it doesn't exist
'strPath is the folder to check and/or create
Dim strTempPath As String
Dim lngPath As Long
Dim vPath As Variant
vPath = Split(strPath, "\")
strPath = vPath(0) & "\"
For lngPath = 1 To UBound(vPath)
strPath = strPath & vPath(lngPath) & "\"
If Not FolderExists(strPath) Then MkDir strPath
Next lngPath
lbl_Exit:
Exit Function
End Function
Private Function FileNameUnique(strPath As String, _
strFileName As String, _
strExtension As String) As String
'Graham Mayor
'A function to create unique filenames (works in all Office apps
that run VBA)
'strPath is the folder in which the file will be saved e.g.
C:\Path\
'strFileName is the original name of the file to be saved
'strExtension is the filename extension e.g. "xlsx", "docx" etc
Dim lngF As Long
Dim lngName As Long
lngF = 1
lngName = Len(strFileName) - (Len(strExtension) + 1)
strFileName = Left(strFileName, lngName)
Do While FileExists(strPath & strFileName & Chr(46) &
strExtension) = True
strFileName = Left(strFileName, lngName) & "(" & lngF & ")"
lngF = lngF + 1
Loop
FileNameUnique = strFileName & Chr(46) & strExtension
lbl_Exit:
Exit Function
End Function
Private Function FileExists(filespec) As Boolean
'Graham Mayor
'A function to establish if a file exists
'(works in all Office apps that run VBA)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(filespec) Then
FileExists = True
Else
FileExists = False
End If
lbl_Exit:
Exit Function
End Function
Private Function FolderExists(strFolderName As String) As
Boolean
'Graham Mayor
'A function to establish if a folder exists
'(works in all Office apps that run VBA)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FolderExists(strFolderName)) Then
FolderExists = True
Else
FolderExists = False
End If
lbl_Exit:
Exit Function
End Function