Loop through subfolders by name - vba

The folder path is "Mailbox - IT Support Center"\"Onshore - Josh"\"Completed".
I want to know the total number of emails in each person's completed mailbox from yesterday.
There are about 25 mailboxes but they all follow the same path starting at Mailbox - IT Support Center.
The script works except for the loop. It iterates through to the second folder but it still searches the first mailbox. Most likely something wrong with objfolder.
Sub CompletedEmailCount()
Dim objOutlook As Object, objnSpace As Object, objFolder As MAPIFolder
Dim MailItem
Dim EmailCount As Integer
Dim strFolderName
Dim FolderName() As Variant
Dim i As Integer
Dim objFolder1
Set objOutlook = CreateObject("Outlook.Application")
Set objnSpace = objOutlook.GetNamespace("MAPI")
Set objFolder = objnSpace.GetDefaultFolder(olFolderInbox)
strFolderName = ("Mailbox - IT Support Center")
ReDim FolderName(3) 'change this to how many folders you have
'assign each folder name on the array elements
FolderName(1) = ("Onshore - Josh")
FolderName(2) = ("OnShore - Ashton")
FolderName(3) = ("OnShore - Beth")
'loop through each foldername
For i = 1 To 3
On Error Resume
Next
Set objFolder = objnSpace.Folders(strFolderName).Folders(FolderName(i)).Folders ("completed")
On Error GoTo 0
If objFolder Is Nothing Then GoTo skip
For Each MailItem In objFolder.Items
If DatePart("d", Date - 1) = DatePart("d", MailItem.ReceivedTime) Then EmailCount = EmailCount + 1
Next
skip:
Next
MsgBox "Completed Email Totals from Yesterday: " & EmailCount
End Sub

Found this out through trial and error, but returns what I need.
Sub Tester()
'Dim objOutlook As Object, objnSpace As Object, objFolder As MAPIFolder
Dim MailItem
Dim EmailCount() As Integer, arrNames
Dim completed, x As Long, num As Long
Dim DayTotal
Set objOutlook = CreateObject("Outlook.Application")
Set objnSpace = objOutlook.GetNamespace("MAPI")
arrNames = Array("Ashton", "Beth", "Bree", "Brittany", "Cecilia", "Chance", "Christina", "Christine", "Dustin", "James", "Jeff", "Jenni", "Jennifer", "Jeromy", "Josh", "Josie", "Lisa", "Misti", "Nathan", "Paul", "Robert", "Sam", "Shane", "Shawna") 'add other names here...
ReDim EmailCount(LBound(arrNames) To UBound(arrNames))
For x = LBound(arrNames) To UBound(arrNames)
On Error Resume Next
Set objFolder = objnSpace.Folders("Mailbox - IT Support Center"). _
Folders("Onshore - " & arrNames(x)).Folders("completed")
On Error GoTo 0
num1 = 0
num2 = 0
num3 = 0
num4 = 0
num5 = 0
num6 = 0
num7 = 0
Dim Totalmsg
If Not objFolder Is Nothing Then
For Each MailItem In objFolder.Items
If DateValue(Date - 1) = _
DateValue(MailItem.ReceivedTime) Then num1 = num1 + 1
If DateValue(Date - 2) = _
DateValue(MailItem.ReceivedTime) Then num2 = num2 + 1
If DateValue(Date - 3) = _
DateValue(MailItem.ReceivedTime) Then num3 = num3 + 1
If DateValue(Date - 4) = _
DateValue(MailItem.ReceivedTime) Then num4 = num4 + 1
If DateValue(Date - 5) = _
DateValue(MailItem.ReceivedTime) Then num5 = num5 + 1
If DateValue(Date - 6) = _
DateValue(MailItem.ReceivedTime) Then num6 = num6 + 1
If DateValue(Date - 7) = _
DateValue(MailItem.ReceivedTime) Then num7 = num7 + 1
Next
Dim DayTotal1 As String
Dim DayTotal2 As String
Dim DayTotal3 As String
Dim DayTotal4 As String
Dim DayTotal5 As String
Dim DayTotal6 As String
Dim DayTotal7 As String
DayTotal1 = arrNames(x) & " " & (Date - 1) & " " & num1
DayTotal2 = arrNames(x) & " " & (Date - 2) & " " & num2
DayTotal3 = arrNames(x) & " " & (Date - 3) & " " & num3
DayTotal4 = arrNames(x) & " " & (Date - 4) & " " & num4
DayTotal5 = arrNames(x) & " " & (Date - 5) & " " & num5
DayTotal6 = arrNames(x) & " " & (Date - 6) & " " & num6
DayTotal7 = arrNames(x) & " " & (Date - 7) & " " & num7
DayTotal = DayTotal1 & vbNewLine _
& DayTotal2 & vbNewLine _
& DayTotal3 & vbNewLine _
& DayTotal4 & vbNewLine _
& DayTotal5 & vbNewLine _
& DayTotal6 & vbNewLine _
& DayTotal7 & vbNewLine _
DayTotals = DayTotals & DayTotal
msg = arrNames(x) & " " & (Date - 1) & " " & num1 & vbNewLine _
& arrNames(x) & " " & (Date - 2) & " " & num2 & vbNewLine _
& arrNames(x) & " " & (Date - 3) & " " & num3 & vbNewLine _
& arrNames(x) & " " & (Date - 4) & " " & num4 & vbNewLine _
& arrNames(x) & " " & (Date - 5) & " " & num5 & vbNewLine _
& arrNames(x) & " " & (Date - 6) & " " & num6 & vbNewLine _
& arrNames(x) & " " & (Date - 7) & " " & num7
' Totalmsg = msg
End If
Debug.Print arrNames(x), num
Next x
MsgBox DayTotals
Set OutApp = CreateObject("outlook.Application")
Set OutMail = OutApp.CreateItem(o)
With OutMail
.Subject = "Total Completed Tickets"
.To = "plotnerj#schneider.com"
.Body = DayTotals
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
Set objFolder = Nothing
Set objnSpace = Nothing
Set objOutlook = Nothing
End Sub

