Use Excel as MS-Outlook clone to handle MSG files

RoVBA

New Member
Joined
Nov 15, 2013
Messages
7
Hi all,
in another thread I promised to publish my code for an MS-Outlook clone using Excel.
I publish this because the code others published was so useful to me and I want to do somethig in return.
I am not a professional programmer, so please don't laugh at what I did. It works and for the most of it I even
understand how and why.
The reason for me to start doing something with VBA is the fact that my employer seriously reduced our email
boxes 3 months ago. We are told to store emails on the network as *.msg files (PST files not allowed), which
sucks. In Explorer you can only use file names to look for emails.
I desperately need to be able to use the "metadata" of the *.msg files as well (sender, receivers, etc.).
My employer is not going to help out with suitable software and we are not allowed to install software ourselves.
I decided to try to use Excel as an Outlook clone. That way I can profit from the built in sort and search
functions of Excel.
The Excel program is a suplement to a piece of VBA I made together with a colleague, that works within MS-Outlook.
With that program we are able to put a date-and-time stamp in the subject of selected emails in Outlook.
The subject becomes the file name in Explorer. The date-and-time stamp ensures the file name is unique.
I am from The Netherlands. Most of my variable names and so on are in Dutch. Sorry about that. The advantage
for me is that Dutch terms will never clash with names VBA reserves for itself.
I started with publishing all of the code for my Excel program, but I think it is a little too much for the forum.
The webpage stalls each time.
So, instead of publishing all of the code I herewith only show the core of the program. I hope it inspires others
to find VBA solutions for things they encounter.
(You have enable Microsoft Outlook 14.0 Object Library for it to work (menu Extra > references))
Code:
Sub NieuweMailsToevoegen()
'This sub adds metadata of *.msg files to a list in an Excel worksheet
'User can select a folder where *.msg files are stored
'If user selects a path different from the one mentioned in cel B2 of the active worksheet
'user is warned that the path is changed. If OK, all metadata is deleted and the whole list is refreshed.
'To save time only new or removed *.msg files are procesed.
'CHANGE LOG
'19 Dec. '13
'- The hyperlinks to *.msg files are no longer used, as they are too vulnerable. They easily "die" after network
'modifications. In stead I use path and file name.
'21 Dec. '13
'- metadata for conversation mode of emails is added to the list.

    Dim AantalMSGBestanden As Long
    Dim MSGTeller As Long
    Dim Voortgang As Single
    Dim AantalGegevensInExcellijst As Long
    Dim AantalDodeLinks As Long
    
    Dim BekendeMailArray() As Variant
    Dim NieuweMailArray() As Variant
    Dim Bestandslijst As New Collection
    Dim BekendeMailPositie As Long
    Dim NieuweMailPositie As Long
    Dim BestandslijstPositie As Long
    Dim teller As Long
     
    Dim GeenDodeLinksOver As Boolean
    Dim DodeLinkGevonden As Boolean
    Dim VerversAlleGegevens As Boolean
    Dim Doorgaan As Integer
    Dim Melding As String
    Dim NieuweMail As Boolean
    Dim FileName As String
    
    Dim MyOutlook As Outlook.Application
    Dim X As Namespace
    Dim msg As Outlook.MailItem
    
    Dim ResetVerticalScroll As Range
    
   
    Dim pad As String 'THis is the path where a user wants to search for *.msg files
    Dim Pad2 As String 'I need this variable because function Browsefolder(....) returns a string without "\" at the end
    
    Set MyOutlook = New Outlook.Application
    Set X = MyOutlook.GetNamespace("MAPI")
    
    'This is for the pop up screen with the progress bar
    Set ProgressIndicator = New UserForm1
   
    Call ResetFiltersEnSorteerGegevensOpDatumOplopend
    Application.ScreenUpdating = False
    
'### DETERMINE PATH #######################################################################
    
'Open the folder with *.msg files.
'Function Browsefolder(....) returns the path the user selected.
'The path Browsefolder(....) returns is compared with the value in cel "B2".
'If ther is a difference between them, the user is warned and all data is refreshed.
    pad = Range("B2").Value
    pad = browsefolder("Select a folder with *.msg files.", pad)
    Pad2 = pad & "\*.msg"
    FileName = Dir(Pad2)
'Terminate sub if user selected cancel during execution of function Browsefolder(....)
    If pad = "" Then
        Application.ScreenUpdating = True
        Exit Sub
    End If
    
