I have a query that generates a table like this:
Row 1 - ID 1 Peter Parker Task 1 $50
Row 2 - ID 1 Peter Parker Task 2 $55
Row 3 - ID 1 Peter Parker Task 3 $60
Row 4 - ID 2 Mary Jane Task 1 $45
Row 5...
I want to be able to send one email to each person with a list of the tasks and amounts, and the total amount:
Peter Parker
Task 1 $50
Task 2 $55
Task 3 $60
Total $165
I've got a module that sends email, but it requires a single recipient per row. I'm thinking I need another loop, but I'm lost as how to do this.
Here's the code I'm using now:
Sub SendMessages(Optional AttachmentPath)
Dim MyDB As Database
Dim MyRS As Recordset
Dim objOutlook As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Dim objOutlookRecip As Outlook.Recipient
Dim objOutlookAttach As Outlook.Attachments
Dim TheAddress As String
Set MyDB = CurrentDb
Set MyRS = MyDB.OpenRecordset("qry_TeacherPayment - Round 2")
MyRS.MoveFirst
' Create the Outlook session.
Set objOutlook = CreateObject("Outlook.Application")
Do Until MyRS.EOF
'Set loop variables
Dim currentRecord As Integer
Dim oldRecord As Integer
Dim totalAmt As Double
currentRecord = MyRS![ID]
totalAmt = 0
If (currentRecord = MyRS![ID]) Then
' Create the e-mail message.
Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
oldRecord = currentRecord
TheAddress = MyRS![WorkEmail]
With objOutlookMsg
' Add the To recipients to the e-mail message.
Set objOutlookRecip = .Recipients.Add("TheAddress")
objOutlookRecip.Type = olTo
' Set the from address.
objOutlookMsg.SentOnBehalfOfName = "email"
' Set the Subject, the Body, and the Importance of the e-mail message.
.Subject = "Subject"
objOutlookMsg.BodyFormat = olFormatHTML
body text
.HTMLBody = .HTMLBody & "</table></body></html>"
.Importance = olImportanceNormal 'Normal importance
' Resolve the name of each Recipient.
For Each objOutlookRecip In .Recipients
objOutlookRecip.Resolve
If Not objOutlookRecip.Resolve Then
objOutlookMsg.Display
End If
Next
.Send
End With
End If
MyRS.MoveNext
Loop
Set objOutlookMsg = Nothing
Set objOutlook = Nothing
DoCmd.SetWarnings True
End Sub
Here is my final code that works a treat. A huge thanks to maxhugen for putting me on the right path!!
Cheers!
Jason
Sub SendNewPaymentEmail(Optional AttachmentPath)
Dim MyDB As Database
Dim MyRS As Recordset
Dim LastTeacherID As Integer
Dim EmailBody As String
Dim TotalAmount As Double
Dim TheAddress As String
Dim TeacherFirstName As String
Dim FinalTeacherID As Integer
Set MyDB = CurrentDb
Set MyRS = MyDB.OpenRecordset("qry_TeacherPayment - Round 2")
MyRS.MoveFirst
LastTeacherID = MyRS![ID]
Do Until MyRS.EOF
If MyRS![ID] = LastTeacherID Then
TheAddress = MyRS![WorkEmail]
TeacherFirstName = MyRS![FirstName]
FinalTeacherID = MyRS![TeacherID]
EmailBody = EmailBody & "<tr><td>" & MyRS![Subject] & " Year " & MyRS![Year] & "</td><td>" & MyRS![TaskName] & "</td><td>$" & MyRS![Teacher Payment] & "</td></tr>"
TotalAmount = TotalAmount + Nz(MyRS![Teacher Payment], 0)
DoCmd.SetWarnings False
DoCmd.RunSQL "Update [tbl_Judging Standards Project round 2] SET [PaymentEmailSent] = -1 WHERE [TeacherID] = " & MyRS![ID] & " AND [TaskIDTRIM] LIKE '" & MyRS![TaskIDTRIM] & "'"
DoCmd.RunSQL "Update [tbl_Judging Standards Project round 2] SET [PaymentEmailSentDate] = Now() WHERE [TeacherID] = " & MyRS![ID] & " AND [TaskIDTRIM] LIKE '" & MyRS![TaskIDTRIM] & "'"
DoCmd.SetWarnings True
Else
Call CreateEmail(EmailBody, TotalAmount, TeacherFirstName)
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO [tbl_Payments]([TeacherID],[PaymentType],[Amount],[Description],[PaymentFormSent],[PaymentFormSentDate]) VALUES(" & FinalTeacherID & ", 'Individual Payment'," & TotalAmount & ",'Judging Standards Project Phases 2 and 3 - Payment for work samples - Round 2', -1, NOW())"
DoCmd.SetWarnings True
'reset variables
EmailBody = ""
TotalAmount = 0
'start again
TheAddress = MyRS![WorkEmail]
TeacherFirstName = MyRS![FirstName]
LastTeacherID = MyRS![ID]
FinalTeacherID = MyRS![TeacherID]
EmailBody = EmailBody & "<tr><td>" & MyRS![Subject] & " Year " & MyRS![Year] & "</td><td>" & MyRS![TaskName] & "</td><td>$" & MyRS![Teacher Payment] & "</td></tr>"
TotalAmount = TotalAmount + Nz(MyRS![Teacher Payment], 0)
DoCmd.SetWarnings False
DoCmd.RunSQL "Update [tbl_Judging Standards Project round 2] SET [PaymentEmailSent] = -1 WHERE [TeacherID] = " & MyRS![ID] & " AND [TaskIDTRIM] LIKE '" & MyRS![TaskIDTRIM] & "'"
DoCmd.RunSQL "Update [tbl_Judging Standards Project round 2] SET [PaymentEmailSentDate] = Now() WHERE [TeacherID] = " & MyRS![ID] & " AND [TaskIDTRIM] LIKE '" & MyRS![TaskIDTRIM] & "'"
DoCmd.SetWarnings True
End If
MyRS.MoveNext
If (MyRS.EOF) Then
Call CreateEmail(EmailBody, TotalAmount, TeacherFirstName)
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO [tbl_Payments]([TeacherID],[PaymentType],[Amount],[Description],[PaymentFormSent],[PaymentFormSentDate]) VALUES(" & FinalTeacherID & ", 'Individual Payment'," & TotalAmount & ",'Judging Standards Project Phases 2 and 3 - Payment for work samples - Round 2', -1, NOW())"
DoCmd.SetWarnings True
End If
Loop
End Sub
Assuming MyRS is returning fields something like PersonID, TaskID, TaskAmt, you need to loop through MyRS and add the Task and Amt to a string variable (eg 'strBody') UNTIL the PersonID changes - at which point you prepare and send the email using objOutlookMsg.
Set MyRS = ...
LastPersonID=MyRS!PersonID
Do Until MyRS.EOF
If MyRS!PersonID=LastPersonID Then
' concatenate to strBody
strBody = strBody & TaskID & " " & TaskAmt
' add Amt to Person's Total
decTotal = decTotal + nz(TaskAmt,0)
Else
' add the Total
strBody = strBody & "Total: " & decTotal
' send email using another function, or GoTo a named line,
' using LastPersonID and strBody
GoTo send_email
' reset the variables
strBody = ""
decTotal = 0
' concatenate to strBody
strBody = strBody & TaskID & " " & TaskAmt & "<br/>"
' add Amt to Person's Total
decTotal = decTotal + nz(TaskAmt,0)
End If
MyRS.MoveNext
Loop
Related
I tested my code with static value
Set rs = CurrentDb.OpenRecordset("SELECT mail FROM UsersData WHERE depid = 2")
and it worked, but when I use the full statement
Set rs = CurrentDb.OpenRecordset( _
"SELECT mail FROM UsersData WHERE depid IN (SELECT depid FROM CyclesDefinitions WHERE cycledefid = " _
& Me.Combo135.Value & " AND rank = " & Me.Combo202.Value) & ")"
it generates an error i don't know what it means
(Compile Error: Type mismatch) and then nothing happens.
full code below: (everything works as intended and tested, but this line)
Private Sub Command15_Click()
Dim dbs As Database
Dim qdf As QueryDef
Set dbs = CurrentDb
Dim StrSqls As String
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT mail FROM UsersData WHERE depid IN (SELECT depid FROM CyclesDefinitions WHERE cycledefid = " & Me.Combo135.Value & " AND rank = " & Me.Combo202.Value) & ")"
'Set rs = CurrentDb.OpenRecordset("SELECT mail FROM UsersData WHERE depid = 2")
Dim ToMails As String
'Check is a flag on form to make sure record is not inserted more than once in Cycles Table
If Me.Check137.Value = False Then
DoCmd.RunCommand acCmdSaveRecord
dbs.Execute "INSERT INTO Cycles (scinvid, cycledefid) VALUES (" & Me.Combo200.Value & ", " & Me.Combo135.Value & ");"
dbs.Close
Me.Check137.Value = True
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst 'Unnecessary in this case, but still a good habit
Do Until rs.EOF = True
ToMails = rs(0) & ";" & ToMails
rs.MoveNext
Loop
Else
MsgBox "There are no Emails recorded for such department"
End If
rs.Close 'Close the recordset
Debug.Print ToMails
Set rs = Nothing 'Clean up
DoCmd.SendObject acSendNoObject, , , ToMails, , , "Test Subject", "Test Message", True
'objRecordset.Open ("SELECT depid FROM CyclesDefinitions WHERE cycledefid =" & Me.Combo135.Value & " AND cycleranktracking =" & Me.Combo202.Value)
'UserDepartmentID = DLookup("depid", "UsersData", "[username]= '" & fOSUserName & "'")
DoCmd.GoToRecord , , acNewRec
Me.Combo83.Requery
Combo83.RowSource = "SCINVSearch"
ElseIf Me.Check137.Value = True Then
DoCmd.GoToRecord , , acNewRec
Me.Combo83.Requery
Combo83.RowSource = "SCINVSearch"
End If
End Sub
In
Set rs = CurrentDb.OpenRecordset( _
"SELECT mail FROM UsersData WHERE depid IN (SELECT depid FROM CyclesDefinitions WHERE cycledefid = " _
& Me.Combo135.Value & " AND rank = " & Me.Combo202.Value) & ")"
You have placed the closing brace at the wrong place. It should be
Set rs = CurrentDb.OpenRecordset( _
"SELECT mail FROM UsersData WHERE depid IN (SELECT depid FROM CyclesDefinitions WHERE cycledefid = " _
& Me.Combo135.Value & " AND rank = " & Me.Combo202.Value & ")")
Your version tries to append a ")" to the Recordset instead of the SQL string. This generates the Type mismatch error.
I have a vba that can send out multiple emails to vendors, but I would like to change it so it embeds the query and only sends one email per vendor. Here is what I have so far:
Option Compare Database
Public Sub SendFollowUpEmail()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim emailTo As String
Dim emailSubject As String
Dim emailText As String
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
Dim outlookStarted As Boolean
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If outApp Is Nothing Then
Set outApp = CreateObject("Outlook.Application")
outlookStarted = True
End If
Set db = CurrentDb
strSQL = "SELECT qry002UnmatchedOpenInvoices.kyUnique, qry002UnmatchedOpenInvoices.[Vendor Nbr],qry002UnmatchedOpenInvoices.[Vendor Name], " & _
" qry002UnmatchedOpenInvoices.[Purchasing Document], qry002UnmatchedOpenInvoices.Item,qry002UnmatchedOpenInvoices.[Document Date], " & _
" qry002UnmatchedOpenInvoices.Material, qry002UnmatchedOpenInvoices.[Short Text],qry002UnmatchedOpenInvoices.[Material Group], " & _
" qry002UnmatchedOpenInvoices.[Invoice Sent], qry002UnmatchedOpenInvoices.[Order Quantity],qry002UnmatchedOpenInvoices.[Order Unit], " & _
" qry002UnmatchedOpenInvoices.[Quantity in SKU], qry002UnmatchedOpenInvoices.[Stockkeeping unit],qry002UnmatchedOpenInvoices.[Net price], " & _
" qry002UnmatchedOpenInvoices.Currency, qry002UnmatchedOpenInvoices.[Price Unit],qry002UnmatchedOpenInvoices.[Release status], " & _
" qry002UnmatchedOpenInvoices.[No of Positions], tblVendors.Vendor, tblVendors.Email " & _
" FROM qry002UnmatchedOpenInvoices LEFT JOIN tblVendors ON qry002UnmatchedOpenInvoices.[Vendor Nbr] =tblVendors.[Vendor Number] " & _
" WHERE (((qry002UnmatchedOpenInvoices.Material) Is Null) AND ((qry002UnmatchedOpenInvoices.[Invoice Sent]) Is Null));"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
Do Until rs.EOF
emailTo = Trim(rs.Fields("Email").Value & "; tom.nguyen#flocorp.com;mike.huston#flocorp.com")
emailSubject = "Open Invoices"
emailText = Trim("Please send invoices of the below Purchase Orders:") & vbCrLf
emailText = emailText & _
"PO# " & rs.Fields("[Purchasing Document]").Value
Set outMail = outApp.CreateItem(olMailItem)
outMail.To = emailTo
outMail.Subject = emailSubject
outMail.Body = emailText
outMail.Send
'rs.Edit
'rs("FUP_Date_Sent") = Now()
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
If outlookStarted Then
outApp.Quit
End If
Set outMail = Nothing
Set outApp = Nothing
End Sub
What you need to do is to use two recordsets. The first selects the distinct vendors, and the second selects the invoices for that vendor. Something like:
Sub sSendFollowUpEMail()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsVendor As DAO.Recordset
Dim rsInvoice As DAO.Recordset
Dim objOL As New Outlook.Application
Dim objMail As Outlook.MailItem
Dim strSQL As String
Dim emailTo As String
Dim emailText As String
Set db = CurrentDb
strSQL = "SELECT DISTINCT V.[Vendor Number], V.EMail " _
& " FROM qry002UnmatchedOpenInvoices AS I LEFT JOIN tblVendors AS V ON I.[Vendor Nbr]=V.[Vendor Number] " _
& " WHERE I.Material IS NULL " _
& " AND I.[Invoice Sent] IS NULL;"
Set rsVendor = db.OpenRecordset(strSQL)
If Not (rsVendor.BOF And rsVendor.EOF) Then
Do
strSQL = "SELECT I.[Purchasing Document] " _
& " FROM qry2002UnMatchedOpenInvoices AS I " _
& " WHERE I.Material IS NULL " _
& " AND I.[Invoice Sent] IS NULL " _
& " AND I.[Vendor Nbr]=" & rsVendor("Vendor Number") _
& " ORDER BY I.[Purchasing Document] ASC;"
Set rsInvoice = db.OpenRecordset(strSQL)
If Not (rsInvoice.BOF And rsInvoice.EOF) Then
emailText = "Please pay:"
Do
emailText = emailText & vbCrLf & rsInvoice("Purchasing Document")
rsInvoice.MoveNext
Loop Until rsInvoice.EOF
End If
emailTo = rsVendor!EMail
Set objMail = objOL.CreateItem(olMailItem)
objMail.To = emailTo
objMail.Subject = EmailSubject
objMail.Body = emailText
objMail.Send
rsVendor.MoveNext
Loop Until rsVendor.EOF
End If
sExit:
On Error Resume Next
rsVendor.Close
rsInvoice.Close
Set rsVendor = Nothing
Set rsInvoice = Nothing
Set db = Nothing
Set objMail = Nothing
objOL.Quit
Set objOL = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbcrfl & "sSendFollowUpEMail", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
A few notes.
In your original recordset you were including a whole load of fields that were not used in this procedure, which is not recommended - only get data that you need as this will enhance performance;
Secondly, it appears that you are mixing early and late binding of Outlook;
Finally, I've used aliases for the query/table names in the SQL statements - this makes the SQL more manageable, and also if you need to change one of the original tables/queries it is a lot easier to change the name just once.
Regards,
I'm not a VBA expert. I simply copy from the net and try to utilize in my program. however, below is my codes. I'm trying to calculate a finish date considering offdays, but the issue is sometime the time required is less than one day in that case it is calculating as 1 day. How can I calculate it by hours. Suppose if the startdate is 1-jan-2019 6:00 am and the required time to produce is 6 hours than the finish time should be 1-jan-2019 12:00pm
Public Function AddFinishDate(StartDate As Date, ReqDays As Double, FriOff As Boolean) As Date
Dim rst As Recordset
Dim db As Database
Dim FinishDate As Date
Dim icount As Integer
On Error GoTo errhandlers:
Set db = CurrentDb
Set rst = db.OpenRecordset("tblHoliday", dbOpenSnapshot)
icount = 0
FinishDate = StartDate
Do While icount < ReqDays
FinishDate = FinishDate + 1
If Weekday(FinishDate, vbSaturday) <> 7 Or FriOff = False Then
rst.FindFirst "(HolidayDate)= #" & FinishDate & "#"
If rst.NoMatch Then
icount = icount + 1
End If
End If
Loop
AddFinishDate = FinishDate
exit_errhandlers:
rst.Close
Set rst = Nothing
Set db = Nothing
AddFinishDate = FinishDate
Exit Function
errhandlers:
MsgBox Err.Description, vbExclamation
Resume Next
End Function
Private Sub Command53_Click()
Dim dbs As DAO.Database
Set dbs = CurrentDb()
dbs.Execute "UPDATE BalFitToFabricate " & "SET used = false , startdate ="""",finishdate ="""";"
Me.Refresh
End Sub
Private Sub Command71_Click()
Dim dbs As DAO.Database, Initrst, rst, rst2 As DAO.Recordset
Dim strSQL
Dim ClientsTableQuery, SalesRepList As TableDef
Dim DataB As Database
Dim ClientQD As QueryDef
Dim rstClient As DAO.Recordset
Dim DurationTotal, Counter, i As Integer
Dim LowDate1, LowDate2 As Date
Dim tmpArray(10), FieldArray(10), TempDate1, TempDate2 As Date
Dim TotalDailyHrs, TempDailyHours As Integer
Dim FirstTimeIn As Boolean
FirstTimeIn = False
TotalDailyHrs = Forms("BalFitToFabricate").Text49.Value
TempDailyHours = TotalDailyHrs
Set dbs = CurrentDb()
ClientsTableQuery = "BalFitToFabricate"
'strSQL = "Select * from Client_Table"
Set DataB = CurrentDb()
Set rstClient = DataB.OpenRecordset(ClientsTableQuery)
rstClient.MoveFirst
Counter = 0
Set Initrst = dbs.OpenRecordset("SELECT * FROM BalFitToFabricate;")
'Set rst = dbs.OpenRecordset("SELECT * FROM BalFitToFabricate;")
Set rst = dbs.OpenRecordset("SELECT * FROM (SELECT * FROM (SELECT * FROM BalFitToFabricate WHERE Used = false)) WHERE FinishDate = (select min(FinishDate) from BalFitToFabricate where Used = false);")
Set rst2 = dbs.OpenRecordset("SELECT * FROM BalFitToFabricate WHERE isnull(StartDate) order by NULLSORTER,Req_Del_Date,Priority;")
'Autonumrst.Requery
'MsgBox Initrst.RecordCount & " " & rst.RecordCount & " " & rst2.RecordCount
'First Loop
Do Until rstClient.EOF = True
If TempDailyHours <= TotalDailyHrs Then
'Autonumrst.Requery
'If FirstTimeIn = False Then
' TotalDailyHrs = TotalDailyHrs - TempDailyHours
'End If
TempDailyHours = Initrst![CreqHours]
Dim Autonumrst, Valuesrst As DAO.Recordset
Dim strSQL2, strSQL3 As String
'strSQL2 = "SELECT [Crew Hours] FROM Table2 where AutoNum = " & Initrst!Autonum & "and used = false;"
strSQL2 = "SELECT [CreqHours] FROM Table2 where Used = False;"
strSQL3 = "SELECT * FROM Table2 where Used = False;"
Set Autonumrst = CurrentDb.OpenRecordset(strSQL2)
Set Valuesrst = CurrentDb.OpenRecordset(strSQL3)
' new code:
'Stopped 2 lines
'TempDailyHours = Autonumrst![Crew Hours]
'Autonumrst.Requery
'Autonumrst.Close
'TempDailyHours = dbs.Execute "select BalFitToFabricate " & "SET startdate = #" & TempDate1 & "# WHERE Autonum = " & Initrst!Autonum & ";"
TotalDailyHrs = TotalDailyHrs - TempDailyHours
If TotalDailyHrs > 0 Then
TempDate1 = Format([Forms]![BalFitToFabricate]![Text51].Value, "mm-dd-yyyy")
'TempDate1 = [Forms]![BalFitToFabricate]![Text68].Value
dbs.Execute "UPDATE BalFitToFabricate " & "SET startdate = #" & TempDate1 & "# WHERE ID = " & Initrst!ID & ";"
TempDate2 = AddFinishDate(Format(TempDate1, "mm-dd-yyyy"), Initrst!ReqDays, Me.FridayOffCheckBox2)
dbs.Execute "UPDATE BalFitToFabricate " & "SET finishdate = #" & TempDate2 & "# WHERE ID = " & Initrst!ID & ";"
'TempDate1 = strSQL59 + (strSQL22 / strSQL57)
'TempDate2 = Format(TempDate1 + (Valuesrst![Total_Req_Manhours] / Valuesrst![Crew Hours]), "dd-mm-yyyy")
'dbs.Execute "UPDATE BalFitToFabricate " & "SET Finishdate = #" & TempDate2 & "# WHERE Autonum = " & Initrst!AutoNum & ";"
dbs.Execute "UPDATE BalFitToFabricate " & "SET Used = True WHERE ID = " & Initrst!ID & ";"
End If
Initrst.MoveNext
'Autonumrst.MoveNext
Else
GoTo ExitLoop1
End If
Loop
ExitLoop1:
'MsgBox rst!Ord_No & " " & rst2!Ord_No
dbs.Execute "UPDATE BalFitToFabricate " & "SET Used = False;"
TotalDailyHrs = Forms("BalFitToFabricate").Text49.Value
TempDailyHours = TotalDailyHrs
'Second Loop
Do Until rstClient.EOF = True
'Counter = Counter + 1
'i = rstClient!Ord_No
'If rstClient.Fields("Duration") <> "" Then
' DurationTotal = DurationTotal + rstClient.Fields("Duration")
'FieldArray(Counter) = rstClient.Fields("End")
'End If
'If DurationTotal >= 15 Then
If TempDailyHours <= TotalDailyHrs Then
'If rstClient!Used = False Then
strSQL3 = "SELECT * FROM Table2 where Finishdate is null;"
Set Valuesrst = CurrentDb.OpenRecordset(strSQL3)
Valuesrst.Requery
'Counter = rst2.RecordCount
Dim temp22 As Integer
temp22 = rst.RecordCount
rst.Requery
rst2.Requery
If rst2.RecordCount <= 0 Then
GoTo ExitLoop2
End If
LowDate1 = "#" & rst!FinishDate & "#"
'LowDate2 = "#" & Valuesrst!finishdate & "#"
'End If
''Set dbs = OpenDatabase("database41.accdb")
TempDate1 = Format(rst!FinishDate, "mm-dd-yyyy")
dbs.Execute "UPDATE BalFitToFabricate " & "SET Used = true WHERE ID = " & rst!ID & ";"
dbs.Execute "UPDATE BalFitToFabricate " & "SET startdate = #" & TempDate1 & "# WHERE ID = " & rst2!ID & ";"
'TempDate1 = Format([Forms]![BalFitToFabricate]![Text59].Value + ([Forms]![BalFitToFabricate]![Text22].Value / [Forms]![BalFitToFabricate]![Text57].Value), "dd-mm-yyyy")
'TempDate1 = Format(Valuesrst![StartDate] + (Valuesrst![Total_Req_Manhours] / Valuesrst![Crew Hours]), "dd-mm-yyyy")
'dbs.Execute "UPDATE BalFitToFabricate " & "SET Finishdate = #" & TempDate1 & "# WHERE Autonum = " & Valuesrst!AutoNum & ";"
TempDate2 = AddFinishDate(Format(TempDate1, "mm-dd-yyyy"), rst!ReqDays, Me.FridayOffCheckBox2)
dbs.Execute "UPDATE BalFitToFabricate " & "SET finishdate = #" & TempDate2 & "# WHERE ID = " & rst2!ID & ";"
End If
'rstClient.MoveNext
Loop
ExitLoop2:
MsgBox "Finished Scheduling " & DurationTotal & "Time: " & Time()
rstClient.Close
[Forms]![BalFitToFabricate].Refresh
End Sub
This is not that easy, if you don't work round the clock. I have an old function that takes off-hours and weekends in consideration, though not holidays:
Public Function WorkhourAdd( _
ByVal datDateStart As Date, _
ByVal intHours As Integer) _
As Date
' Purpose: Add number of working hours to date datDateStart.
' Assumes: 5 working days per week. Adjust cbytWorkdaysOfWeek for other values.
' First workday is Monday.
' Weekend is up to and including Sunday.
' Limitation: Does not count for public holidays.
' May be freely used and distributed.
'
' 2011-01-15. Gustav Brock, Cactus Data ApS, Copenhagen
' Specify begin and end time of daily working hours.
Const cdatWorkTimeStart As Date = #8:00:00 AM#
Const cdatWorkTimeStop As Date = #4:00:00 PM#
Const cbytWorkdaysOfWeek As Byte = 5
Dim intCount As Integer
Dim datDateEnd As Date
datDateEnd = datDateStart
While intCount < intHours
datDateEnd = DateAdd("h", 1, datDateEnd)
If Weekday(datDateEnd, vbMonday) <= cbytWorkdaysOfWeek Then
If DateDiff("h", cdatWorkTimeStart, TimeValue(datDateEnd)) > 0 Then
If DateDiff("h", TimeValue(datDateEnd), cdatWorkTimeStop) >= 0 Then
intCount = intCount + 1
End If
End If
End If
Wend
WorkhourAdd = datDateEnd
End Function
You could modify it to check if time is within a holiday, to find finish time across holidays.
I have three listboxes and a date range on a parameter form. I am able to pass all of the Listbox selections with no problem. I cannot seem to find a way or answer to adding a date range to the where clause.
The Date field is Course_Date, and the textbox control names for the dates are Start_Date and End_Date
Option Compare Database
Option Explicit
Private Sub cmdPreviewReports_Click()
On Error GoTo cmdPreviewReports_Err
Dim blnQueryExists As Boolean
Dim cat As New ADOX.Catalog
Dim cmd As New ADODB.Command
Dim qry As ADOX.View
Dim varItem As Variant
Dim strInstructors As String
Dim strCourseType As String
Dim strCourseTypeCondition As String
Dim strRoleType As String
Dim strRoleTypeCondition As String
Dim strCourse_Date As Date
Dim strDateRange As String
Dim strSql As String
' Check for the existence of the stored query
blnQueryExists = False
Set cat.ActiveConnection = CurrentProject.Connection
For Each qry In cat.Views
If qry.Name = "q_Parameter_Form" Then
blnQueryExists = True
Exit For
End If
Next qry
' Create the query if it does not already exist
If blnQueryExists = False Then
cmd.CommandText = "SELECT * FROM q_jt_MCR_Instructor_Roles"
cat.Views.Append "q_Parameter_Form", cmd
End If
Application.RefreshDatabaseWindow
' Turn off screen updating
DoCmd.Echo False
' Close the query if it is already open
If SysCmd(acSysCmdGetObjectState, acQuery, "q_Parameter_Form") = acObjStateOpen Then
DoCmd.Close acQuery, "q_Parameter_Form"
End If
' Build criteria string for Instructors
For Each varItem In Me.lst_Instructors.ItemsSelected
strInstructors = strInstructors & "," & Me.lst_Instructors.ItemData(varItem) & ""
Next varItem
If Len(strInstructors) = 0 Then
strInstructors = "Like '*'"
Else
strInstructors = Right(strInstructors, Len(strInstructors) - 1)
strInstructors = "IN(" & strInstructors & ")"
End If
' Build criteria string for CourseType
For Each varItem In Me.lst_Course_Type.ItemsSelected
strCourseType = strCourseType & "," & Me.lst_Course_Type.ItemData(varItem) & ""
Next varItem
If Len(strCourseType) = 0 Then
strCourseType = "Like '*'"
Else
strCourseType = Right(strCourseType, Len(strCourseType) - 1)
strCourseType = "IN(" & strCourseType & ")"
End If
' Get CourseType condition
If Me.optAndCourseType.Value = True Then
strCourseTypeCondition = " AND "
Else
strCourseTypeCondition = " OR "
End If
' Build criteria string for RoleType
For Each varItem In Me.lst_Role.ItemsSelected
strRoleType = strRoleType & "," & Me.lst_Role.ItemData(varItem) & ""
Next varItem
If Len(strRoleType) = 0 Then
strRoleType = "Like '*'"
Else
strRoleType = Right(strRoleType, Len(strRoleType) - 1)
strRoleType = "IN(" & strRoleType & ")"
End If
' Get RoleType condition
If Me.optAndRoleType.Value = True Then
strRoleTypeCondition = " AND "
Else
strRoleTypeCondition = " OR "
End If
'Build Criteria String for Course_Date
strDateRange = strSql And " Between Me.[Start_Date] AND Me.[End_Date]"
' Build SQL statement
strSql = "SELECT q_jt_MCR_Instructor_Roles.* FROM q_jt_MCR_Instructor_Roles " & _
"WHERE q_jt_MCR_Instructor_Roles.[InstructorID] " & strInstructors & _
strCourseTypeCondition & "q_jt_MCR_Instructor_Roles.[Course_TypesID] " & strCourseType & _
strRoleTypeCondition & "q_jt_MCR_Instructor_Roles.[Roles_ID] " & strRoleType & ";"
' Apply the SQL statement to the stored query
cat.ActiveConnection = CurrentProject.Connection
Set cmd = cat.Views("q_Parameter_Form").Command
cmd.CommandText = strSql
Set cat.Views("q_Parameter_Form").Command = cmd
Set cat = Nothing
' Open the Query
If Not IsNull(cboReports) And cboReports <> "" Then
DoCmd.OpenReport cboReports, acViewPreview ' use acNormal to print without preview
Else
MsgBox ("Please make a Label selection first from the dropdown list to the left.")
cboReports.SetFocus
End If
cboReports = ""
' If required the dialog can be closed at this point
' DoCmd.Close acForm, Me.Name
'Restore screen updating
cmdPreviewReports_Exit:
DoCmd.Echo True
Exit Sub
cmdPreviewReports_Err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description:" & Err.Description _
, vbCritical, "Error"
Resume cmdPreviewReports_Exit
End Sub
I am also able to provide the database to look at if you wish?
Thank you for helping !!!!!!
William
It could be:
'Build Criteria String for Course_Date.
strDateRange = " And Course_Date Between #" & Format(Me![Start_Date].Value, "yyyy\/mm\/dd") & "# AND #" & Format(Me![End_Date].Value, "yyyy\/mm\/dd") & "#"
strSql = strSql & strDateRange
Please help below code is not generating the mail and hangs access application:
Where is issue as when I dont do dQuery Processing Email Generates properly but dont include subform records aswell.
Without Subform Details Mail is something like this Email Generated with Proper variables present on MainForm
Private Sub InformCustomer_Click()
On Error GoTo Err_InformCustomer_Click
Dim CustName As String ' Customer Name
Dim varTo As Variant '-- Address for SendObject
Dim stText As String '-- E-mail text
Dim DelDate As Variant '-- Rec date for e-mail text
Dim stSubject As String '-- Subject line of e-mail
Dim stOrderID As String '-- The Order ID from form
Dim strSQL As String '-- Create SQL update statement
Dim errLoop As Error
Dim dQuery As String
Dim MyDb As DAO.Database
Dim rs As DAO.Recordset
stOrderID = Me![OdrID]
strSQL = "SELECT BrandName, ModelName, Status " _
& " FROM OrderProdDetails " _
& " WHERE (OrdID)=" & stOrderID & ";"
Set MyDb = CurrentDb
Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
While Not rs.EOF
dQuery = dQuery & rs![BrandName].Value & vbTab & rs![ModelName].Value & rs![Status].Value & vbCrLf
Wend
Set rs = Nothing
CustName = Me![CustName]
varTo = Me![CustEmail]
stSubject = ":: Update - Oder Status ::"
stOrderID = Me![OdrID]
DelDate = Me![OdrDeliveryDate]
stText = "Dear" & CustName & Chr$(13) & _
"You have been assigned a new ticket." & Chr$(13) & Chr$(13) & _
"Order Number: " & stOrderID & Chr$(13) & _
_
"Please refer to your order status " & Chr$(13) & _
"Exp Delevery Date: " & DelDate & Chr$(13) & Chr$(13) & _
dQuery & Chr$(13) & _
"This is an automated message. Please do not respond to this e-mail."
'Write the e-mail content for sending to assignee
DoCmd.SendObject , , acFormatTXT, varTo, , , stSubject, stText, True
MsgBox "Done"
Exit Sub
Err_InformCustomer_Click:
MsgBox Err.Description
End Sub
You have created an endless loop.
While Not rs.EOF
dQuery = dQuery & rs![BrandName].Value & vbTab & rs![ModelName].Value & rs![Status].Value & vbCrLf
' This is missing -->
rs.MoveNext
Wend