Related

Updating SQL Table via VBA cuts off decimals

I need to update a set of values from an Excel Worksheet into a SQL Server Table.
This is the Excel Table:
I wrote some code in VBA to do this, but I'm not very expert.
The update work just fine except for the part where it truncate decimals.
As you can see the decimals get cuts off. The fields on SQL are declared as Decimal (19,5).
Sure there's something wrong in the VBA code. Here's my code.
On Error GoTo RigaErrore
Dim cn_ADO As Object
Dim cmd_ADO As Object
Dim SQLUser As String
Dim SQLPassword As String
Dim SQLServer As String
Dim DBName As String
Dim DBConn As String
Dim SQLQuery As String
Dim strWhere As String
Dim i As Integer
Dim jOffset As Integer
Dim iStartRow As Integer
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'iStep = 100
jOffset = 20
iStartRow = 3
i = iStartRow
SQLUser = "xxxx"
SQLPassword = "xxx"
SQLServer = "xxxxxxxx"
DBName = "xxxxx"
DBConn = "Provider=SQLOLEDB.1;Pesist Security Info=True;User ID=" & SQLUser & ";Password=" & SQLPassword & ";Initial Catalog=" & DBName & ";" & _
"Data Source=" & SQLServer & ";DataTypeCompatibility=80;"
Set cn_ADO = CreateObject("ADODB.Connection")
cn_ADO.Open DBConn
Set cmd_ADO = CreateObject("ADODB.Command")
While Cells(i, jOffset).Value <> ""
xlsIDKey = Cells(i, 0 + jOffset)
xlsVendSim = CDbl(Cells(i, 1 + jOffset))
xlsOreSim = CDbl(Cells(i, 2 + jOffset))
xlsProdVar = CDbl(Cells(i, 3 + jOffset))
xlsOreSimVar = CDbl(Cells(i, 4 + jOffset))
strWhere = "ID_KEY = '" & xlsIDKey & "'"
SQLQuery = "UPDATE DatiSimulati " & _
"SET " & _
"VEND_SIM = Cast(('" & xlsVendSim & "') as decimal (19,5)), " & _
"ORE_SIM = Cast(('" & xlsOreSim & "') as decimal (19,5)), " & _
"PROD_VAR = Cast(('" & xlsProdVar & "') as decimal (19,5)), " & _
"ORE_SIM_VAR = Cast(('" & xlsOreSimVar & "') as decimal (19,5)) " & _
"WHERE " & strWhere
cmd_ADO.CommandText = SQLQuery
cmd_ADO.ActiveConnection = cn_ADO
cmd_ADO.Execute
i = i + 1
Wend
Set cmd_ADO = Nothing
Set cn_ADO = Nothing
Exit Sub
RigaErrore:
MsgBox Err.Number & vbNewLine & Err.Description
Application.StatusBar = False
Application.Cursor = xlDefault
If Not cn_ADO Is Nothing Then
Set cn_ADO = Nothing
End If
If Not cmd_ADO Is Nothing Then
Set cmd_ADO = Nothing
End If
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Thanks everybody who could help solve this.
A work-around would be to replace the decimal commas with dots.
Option Explicit
Sub connectDB()
Const SQLUser = "#"
Const SQLPassword = "#"
Const SQLServer = "#"
Const DBName = "#"
Dim DBConn As String
DBConn = "Provider=SQLOLEDB.1;Pesist Security Info=True" & _
";User ID=" & SQLUser & ";Password=" & SQLPassword & _
";Initial Catalog=" & DBName & _
";Data Source=" & SQLServer & _
";DataTypeCompatibility=80;"
Dim cn_ADO As Object, cmd_ADO As Object
Set cn_ADO = CreateObject("ADODB.Connection")
cn_ADO.Open DBConn
Set cmd_ADO = CreateObject("ADODB.Command")
cmd_ADO.ActiveConnection = cn_ADO
Const joffset = 20
Const iStartRow = 3
Dim SQLQuery As String, sIDKey As String
Dim sVendSim As String, sOreSim As String
Dim sProdVar As String, sOreSimVar As String
Dim i As Long
i = iStartRow
' create log file
Dim LOGFILE As String
LOGFILE = ThisWorkbook.Path & "\logfile.txt"
Dim fs As Object, ts As Object
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.CreateTextFile(LOGFILE, True)
While Len(Cells(i, joffset).Value) > 0
sIDKey = Cells(i, 0 + joffset)
sVendSim = Replace(Cells(i, 1 + joffset), ",", ".")
sOreSim = Replace(Cells(i, 2 + joffset), ",", ".")
sProdVar = Replace(Cells(i, 3 + joffset), ",", ".")
sOreSimVar = Replace(Cells(i, 4 + joffset), ",", ".")
SQLQuery = "UPDATE DatiSimulati " & _
"SET " & _
"VEND_SIM = " & sVendSim & ", " & _
"ORE_SIM = " & sOreSim & ", " & _
"PROD_VAR = " & sProdVar & ", " & _
"ORE_SIM_VAR = " & sOreSimVar & " " & _
"WHERE ID_KEY = " & sIDKey
ts.writeline SQLQuery & vbCr
cmd_ADO.CommandText = SQLQuery
cmd_ADO.Execute
i = i + 1
Wend
ts.Close
MsgBox i - iStartRow & " records updated see " & LOGFILE, vbInformation
End Sub