'Check if it is necessary to refresh all email data.
'This is required if the user selected path different from the value in cel B2, or if no email data was found in the
'active sheet.
    VerversAlleGegevens = False
    
    If Range("E6").Value = "" Then
        VerversAlleGegevens = True
    End If
    
    If Range("B2").Value <> pad Then
        VerversAlleGegevens = True
        Melding = "You have selected the following path to look for email data:" & Chr(13) & _
                    "     " & pad & Chr(13) & Chr(13) & _
                    "This path is not the same as the path used before, which was:" & Chr(13) & _
                    "     " & Range("B2").Value & Chr(13) & Chr(13) & _
                    "If you continue, all available data in this Excel sheet will be deleted and then refreshed." & Chr(13) & Chr(13) & _
                    "Continue?" & Chr(13)
        Doorgaan = MsgBox(Melding, vbYesNo + vbExclamation, "New Path Detected")
        If Doorgaan = vbYes Then
            Call WisGegevens
            Range("B2").Value = ""
            'Show user that email data is removed by switching screen updating on and off again.
            Application.ScreenUpdating = True
            Application.ScreenUpdating = False
        ElseIf Doorgaan = vbNo Then
            Application.ScreenUpdating = True
            Exit Sub
        End If
    End If
 
'### RECORD MAIL DATA #######################################################################
   
   
    'First determine how much email data is available to be able to use the progress bar pop up screen
    Range("E5").Select
    Do
        ActiveCell.Offset(1, 0).Activate
    Loop Until ActiveCell.Offset(1, 0).Value = ""
    AantalGegevensInExcellijst = ActiveCell.Row - 5
    
    Range("E6").Select
    
    'show progress screen
    ProgressIndicator.Show vbModeless
    
    'Store all file names in arrayvariabele BestandArray
    BekendeMailPositie = 0
    Do While ActiveCell.Value <> "" 'as long as file names are found
        BekendeMailPositie = BekendeMailPositie + 1 'counter needed to make room in the array variable
        ReDim Preserve BekendeMailArray(1 To BekendeMailPositie) 'change the size of the array variable if another filename must be added (while preserving the existing data)
        BekendeMailArray(BekendeMailPositie) = ActiveCell.Value 'store the current file name in the array variable
        
        ActiveCell.Offset(1, 0).Activate
        
        'calculate the progress and show the updated progress bar
        If ActiveCell.Value <> "" Then
            Voortgang = (ActiveCell.Row - 5) / AantalGegevensInExcellijst
            Call UpdateProgress(Voortgang, "Capturing current Email data")
        End If
    
    Loop
    
    'remove the pop up screen with the progress bar and reset it
    Unload ProgressIndicator
    Set ProgressIndicator = New UserForm1
    Voortgang = 0
    
    'Move all file names from arrayvariable BestandArray to collection variable Bestandslijst
    'because it is easier to remove a certain record from a collection variable. I need that later on
    'I am a little too lazy now to spend time figure out how to remove a certain record from an array variable....
    For BestandslijstPositie = 1 To BekendeMailPositie
          Bestandslijst.Add BekendeMailArray(BestandslijstPositie)
    Next BestandslijstPositie
 
'### SEARCH FOR NEW MSG FILES #######################################################################

'Go through all *.msg files in the selected folder. Check for each file if it was already present in collection
'variable FileLijst. If already present, remove this name from the collection variable.
    'show progress screen
    ProgressIndicator.Show vbModeless
    
    NieuweMailPositie = 0
    AantalMSGBestanden = CountFiles(pad, "msg") 'needed to calculate progress
    
    Do While FileName <> ""
         
        NieuweMail = True
        BestandslijstPositie = 0
             
        If VerversAlleGegevens = False Then
            If BekendeMailPositie > 0 Then
                Do
                    BestandslijstPositie = BestandslijstPositie + 1
                    If FileName = Bestandslijst(BestandslijstPositie) Then
                        Bestandslijst.Remove (BestandslijstPositie)
                        BekendeMailPositie = BekendeMailPositie - 1
                        NieuweMail = False
                    End If
                Loop Until BestandslijstPositie = BekendeMailPositie _
                    Or BekendeMailPositie = 0 Or NieuweMail = False
                If BekendeMailPositie = 0 Then
                    Bestandslijst.Add "Geen dode links"
                End If
            
            End If
        End If
  
        If NieuweMail = True Then
            NieuweMailPositie = NieuweMailPositie + 1 ''counter needed to make room in the array variable
            ReDim Preserve NieuweMailArray(1 To NieuweMailPositie) 'change the size of the array variable if another filename must be added (while preserving the existing data)
            NieuweMailArray(NieuweMailPositie) = FileName 'put the current file name in the array varable
        End If
        
        MSGTeller = MSGTeller + 1
        Voortgang = MSGTeller / AantalMSGBestanden
        Call UpdateProgress(Voortgang, "Looking for new *.msg files.")
        
        FileName = Dir()
    Loop
    
    'remove the progress screen and reset it
    Unload ProgressIndicator
    Set ProgressIndicator = New UserForm1
    Voortgang = 0

