Option Compare Database
Option Explicit
Dim rs As DAO.Recordset
'----------------------------------------------------------------
' arnel g. puzon
' 18-Aug-2015
'
' in response to Mr. JohnLee's
'
' I Hoping someone can help me as I’m having problems understanding
' how to write VBA to extract data from “.msg” files and import that data into a table in my database.
' I have over 5000 .msg files of which I need to extract the following information:
'----------------------------------------------------------------
Public Sub UpdateTableFromMsgFiles()
'
'-----------------------------------------------------------------
' table structure to update from .msg (outlook)
'
' strFirstName
' strSurname
' strStreetNr
' strCity
' strPostcode
' strTel
' strMobile
' strEmail
' strVoucherCode
' strAddif
' strModel
' strSerialNo
' strName
' strStreet
' strNr
' strPostcode2
' strGasSafe
' strIsadv
' strTC
' strInstallationDate
'
'---------------------------------------------------------------
'
' location of .msg
' G:\Scan - Verify\eFlow\Dynamics\Vaillant\Old No DPA Printed
'
'----------------------------------------------------------------
' format of .msg
'
' First Name: Tim
' Surname: O 'Rourke
' Street & Nr: 399 Upper Eastern Green Lane
' City: Coventry
' Postcode: CV5 7DJ
' Tel: 02476 421140
' Mobile: 07854420697
' Email: timorourke@ fsmail.net
' Do you have a voucher code?:
' adddif:
' Select a model: ecoTEC plus 831
' serial numer (28 didgets): 21145000100116861300375260N1 DD-MM-YYYY Installation Date: 2015-03-27
' Name: Barry Allard,Premium Heating and Plumbing
' Street: Broad Lane
' Nr.: Coventry
' Postcode: CV5 7DJ
' Gas Safe Number (5/6 digits): 518169
' isadv:
' tc: 1
' DD-MM-YYYY Installation Date:
'
'----------------------------------------------------------------
' Make reference to the ff:
'
' Microsoft Outlook XX.X Object Library
' Microsoft Scripting Runtime
'
'----------------------------------------------------------------
' your table name here
Const strTableName As String = "tblWebReg"
Dim db As DAO.Database
Dim fso As Scripting.FileSystemObject
Dim strPath As String
Dim strSaveTo As String
Dim lngCounter As Long
Dim strHTML As String
Dim OL As Outlook.Application
Dim Msg As Outlook.MailItem
Dim f As Scripting.File
'*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
'*!
'*!
'*! CHANGE THE PATH BELOW TO THE CORRECT LOCATION OF YOUR .msg FILES
'*!
'*!
'strPath = CurrentProject.Path
strPath = "G:\Scan - Verify\eFlow\Dynamics\Vaillant\Old No DPA Printed"
'*!
'*!
'*! NOTE:
'*! it will create a temporary folder "Text" to your source
'*! folder.
'*!
'*!
'*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
strSaveTo = strPath & "\Text"
Set fso = New Scripting.FileSystemObject
If fso.FolderExists(strSaveTo) Then
' delete folder if already exists
fso.DeleteFolder strSaveTo, True
End If
' create new temporary foldr
fso.CreateFolder strSaveTo
Set db = CurrentDb
' open our table
Set rs = db.OpenRecordset(strTableName, dbOpenDynaset)
' create outlook instance
Set OL = CreateObject("Outlook.Application")
' create scripting instance
Set fso = CreateObject("Scripting.FileSystemObject")
' recurse folder for .msg files
For Each f In fso.GetFolder(strPath).Files
If LCase(fso.GetExtensionName(f)) = "msg" Then
Set Msg = OL.CreateItemFromTemplate(f.Path)
' save .msg as text file, so we can read later
'Msg.SaveAs strSaveTo & "\" & Replace(f.Name, ".msg", ".txt"), olTXT 'olDoc
Call subSaveStream(fso, strSaveTo & "\" & Replace(f.Name, ".msg", ".txt"), Msg.Body)
End If
Next
If Not (OL Is Nothing) Then OL.Quit: Set OL = Nothing
'process our text files
lngCounter = 0
For Each f In fso.GetFolder(strSaveTo).Files
If LCase(fso.GetExtensionName(f)) = "txt" Then
''''''''''''''''''''
'' add to our table
''''''''''''''''''''
Call addToTable(f)
End If
Next
house_keeping:
' housekeeping
' close all instance of automations
If Not (fso Is Nothing) Then Set fso = Nothing
If Not (rs Is Nothing) Then rs.Close: Set rs = Nothing
If Not (db Is Nothing) Then db.Close: Set db = Nothing
MsgBox "Done!" & vbCrLf & vbCrLf & "Please see table tblWebReg."
End Sub
Private Sub addToTable(ByVal strFileName As String)
' array to hold search strings
Dim s() As String
' array to hold table field names
Dim f() As String
Dim bolAdd As Boolean
Dim bolVaillant As Boolean
Dim i As Long
Dim j As Long
Dim lngPos As Long
Dim bolPostalOneFinished As Boolean
Dim strTextLine As String
Dim iFile As Integer
' variable count for vaillant msg
Dim bytAddress As Byte
Dim bytCity As Byte
Dim bytPostCode As Byte
ReDim s(19)
ReDim f(19)
' text to search in the text file
s(0) = "First Name:"
s(1) = "Surname:"
s(2) = "Street & Nr:"
s(3) = "City:"
s(4) = "Postcode:"
s(5) = "Tel:"
s(6) = "Mobile:"
s(7) = "Email:"
s(8) = "Do you have a voucher code?:"
s(9) = "adddif:"
s(10) = "Select a model:"
s(11) = "serial numer (28 didgets):"
s(12) = "Name:"
s(13) = "Street:"
s(14) = "Nr.:"
s(15) = "Postcode:"
s(16) = "Gas Safe Number (5/6 digits):"
s(17) = "isadv:"
s(18) = "tc:"
s(19) = "DD-MM-YYYY Installation Date:"
'field name to update from our table
f(0) = "strFirstName"
f(1) = "strSurname"
f(2) = "strStreetNr"
f(3) = "strCity"
f(4) = "strPostcode"
f(5) = "strTel"
f(6) = "strMobile"
f(7) = "strEmail"
f(8) = "strVoucherCode"
f(9) = "strAddif"
f(10) = "strModel"
f(11) = "strSerialNo"
f(12) = "strName"
f(13) = "strStreet"
f(14) = "strNr"
f(15) = "strPostcode2"
f(16) = "strGasSafe"
f(17) = "strIsadv"
f(18) = "strTC"
f(19) = "strInstallationDate"
iFile = FreeFile
Open strFileName For Input As #iFile
Line Input #iFile, strTextLine
While Not EOF(iFile)
'check for blank line and skip if blank
If Not (Trim(strTextLine) = "") Then
If InStr(strTextLine, "vaillantthinksahead") Then
'this one has different format
bolVaillant = True
ReDim s(18)
ReDim f(18)
s(0) = "Full Name:"
s(1) = "Address:"
s(2) = "City:"
s(3) = "Postcode:"
s(4) = "Address:"
s(5) = "City:"
s(6) = "Postcode:"
s(7) = "Email:"
s(8) = "Phone:"
s(9) = "Mobile:"
s(10) = "Name:"
s(11) = "Address:"
s(12) = "Postcode:"
s(13) = "Gas Safe Number:"
s(14) = "Is Advance:"
s(15) = "Serial Number:"
s(16) = "Installation Date:"
s(17) = "Model:"
s(18) = "Voucher Code:"
f(0) = "strFullName"
f(1) = "strStreetNr"
f(2) = "strCity"
f(3) = "strPostcode"
f(4) = "strCorrespondenceAddress"
f(5) = "strCorrespondenceCity"
f(6) = "strCorrespondencePostCode"
f(7) = "strCorrespondenceEmail"
f(8) = "strCorrespondencePhone"
f(9) = "strCorrespondenceMobile"
f(10) = "strName"
f(11) = "strStreet"
f(12) = "strPostcode2"
f(13) = "strGasSafe"
f(14) = "strIsadv"
f(15) = "strSerialNo"
f(16) = "strInstallationDate"
f(17) = "strModel"
f(18) = "strVoucherCode"
End If
If (bolVaillant) Then
For i = LBound(s) To UBound(s)
DoEvents
lngPos = InStr(strTextLine, s(i))
If lngPos > 0 Then
If Not bolAdd Then
bolAdd = True
rs.AddNew
End If
Select Case i
Case 1, 4, 11
' three field for Address
bytAddress = bytAddress + 1
j = Switch(bytAddress = 1, 1, bytAddress = 2, 4, bytAddress = 3, 11)
Call rsUpdate(f(j), strTextLine, s(j))
'Select Case bytAddress
' Case 1
' Call rsUpdate(f(1), strTextLine, s(1))
' Case 2
' Call rsUpdate(f(4), strTextLine, s(4))
' Case Else
' Call rsUpdate(f(11), strTextLine, s(11))
'End Select
Case 2, 5
' two fields for City
bytCity = bytCity + 1
j = Switch(bytCity = 1, 2, bytCity = 2, 5)
Call rsUpdate(f(j), strTextLine, s(j))
'Select Case bytCity
' Case 1
' Call rsUpdate(f(2), strTextLine, s(2))
' Case Else
' Call rsUpdate(f(5), strTextLine, s(5))
'End Select
Case 3, 6, 12
' three fields for Postcode
bytPostCode = bytPostCode + 1
j = Switch(bytPostCode = 1, 3, bytPostCode = 2, 6, bytPostCode = 3, 12)
Call rsUpdate(f(j), strTextLine, s(j))
'Select Case bytPostCode
' Case 1
' Call rsUpdate(f(3), strTextLine, s(3))
' Case 2
' Call rsUpdate(f(6), strTextLine, s(6))
' Case Else
' Call rsUpdate(f(12), strTextLine, s(12))
'End Select
Case Else
Call rsUpdate(f(i), strTextLine, s(i))
End Select
Exit For
End If
Next i
Else
For i = LBound(s) To UBound(s)
DoEvents
lngPos = InStr(strTextLine, s(i))
' test if search string in our text variable
If lngPos <> 0 Then
' found, then create new recod to our table
If Not bolAdd Then
bolAdd = True
rs.AddNew
End If
' check if postal code is being processed
Select Case i
Case 4, 15
' two fields for Postcode
bytPostCode = bytPostCode + 1
j = Switch(bytPostCode = 1, 4, bytPostCode = 2, 15)
Call rsUpdate(f(j), strTextLine, s(j))
'Select Case bytPostCode
' Case 1
' Call rsUpdate(f(4), strTextLine, s(4))
' Case Else
' Call rsUpdate(f(15), strTextLine, s(15))
'End Select
Case 11
' remove DD-MM-YYYY from our text line
lngPos = InStr(strTextLine, "DD-MM-YYYY")
If lngPos > 0 Then strTextLine = Left(strTextLine, lngPos - 1)
Call rsUpdate(f(11), strTextLine, s(11))
Case Else
Call rsUpdate(f(i), strTextLine, s(i))
End Select
Exit For
End If
Next
End If
End If
Line Input #iFile, strTextLine
Wend
If bolAdd Then rs.Update
' close text file
Close #iFile
' remove array from memory
Erase s
Erase f
End Sub
Private Sub rsUpdate(ByVal strFieldName As String, _
ByVal strTextLine As String, ByVal strTextToBeReplaced As String)
' remove our search string from this text and
' remove all leading and trailing space from text
strTextLine = RTrim(LTrim(Replace(strTextLine, strTextToBeReplaced, "")))
' update field with our text
'
' note:
'
' table's field size must be big enough (255 char) to hold variable
' length strings.
' i have access complaining when saving this record, saying
' that that the text i am saving cannot fit on the field!
' i don't want to truncate it as we may loose some text.
'
' but if you really want to fit the text to the size of your field (losing some text)
' just uncomment the line below and comment out
' the second line in the code
' rs.Fields(strFieldName).Value = Left(strTextLine, rs.Fields(strFieldName).Size)
rs.Fields(strFieldName).Value = "" & strTextLine
DoEvents
End Sub
Public Sub subSaveStream(ByRef fso As Scripting.FileSystemObject, ByVal sFileName As String, ByVal sText As String)
Dim TxtStream As Scripting.TextStream
Set TxtStream = fso.CreateTextFile(sFileName, True)
With TxtStream
.Write sText
.Close
End With
Set TxtStream = Nothing
End Sub