Select new Email by Subject and Date Range

I developed a macro to save attached files from selected emails with a subject depending on the body.
I would like to make the macro select the emails instead of doing it manually.
Goal: Select emails depending on their subject and an specific date range.
Filter mails received in a specified date range which corresponds with subject "Ordenes" and come from "ordenes#ordenes.com". This must be done without reading every single email on the inbox folder as I do not have the option of moving historical ones to another folder (shared email).
Select the mails that match the previous step and then call a macro called "SaveAttachements".
I've been checking Items.Restrict, Items.Find, Explorer.Selection, Explorer.AddToSelection but I don't seem to be getting the right concept.
You can filter (select) emails with .Restrict, which allows multiple conditions.
Option Explicit
Private Sub restrict_SenderEmailAddress_Subject_DateRangeRecent()
Dim itms As Items
Dim resItms As Items
Dim itm As Object
Dim srchSenderEmailAddress As String
Dim srchSubject As String
Dim dateRangeDays As Long
Dim srchDatePeriod As String
Dim strFilterBuild As String
Dim resItmsBuild As Items
Dim strFilter As String
Dim i As Long
Set itms = Session.GetDefaultFolder(olFolderInbox).Items
'For i = 1 To itms.Count
' Debug.Print itms(i).SenderEmailAddress
'Next
srchSenderEmailAddress = "ordenes#ordenes.com"
' If you cannot get the quotes right all at once, build the filter.
strFilterBuild = "[SenderEmailAddress] = '" & srchSenderEmailAddress & "'"
Debug.Print strFilterBuild
Set resItmsBuild = itms.Restrict(strFilterBuild)
If resItmsBuild.Count = 0 Then
Debug.Print "No " & srchSenderEmailAddress & " email."
'MsgBox "No " & srchSenderEmailAddress & " email."
Exit Sub
End If
srchSubject = "Ordenes"
strFilterBuild = strFilterBuild & " And [Subject] = '" & srchSubject & "'"
Debug.Print strFilterBuild
Set resItmsBuild = itms.Restrict(strFilterBuild)
If resItmsBuild.Count = 0 Then
Debug.Print "No " & srchSenderEmailAddress & " email with subject " & srchSubject
'MsgBox "No " & srchSenderEmailAddress & " email with subject " & srchSubject
Exit Sub
End If
' adjust as needed
dateRangeDays = 1400
srchDatePeriod = Format(Date - dateRangeDays, "yyyy-mm-dd")
'Debug.Print srchDatePeriod
strFilterBuild = strFilterBuild & " And [ReceivedTime] > '" & srchDatePeriod & "'"
Debug.Print strFilterBuild
Set resItmsBuild = itms.Restrict(strFilterBuild)
resItmsBuild.sort "[ReceivedTime]", True
If resItmsBuild.Count = 0 Then
Debug.Print "No " & srchSenderEmailAddress & " email with subject " & srchSubject & " in the last " & dateRangeDays & " days."
'MsgBox "No " & srchSenderEmailAddress & " email with subject " & srchSubject & " in the last " & datePeriodDays & " days."
Exit Sub
End If
' This should match the final strFilterBuild to confirm it can be done all at once.
strFilter = "[SenderEmailAddress] = '" & srchSenderEmailAddress & "' And [Subject] = '" & srchSubject & "' And [ReceivedTime] > '" & srchDatePeriod & "'"
Debug.Print strFilter
Set resItms = itms.Restrict(strFilter)
resItms.sort "[ReceivedTime]", True
If resItms.Count = 0 Then
MsgBox "No " & srchSubject & " email on " & srchDatePeriod
End If
For i = 1 To resItms.Count
Debug.Print resItms(i).ReceivedTime & ": " & resItms(i).Subject
'SaveAttachments resItms(i)
Next
End Sub