'### REMOVE EMAIL DATA OF MSG FILES THAT NO LONGER EXIST ####################################################################
    'Count how many "dead links" there are (rows with data of files that no longer exist).
    'The number of dead links is the same as the number of records that are left in
    'collection variable Bestandslijst()
    
    AantalDodeLinks = 0
    DodeLinkGevonden = True
    Do
        AantalDodeLinks = AantalDodeLinks + 1
        On Error Resume Next
        Bestandslijst (AantalDodeLinks)
        If Err.Number = 9 Then
            DodeLinkGevonden = False
            AantalDodeLinks = AantalDodeLinks - 1
        ElseIf Bestandslijst(AantalDodeLinks) = "Geen dode links" Then
            DodeLinkGevonden = False
        
        End If
    Loop Until DodeLinkGevonden = False
    'Remove rows with dead links from the excel sheet
    If AantalDodeLinks > 0 Then
        teller = 0
        Range("E5").Select
        Do
            ActiveCell.Offset(1, 0).Activate
            For teller = 1 To AantalDodeLinks
                If Bestandslijst(teller) = "Geen dode links" Then
                    Exit Do
                ElseIf ActiveCell.Value = Bestandslijst(teller) Then
                    Rows(ActiveCell.Row).Delete Shift:=xlUp
                    ActiveCell.Offset(-1, 0).Activate
                End If
            Next teller
        Loop Until ActiveCell.Value = ""
     End If
    