Optimizing loop through Access Database

I need help with an massive loop through a continously expanding Access database consisting of approximately 280.000 rows of data. The procedure adds 3000 rows of data every week, and the macros running time is therefore only increasing. It takes around one hour to complete.
What is the optimal way to complete my procedure? I'm experienced with VBA, but SQL knowledge is limited.
The issue summarized is that the If-statement, located in "Help needed here" runs through 280.000 rows of data for 3000 companies.
The goal is that the fresh weekly scores of the company will be scored in JQHistory, but it has to take the date of running the macro into consideration
Note: Everything outside of "Help needed here", I've optimized in another macro. I've left it to hopefully improve the context of the issue.
Here is the non-optimized macro:
Sub OpdaterKvant()
Dim wb As Workbook
Dim ws As Worksheet
Dim DatoIn As Date
Set db = New ADODB.Connection
Set DbEQ = New ADODB.Connection
'The location of the database is determined outside the macro'
strConn = ConnectionString
db.Open strConn
Set wb = Workbooks.Open("My File Location")
Set ws = wb.Worksheets(1)
n = ws.UsedRange.Rows.Count
DateIn = Right(ws.Cells(1, 1), 2) & "-" & Mid(ws.Cells(1, 1), 5, 2) & "-" & Left(ws.Cells(1, 1), 4)
Dato = Format(DateIn, "mm-dd-yyyy")
db.Execute ("DELETE * FROM JQScores")
For i = 3 To n
Sedol = Replace(ws.Cells(i, 1), " ", "")
Company = Left(Replace(ws.Cells(i, 2), "'", ""), Len(Replace(ws.Cells(i, 2), "'", "")) - 1)
Country = Replace(ws.Cells(i, 3), " ", "")
Region = Replace(ws.Cells(i, 4), " ", "")
Sector = Replace(ws.Cells(i, 5), " ", "")
MarketCap = Replace(Replace(ws.Cells(i, 6), " ", ""), ",", ".")
JQRank = Replace(ws.Cells(i, 7), " ", "")
ValueRank = Replace(ws.Cells(i, 8), " ", "")
QualityRank = Replace(ws.Cells(i, 9), " ", "")
MomentumRank = Replace(ws.Cells(i, 10), " ", "")
JQScore = Replace(Replace(ws.Cells(i, 11), " ", ""), ",", ".")
'Inserts the information into the Access database.'
Sql = "Insert into JQScores (Sedol, Company, Region, Sector, MarketCapUSD, JQ_Rank, Value_Rank, Quality_Rank, Momentum_Rank, JQ_Score, Country) VALUES ('" & Sedol & "','" & Company & "', '" & Region & "', '" & Sector & "', " & MarketCap & ", '" & JQRank & "', '" & ValueRank & "', '" & QualityRank & "', '" & MomentumRank & "', " & JQScore & ", '" & Country & "')"
db.Execute (Sql)
'*** HELP NEEDED IN THIS SECTION'
If db.Execute("Select Count(Id) as NumId from JQHistory where Sedol='" & Sedol & "' and history_date=#" & Dato & "#")("NumId") = 0 Then
Sql = "Insert into JQHistory (History_date, Sedol, Selskabsnavn, JQScore, JQ_Rank, Value_Rank, Momentum_Rank, Quality_Rank, Marketcap) VALUES (#" & Dato & "#, '" & Sedol & "','" & Company & "'," & JQScore & ", '" & JQRank & "', '" & ValueRank & "', '" & MomentumRank & "', '" & QualityRank & "', " & MarketCap & ")"
db.Execute (Sql)
Else
Sql = "Update JQHistory set MarketCap=" & MarketCap & ", Selskabsnavn='" & Company & "' , JQ_Rank='" & JQRank & "', Value_Rank='" & ValueRank & "', Quality_Rank='" & QualityRank & "', Momentum_Rank='" & MomentumRank & "', JQScore=" & JQScore & " WHERE SEDOL='" & Sedol & "' and History_Date=#" & Dato & "#"
db.Execute (Sql)
End If
'***'
Next i
db.Close
wb.Close
The optimal way ended up using the DAO.Recordset and DAO.Database options, and a lot of tweaks for optimization.
The biggest shortcut was using the 'Recordset.FindFirst' to identify if the data should only be added (takes 22 seconds), or update the data with identical date (takes 12 minutes). Although mainly the scenario taking 22 seconds will happen.
The scenario taking 12 minutes is not optimized since it rarely happens.
Full solution:
Sub OpdaterKvant()
Dim wb As Workbook
Dim wbOp As Workbook
Dim ws As Worksheet
Dim wsOp As Worksheet
Dim i, n As Integer
Dim db As DAO.Database
Dim rsScores As DAO.Recordset
Dim rsHistory As DAO.Recordset
StartTime = Timer
Call PERFORMANCEBOOST(False)
Set PB = CREATEPROGRESSBAR
With PB
.SetStepCount (4)
.Show
End With
Set wbOp = ThisWorkbook
Set wsOp = wbOp.ActiveSheet
'Step 1: Open JQGCLE
Set wb = Workbooks.Open("Location", ReadOnly:=True)
Set ws = wb.Worksheets(1)
ws.Activate
n = ws.UsedRange.Rows.Count
DateIn = Right(ws.Cells(1, 1), 2) & "-" & Mid(ws.Cells(1, 1), 5, 2) & "-" & Left(ws.Cells(1, 1), 4)
'Step 2: Optag værdier i Excel
PB.Update "Data hentes fra JQGLCE-ark"
ReDim Sedol(3 To n) As String
ReDim Company(3 To n) As String
ReDim Country(3 To n) As String
ReDim Region(3 To n) As String
ReDim Sector(3 To n) As String
ReDim MarketCap(3 To n) As String 'Tal
ReDim MarketCapSQL(3 To n) As String 'Tal
ReDim JQRank(3 To n) As String
ReDim ValueRank(3 To n) As String
ReDim QualityRank(3 To n) As String
ReDim MomentumRank(3 To n) As String
ReDim JQScore(3 To n) As String 'Tal
ReDim JQScoreSQL(3 To n) As String 'Tal
For i = 3 To n
Sedol(i) = Trim(ws.Cells(i, 1))
Company(i) = Left(Replace(ws.Cells(i, 2), "'", ""), Len(Replace(ws.Cells(i, 2), "'", "")) - 0) 'Stod tidligere på minus 1 - Hvorfor?
Country(i) = Trim(ws.Cells(i, 3))
Region(i) = Trim(ws.Cells(i, 4))
Sector(i) = Trim(ws.Cells(i, 5))
MarketCap(i) = ws.Cells(i, 6) 'Til DAO
MarketCapSQL(i) = Replace(ws.Cells(i, 6), ",", ".") 'Til SQL
JQRank(i) = Trim(ws.Cells(i, 7))
ValueRank(i) = Trim(ws.Cells(i, 8))
QualityRank(i) = Trim(ws.Cells(i, 9))
MomentumRank(i) = Trim(ws.Cells(i, 10))
JQScore(i) = ws.Cells(i, 11) 'Til DAO
JQScoreSQL(i) = Replace(ws.Cells(i, 11), ",", ".") 'Til SQL
'DAO og SQL bliver behandlet forskelligt ift. komma
Next i
'Step 3: Indsæt værdier i Access-database
Set acc = New Access.Application
Set db = acc.DBEngine.OpenDatabase("Location", 1, 0)
'Step 3.1: JQScores
PB.Update "JQScores indsættes i databasen"
Set rsScores = db.OpenRecordset(Name:="JQScores", Type:=RecordsetTypeEnum.dbOpenDynaset)
db.Execute "DELETE * FROM JQScores"
For i = 3 To n
With rsScores
.AddNew
!Sedol = Sedol(i)
!Company = Company(i)
!Region = Region(i)
!Sector = Sector(i)
!MarketCapUSD = MarketCap(i)
!JQ_Rank = JQRank(i)
!Value_Rank = ValueRank(i)
!Quality_Rank = QualityRank(i)
!Momentum_Rank = MomentumRank(i)
!JQ_Score = JQScore(i)
!Country = Country(i)
.Update
End With
Next i
rsScores.Close
Set rsScores = Nothing
'Step 3.2: JQHistory
Set rsHistory = db.OpenRecordset(Name:="JQHistory", Type:=RecordsetTypeEnum.dbOpenDynaset)
With rsHistory
If .RecordCount <> 0 Then
i = 3
.FindFirst "History_Date = '" & DateIn & "'"
If .NoMatch = True Then
'Hvis datoen ikke er i datasættet, bliver dataen tilføjet
PB.Update "Hurtig: JQHistory indsættes i databasen"
For i = 3 To n
.AddNew
!History_Date = DateIn
!Sedol = Sedol(i)
!Selskabsnavn = Company(i)
!MarketCap = MarketCap(i)
!JQ_Rank = JQRank(i)
!Value_Rank = ValueRank(i)
!Quality_Rank = QualityRank(i)
!Momentum_Rank = MomentumRank(i)
!JQScore = JQScore(i)
.Update
Next i
Else
'Hvis datoen allerede er der, skal den opdateres
PB.Update "Langsom: JQHistory indsættes i databasen"
For i = 3 To n
db.Execute ("UPDATE JQHistory SET MarketCap=" & MarketCapSQL(i) & ", Selskabsnavn='" & Company(i) & "', JQ_Rank='" & JQRank(i) & "', Value_Rank='" & ValueRank(i) & "', Quality_Rank='" & QualityRank(i) & "', Momentum_Rank='" & MomentumRank(i) & "', JQScore=" & JQScoreSQL(i) & " WHERE SEDOL='" & Sedol(i) & "' and History_Date='" & DateIn & "'")
Next i
End If
End If
End With
rsHistory.Close
Set rsHistory = Nothing
'Step 4: Færdiggørelse
acc.DoCmd.Quit acQuitSaveAll 'Lukker og gemmer database
Set db = Nothing
wsOp.Activate
wsOp.Range("B7").Value = "Seneste data benyttet: " & DateIn
wb.Close SaveChanges:=False
Call PERFORMANCEBOOST(True)
Unload PB
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "Opdatering fuldført. Proceduren tog " & MinutesElapsed & "."
End Sub