'### ADD DATA OF NEW MSG FILES TO THE LIST #######################################################################
   'Show progress screen
    ProgressIndicator.Show vbModeless
    'add new data to the list
    Range("E5").Select
    Do
        ActiveCell.Offset(1, 0).Activate
    Loop Until ActiveCell.Value = ""
    
    For teller = 1 To NieuweMailPositie
        
        'add metadata of the active mailfile in the list
        Set msg = X.OpenSharedItem(pad & "\" + NieuweMailArray(teller))
        Application.Wait (True)
        ActiveCell.Offset(0, -4).Value = msg.SenderName
        ActiveCell.Offset(0, -3).Value = msg.To
        ActiveCell.Offset(0, -2).Value = msg.CC
        ActiveCell.Offset(0, -1).Value = msg.SentOn
        ActiveCell.Value = NieuweMailArray(teller) 'add the file name instead of a hyperlink
        ActiveCell.Font.Color = -4165632 'blue text for legibility
        ActiveCell.Offset(0, 1).Value = msg.Body
        ActiveCell.RowHeight = 12.75
        If msg.Attachments.Count > 0 Then
            ActiveCell.Offset(0, 2).Value = "Attachment(s)"
        End If
        ActiveCell.Offset(0, 3).Value = msg.ConversationTopic
        ActiveCell.Offset(1, 0).Select
        Voortgang = teller / NieuweMailPositie
        Call UpdateProgress(Voortgang, "Adding Email data to list.")
    Next teller
    
        
    'remove progress screen and reset values
    Unload ProgressIndicator
    Set ProgressIndicator = Nothing
    Voortgang = 0
    
'### CLEAN, SORT, ETC. ##############################################################
    
    Call ResetFiltersEnSorteerGegevensOpDatumOplopend
    Application.ScreenUpdating = False
    Range("B2").Value = pad
    Range("B3").Value = Now()
    Range("B3").HorizontalAlignment = xlLeft
    Range("B3").VerticalAlignment = xlBottom
         
    Range("A6").Select
    
    'make sure the vertical scroll function is usable again (without this the screen flashes up and down
    'if a user tries to scroll using the ruler on the right side of the screen, as all 10 milion + rows
    'were modified while executing this sub)
    Set ResetVerticalScroll = ActiveSheet.UsedRange
    
    Application.ScreenUpdating = True
'### CHECK IF THE SUB WORKED CORRECTLY ############################################################################
'The sub worked correctly if the number of *.msg files is the same as the number
'of records in the Excel list.
    AantalGegevensInExcellijst = 0
    Range("E5").Select
    If ActiveCell.Offset(1, 0).Value <> "" Then
        Do
            ActiveCell.Offset(1, 0).Activate
            AantalGegevensInExcellijst = AantalGegevensInExcellijst + 1
        Loop Until ActiveCell.Offset(1, 0).Value = ""
    End If
    
    If AantalMSGBestanden <> AantalGegevensInExcellijst Then
        Melding = MsgBox("Something is wrong." & Chr(13) & Chr(13) & _
                        AantalMSGBestanden & " *.msg files were found in the selected folder." & Chr(13) & _
                        AantalGegevensInExcellijst & " items were recorded in this Excel list." & Chr(13) & _
                        "These two figures should be the same." & Chr(13) & Chr(13) & _
                        "Try to refresh all items by first removing the link in cell B2" & Chr(13) & _
                        "and then pressing the refresh button.", vbOKOnly + vbCritical, "Program fault detected")
    ElseIf AantalMSGBestanden = AantalGegevensInExcellijst Then
        Melding = MsgBox("Program completed successfully." & Chr(13) & Chr(13) & _
                        AantalMSGBestanden & " *.msg files were found in the selected folder." & Chr(13) & _
                        AantalGegevensInExcellijst & " items are now recorded in this Excel list." & Chr(13), _
                        vbOKOnly + vbInformation, "Ready")
    End If
          
End Sub 'NieuweMailsToevoegen

Function browsefolder(Title As String, _
        Optional InitialFolder As String = vbNullString, _
        Optional InitialView As Office.MsoFileDialogView = _
            msoFileDialogViewList) As String
    
'Found on the Internet. Thanks!
    Dim V As Variant
    Dim InitFolder As String
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = Title
        .InitialView = InitialView
        If Len(InitialFolder) > 0 Then
            If Dir(InitialFolder, vbDirectory) <> vbNullString Then
                InitFolder = InitialFolder
                If Right(InitFolder, 1) <> "\" Then
                    InitFolder = InitFolder & "\"
                End If
                .InitialFileName = InitFolder
            End If
        End If
        .Show
        On Error Resume Next
        Err.Clear
        V = .SelectedItems(1)
        If Err.Number <> 0 Then
            V = vbNullString
        End If
    End With
    browsefolder = CStr(V)
End Function 'browsefolder
Function CountFiles(strDirectory As String, Optional strExt As String = "*.*") As Double
'Found on the Internet, Thanks!
'Author          : Ken Puls ([URL="http://www.excelguru.ca"]www.excelguru.ca[/URL])
'Function purpose: To count files in a directory.  If a file extension is provided,
'   then count only files of that type, otherwise return a count of all files.
    Dim objFso As Object
    Dim objFiles As Object
    Dim objFile As Object
    'Set Error Handling
    On Error GoTo EarlyExit
    'Create objects to get a count of files in the directory
    Set objFso = CreateObject("Scripting.FileSystemObject")
    Set objFiles = objFso.GetFolder(strDirectory).Files
    'Count files (that match the extension if provided)
    If strExt = "*.*" Then
        CountFiles = objFiles.Count
    Else
        For Each objFile In objFiles
            If UCase(Right(objFile.Path, (Len(objFile.Path) - InStrRev(objFile.Path, ".")))) = UCase(strExt) Then
                CountFiles = CountFiles + 1
            End If
        Next objFile
    End If
EarlyExit:
    'Clean up
    On Error Resume Next
    Set objFile = Nothing
    Set objFiles = Nothing
    Set objFso = Nothing
    On Error GoTo 0
    
End Function 'CountFiles

That's it. I hope someone can use it.
Cheers,
Ro.
 

Excel Facts

Who is Mr Spreadsheet?
Author John Walkenbach was Mr Spreadsheet until his retirement in June 2019.

Forum statistics

Threads
1,214,869
Messages
6,122,015
Members
449,060
Latest member
LinusJE

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top