Search for Outlook Email based on Sender, Subject, and Today's Date

I am supposed to receive an email with the subject "Testing Protocol" from "BobSmith#company.com" every day.
Is there a way to search my Outlook Inbox to determine if an email has come through with that subject and that sender for the current day? Id like a simple "Yes" or "No" to be placed in cell A1 of "Control" if it has or has not been received today.
Below is what I have tried to come up with on my own using previous questions with no luck.
Any help is greatly appreciated. EmailSubject = "Testing Protocol"
Private Sub Application_Reminder(ByVal Item As Object)
Dim EmailSubject As Range
Set EmailSubject = Sheets("Control").Range("EmailSubject")
If Item.Class = olTask Then
If InStr(Item.Subject, EmailSubject) > 0 Then
ReminderUnreceivedMail
End If
End If
End Sub
Sub ReminderUnreceivedMail()
Dim Itms As Items
Dim srchSender As String
Dim srchSubject As String
Set Itms = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
srchSender = "BobSmith#company.com"
srchSubject = EmailSubject
Set Itms = Itms.Restrict("[SenderName] = "BobSmith#company.com" And
[Subject] = EmailSubject And [SentOn] > '" & Format(Date, "yyyy-mm-dd") &
"'")
If Itms.Count = 0 Then
MsgBox "No " & srchSubject & " email on " & Format(Date, "yyyy-mm-dd")
End If
Set Itms = Nothing
End Sub
Likely wrong format for srchSender and combining a filter, for me, requires a confusing sequence of matching quotes.
Private Sub ReminderUnreceivedMail()
Dim Itms As items
Dim srchSender As String
Dim srchSubject As String
Dim strFilterBuild As String
Dim ItmsBuild As items
Dim strFilter As String
Set Itms = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).items
Dim i As Long
For i = 1 To Itms.count
Debug.Print Itms(i).senderName
Next
srchSender = "what you see in senderName from the above"
srchSubject = "EmailSubject"
' If you cannot get the quotes right all at once, build the filter.
strFilterBuild = "[SenderName] = '" & srchSender & "'"
Debug.Print strFilterBuild
Set ItmsBuild = Itms.Restrict(strFilterBuild)
If ItmsBuild.count = 0 Then
MsgBox "No " & srchSender & " email."
GoTo ExitRoutine
End If
strFilterBuild = strFilterBuild & " And [Subject] = '" & srchSubject & "'"
Debug.Print strFilterBuild
Set ItmsBuild = Itms.Restrict(strFilterBuild)
If ItmsBuild.count = 0 Then
' This should find old mail
MsgBox "No " & srchSender & " email with subject " & srchSubject
GoTo ExitRoutine
End If
strFilterBuild = strFilterBuild & " And [SentOn] > '" & Format(Date, "yyyy-mm-dd") & "'"
Debug.Print strFilterBuild
Set ItmsBuild = Itms.Restrict(strFilterBuild)
If ItmsBuild.count = 0 Then
MsgBox "No " & srchSender & " email with subject " & srchSubject & " today"
GoTo ExitRoutine
End If
' This should match the final strFilterBuild to confirm it can be done all at once.
strFilter = "[SenderName] = '" & srchSender & "' And [Subject] = '" & srchSubject & "' And [SentOn] > '" & Format(Date, "yyyy-mm-dd") & "'"
Debug.Print strFilter
Set Itms = Itms.Restrict(strFilter)
If Itms.count = 0 Then
MsgBox "No " & srchSubject & " email on " & Format(Date, "yyyy-mm-dd")
End If
ExitRoutine:
Set Itms = Nothing
End Sub

Quotations in Access String from Excel VBA

Ok I am having a Problem using VBA from Excel 2010 to Query data in access, the problem comes when the variable Descripcheck, or Grouplocal, some of the descriptions have a "" in the excel cell so when it pulls the string itself this causes the query function gets a syntax error. Any ideas?
PMnum = Cells(B, 3)
Grouplocal = Cells(B, 4)
Descripcheck = Cells(B, 6)
DevTyp = Cells(B, 5)
TagName = Cells(B, 2)
If PMnum = "" Then
PMnum = " IS NULL"
Else:
PMnum = "=" & PMnum
End If
If Grouplocal = "" Then
Grouplocal = " IS NULL"
Else:
Grouplocal = "=" & Chr$(34) & Grouplocal & Chr$(34)
End If
If Descripcheck = "" Then
Descripcheck = " IS NULL"
Else:
Descripcheck = "=" & Chr$(34) & Descripcheck & Chr$(34)
End If
If DevTyp = "" Then
DevTyp = " IS NULL"
Else:
DevTyp = "=" & Chr$(34) & DevTyp & Chr$(34)
End If
If TagName = "" Then
TagName = " IS NULL"
Else:
TagName = "=" & Chr$(34) & TagName & Chr$(34)
End If
sCmndString = "SELECT Site_Data.Pass_Fail, Site_Data.Tag_Name, Site_Data.[PM_#],Site_Data.Group_Location_Reference, Site_Data.Device_Type, Site_Data.Description, Site_Data.Set_Point, Site_Data.Set_Point_Units, Site_Data.Fail_Low, Site_Data.Fail_High, Site_Data.As_Found, Site_Data.As_Left, Site_Data.Manufacturer_SN, Site_Data.Year_Put_Into_Service, Site_Data.Date_of_Test, Site_Data.Time_To_Complete, Site_Data.Service, Site_Data.Comments, Site_Data.Site, Site_Data.Year, Site_Data.Month " & _
"FROM Site_Data WHERE (((Site_Data.[PM_#])" & PMnum & ") AND " & _
"((Site_Data.Group_Location_Reference)" & Grouplocal & ") AND " & _
"((Site_Data.Device_Type)" & DevTyp & ") AND " & _
"((Site_Data.Description)" & Descripcheck & ") AND " & _
"((Site_Data.Site)=" & Chr$(34) & SiteName & Chr$(34) & ") AND " & _
"((Site_Data.Year)=" & Chr$(34) & yrs & Chr$(34) & ") AND " & _
"((Site_Data.Month)=" & Chr$(34) & Mnth & Chr$(34) & ") AND " & _
"((Site_Data.Tag_Name)" & TagName & "));"
Set rs = New ADODB.Recordset
rs.Open sCmndString, cnt, 2, 3, 1
If you keep fooling around with those "s and Chr$(34)s you'll drive yourself crazy. Try using a parameterized query instead. Consider the following (simplified) example. It uses some test data in Access...
Site_ID Device_Type Description
------- ----------- ------------
1 Type1 test1
2 Type1
3 Type1
4 Type2 "some" value
5 Type2 "some" value
6 Type2
7 Type2
8 Type2
...an Excel sheet that looks like this...
...and the code behind the button is
Option Explicit
Public Sub AccessLookup()
Dim con As ADODB.Connection, cmd As ADODB.Command, rst As ADODB.Recordset
Dim DevTyp As Variant, Descripcheck As Variant
Dim s As String, i As Long
s = Trim(CStr(Range("B1").Value))
DevTyp = IIf(Len(s) = 0, Null, s)
s = Trim(CStr(Range("B2").Value))
Descripcheck = IIf(Len(s) = 0, Null, s)
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Public\Database1.accdb;"
Set cmd = New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandText = _
"SELECT COUNT(*) AS n FROM Site_Data " & _
"WHERE Device_Type " & IIf(IsNull(DevTyp), "IS NULL ", "= ? ") & _
"AND Description " & IIf(IsNull(Descripcheck), "IS NULL ", "= ? ")
i = 0
If Not IsNull(DevTyp) Then
cmd.CreateParameter "?", adVarWChar, adParamInput, 255
cmd.Parameters(i).Value = DevTyp
i = i + 1
End If
If Not IsNull(Descripcheck) Then
cmd.CreateParameter "?", adVarWChar, adParamInput, 255
cmd.Parameters(i).Value = Descripcheck
i = i + 1
End If
Set rst = cmd.Execute
Range("B6").Value = rst("n").Value
rst.Close
Set rst = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub