I have a query table which shows the "FirstName", "LastName", "DueDate". What I wanted to do is create a follow-up process. If the duedate is today (date()), access needs to send notification email to the one general email address.
My code works only for first record in the query, it doesn't goes to other records.
Here is the code that I am using for;
Public Sub FollowUpEmail()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim oApp As Object
Dim oEmail As Object
Set oApp = CreateObject("Outlook.Application")
Set oEmail = oApp.CreateItem(0)
Set db = CurrentDb
strSQL = "SELECT FirstName, SurName, DueDate" & _
" FROM TestQuery"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
While Not rs.EOF
SendKeys "^{ENTER}"
With oEmail
.To = "xxx"
.Subject = rs.Fields("FirstName").Value & "/" & "Deadline"
.Body = "test"
.Display
End With
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
Set db = Nothing
Set oApp = Nothing
Set oEmail = Nothing
End Sub
You will need to create & send a new email for every iteration of the loop, for example:
Public Sub FollowUpEmail()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim oApp As Object
Set oApp = CreateObject("Outlook.Application")
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT FirstName, SurName, DueDate FROM TestQuery")
Do Until rs.EOF
With oApp.CreateItem(0)
.To = "xxx"
.Subject = rs!FirstName & "/" & "Deadline"
.Body = "test"
.Display
End With
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
Set oApp = Nothing
End Sub
Or, if you want to send the emails directly:
Public Sub FollowUpEmail()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim oApp As Object
Set oApp = CreateObject("Outlook.Application")
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT FirstName, SurName, DueDate FROM TestQuery")
Do Until rs.EOF
With oApp.CreateItem(0)
.To = "xxx"
.Subject = rs!FirstName & "/" & "Deadline"
.Body = "test"
.Send
End With
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
Set oApp = Nothing
End Sub
Related
So I have a table in access with file names I have been using as links in a form to view pictures. I would like to move these into an attachment database of photos so I can distribute the database to others without having to copy the file path names too.
I started some code to try it but not sure how to loop through the file paths because I have specific images I choose.
Here is an example of some of the data...so I would take the Tassel photo filepath and upload the picture to column PhotoT with datatype attachment.
EDIT:
I updated my code to get this to work. I added in a column import to the previous table. and added in seperate coding sections for each column. It works great! My database increased in size to 1.7gb. It was originally only 30mb with 60mb of pictures to update. Not sure where all the storage went too. The speed is a lot faster and its now self contained so thats great. If i had anymore picture i would have had to figure something else out haha
Option Compare Database
Option Explicit
Sub test()
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim rsA As DAO.Recordset
Dim fld As DAO.Field
Dim tdf As DAO.TableDef
Dim rstChild As Recordset2
Dim strsql As String
Dim noRows As String
Dim Tasselpath As String
'''''''''''''''''''''''''''''
'add columns to table
'''''''''''''''''''''''''''''
If DoesTblFieldExist("InbredPicPaths", "PE") = False Then
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("InbredPicPaths")
Set fld = tdf.CreateField("PT", dbAttachment)
tdf.Fields.Append fld
Set fld = tdf.CreateField("PS", dbAttachment)
tdf.Fields.Append fld
Set fld = tdf.CreateField("PE", dbAttachment)
tdf.Fields.Append fld
Set fld = tdf.CreateField("PBR", dbAttachment)
tdf.Fields.Append fld
Set tdf = Nothing
End If
'''''''''''''''''''''''''''''
'Tassel
'''''''''''''''''''''''''''''
Set dbs = CurrentDb
strsql = "SELECT InbredPicPaths.* FROM InbredPicPaths WHERE (((InbredPicPaths.Tassel)<>''))"
Set rst = dbs.OpenRecordset(strsql)
'Set fld = rst("Tassel")
Set rstChild = rst.Fields("PT").Value
If rstChild.RecordCount <= 0 Then
'Navigate through the table
Do While Not rst.EOF
'Get the recordset for the Attachments field
Tasselpath = rst!Tassel
rst.Edit
Set rsA = rst.Fields("PT").Value
rsA.AddNew
rsA("FileData").LoadFromFile Tasselpath
rsA.Update
rsA.Close
rst.Update
'Next record
rst.MoveNext
Loop
End If
'''''''''''''''''''''''''''''
'silk
'''''''''''''''''''''''''''''
' Set dbs = CurrentDb
strsql = "SELECT InbredPicPaths.* FROM InbredPicPaths WHERE (((InbredPicPaths.Silk)<>''))"
Set rst = dbs.OpenRecordset(strsql)
'Set fld = rst("Silk")
Set rstChild = rst.Fields("PS").Value
If rstChild.RecordCount <= 0 Then
'Navigate through the table
Do While Not rst.EOF
'Get the recordset for the Attachments field
Tasselpath = rst!Silk
rst.Edit
Set rsA = rst.Fields("PS").Value
rsA.AddNew
rsA("FileData").LoadFromFile Tasselpath
rsA.Update
rsA.Close
rst.Update
'Next record
rst.MoveNext
Loop
End If
'''''''''''''''''''''''''''''
'Braceroot
'''''''''''''''''''''''''''''
'Set dbs = CurrentDb
strsql = "SELECT InbredPicPaths.* FROM InbredPicPaths WHERE (((InbredPicPaths.BraceRoot)<>''))"
Set rst = dbs.OpenRecordset(strsql)
'Set fld = rst("BraceRoot")
Set rstChild = rst.Fields("PBR").Value
If rstChild.RecordCount <= 0 Then
'Navigate through the table
Do While Not rst.EOF
'Get the recordset for the Attachments field
Tasselpath = rst!BraceRoot
rst.Edit
Set rsA = rst.Fields("PBR").Value
rsA.AddNew
rsA("FileData").LoadFromFile Tasselpath
rsA.Update
rsA.Close
rst.Update
'Next record
rst.MoveNext
Loop
End If
'''''''''''''''''''''''''''''
'Ear
'''''''''''''''''''''''''''''
'Set dbs = CurrentDb
strsql = "SELECT InbredPicPaths.* FROM InbredPicPaths WHERE (((InbredPicPaths.Ear)<>''))"
Set rst = dbs.OpenRecordset(strsql)
' Set fld = rst("Ear")
Set rstChild = rst.Fields("PE").Value
If rstChild.RecordCount <= 0 Then
'Navigate through the table
Do While Not rst.EOF
'Get the recordset for the Attachments field
Tasselpath = rst!Ear
rst.Edit
Set rsA = rst.Fields("PE").Value
rsA.AddNew
rsA("FileData").LoadFromFile Tasselpath
rsA.Update
rsA.Close
rst.Update
'Next record
rst.MoveNext
Loop
End If
rst.Close
Set rst = Nothing
Set rsA = Nothing
Set dbs = Nothing
Set rstChild = Nothing
End Sub
So from the picture it looks like you need to iterate through the rows of a table with a column containing the url of a file and then attach that file to an attachment type column in the same file. Assuming:
Here is code that does that.
Public Sub MovethroughTableAttachingPhotos(TableName As String, urlColumnName As String, attachmenttypeColumnName As String)
'adapted from https://learn.microsoft.com/en-us/office/vba/access/concepts/data-access-objects/work-with-attachments-in-dao
Dim db As Database
Set db = CurrentDb
Dim rsTable As Recordset
Dim rsPhotos As Recordset
Set rsTable = db.OpenRecordset(TableName)
rsTable.MoveFirst 'avoids an error
Dim currentURL As String
Do Until rsTable.EOF
currentURL = rsTable(urlColumnName)
rsTable.Edit
Set rsPhotos = rsTable.Fields(attachmenttypeColumnName).value
rsPhotos.AddNew
rsPhotos.Fields("FileData").LoadFromFile (currentURL)
rsPhotos.Update
rsPhotos.Close 'placing here avoids an error
rsTable.Update
rsTable.MoveNext
Loop
'clean up
rsTable.Close
Set rsPhotos = Nothing
Set rsTable = Nothing
Set db = Nothing
End Sub
'to call the subroutine : MovethroughTableAttachingPhotos "Photos", "PhotoAddress", "PhotoAttachment"
I'm trying to call several modules that are set up to send an email to specified users who are listed in a table using a function. The logic that the emails follow are supposed to be setup to email each user after 7 days contingent upon the preceding date that they were emailed previously (FirstEmailDate, SecondEmailDate, ThirdEmailDate, and FinalEmailDate). I'm having a hard time with that logic, searching each row of the entire table, and being able to automatically add a date and timestamp to the fields for each email date. Any help with this coding would greatly appreciated. Thank you
Below is just one module as an example:
Option Compare Database
Option Explicit
Sub EmailFinalAttempt()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim emailTo As String
Dim emailSubject As String
Dim emailText As String
Dim UPDATE As String
Dim Edit As String
Dim strCompleted As String
Dim strMessage As String
Dim oApp As New Outlook.Application
Dim oMail As Outlook.MailItem
Dim oStarted As Boolean
Dim EditMessage As Object
Dim qdf As QueryDef
On Error Resume Next
Set oApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If oApp Is Nothing Then
Set oApp = CreateObject("Outlook.Application")
oStarted = True
End If
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM ProductRequestForm")
rs.MoveFirst
Do While Not rs.EOF
emailTo = 'email address'
emailSubject = "Final Email Attempt"
emailText = Trim("Hello " & rs.Fields("SubmitterFirstName").Value) & "," & vbCrLf
If (rs.Fields("ThirdEmailDate").Value >= 7 Or (IsNull(rs.Fields("FinalEmailDate").Value))) And (rs.Fields("ThirdEmailDate").Value) Then
emailText = emailText & "message body" & _ vbCrLf
' If today is greater than third attempt date and third attempt is + Null then send email
End If
rs.MoveNext
Loop
rs.MoveFirst
Do While Not rs.EOF
If rs.Fields("Completed?").Value = "Active" Then
rs.Edit
rs.Fields("Completed?").Value = "Inactive"
rs.UPDATE
End If
rs.MoveNext
Loop
rs.MoveNext
Do While Not rs.EOF
If rs.Fields("FinalEmailDate").Value Then
rs.Edit
rs.Fields("FinalEmailDate").Value = Date
rs.UPDATE
End If
rs.MoveLast
Set oMail = oApp.CreateItem(0)
With oMail
.To = emailTo
.Subject = emailSubject
.Body = emailText
'.Save
DoCmd.SendObject acSendForm, "ProductRequestForm", acFormatXLS, emailTo, , , emailSubject, emailText, False
DoCmd.SetWarnings (False)
End With
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
If oStarted Then
oApp.Quit
End If
Set oMail = Nothing
Set oApp = Nothing
End Sub
Really should be able to do this with one procedure regardless of last email date.
Only pull records that meet 7-day criteria. Calculate a field that identifies which cycle and field to update. Presume FirstEmailDate is populated when record created.
Set rs = db.OpenRecordset("SELECT *, " & _
" Switch(IsNull(SecondEmailDate),"Second", IsNull(ThirdEmailDate),"Third", True,"Final") AS Fld " & _
" FROM ProductRequestForm WHERE FinalEmailDate Is Null " & _
" AND Nz(ThirdEmailDate, Nz(SecondEmailDate, FirstEmailDate)) <= Date()-7")
Use Fld value from recordset to update appropriate field.
rs(rs!Fld & "EmailDate") = Date()
I tried using SQL but with no success. I then tried DAO, the other fields
seems to work but the column which holds attachments fails. Has someone done this before?
Private Sub copyfromtblA_Click()
Dim db As Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset2
'Set db = CurrentDb()
Set rs1 = db.OpenRecordset("tblA")
Set rs2 = db.OpenRecordset("tblB")
With rs2
rs2.AddNew
rs2.Fields("ItemNo").Value = Me.ItemNo.Value
rs2.Fields("Quantity").Value = Me.Quantity.Value
rs2.Fields("itemName").Value = Me.itemName.Value
'This is were I get the error since this field contains images as attachments
rs2.Fields("ItemImage").Value = Me.itemImage.Value
rs2.Update
rs1.MoveNext
End With
rs2.Close
Form.Requery
Set rs2 = Nothing
rs1.Close
Set rs1 = Nothing
End Sub
Something like this:
Private Sub copyfromtblA_Click()
Dim db As Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rsAtt1 As DAO.Recordset2
Dim rsAtt2 As DAO.Recordset2
Set db = CurrentDb()
Set rs2 = db.OpenRecordset("tblB")
With Me.Recordset
rs2.AddNew
rs2.Fields("ItemNo").Value = !ItemNo.Value
rs2.Fields("Quantity").Value = !Quantity.Value
rs2.Fields("itemName").Value = !itemName.Value
Set rsAtt1 = !ItemImage.Value
Set rsAtt2 = rs2!ItemImage.Value
With rsAtt1
Do While Not .EOF
rsAtt2.AddNew
rsAtt2.Fields("FileData") = .Fields("FileData")
rsAtt2.Fields("FileName") = .Fields("FileName")
rsAtt2.Update
.MoveNext
Loop
End With
rs2.Update
End With
rs2.Close
Set rs2 = Nothing
rsAtt1.Close
Set rsAtt1 = Nothing
'I was getting an error here! removing the "rsAtt2.Close" solved the problem
'rsAtt2.Close
Set rsAtt2 = Nothing
End Sub
I am unable to get the count of records by openining Ms Access Query, I use the following code.
Private Sub CmdGetData_Click()
Dim WRK As Workspace
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim StrSql As String
Set WRK = DBEngine.Workspaces(0)
Set db = CurrentDb
StrSql = "select * from [QrySalePatti]"
Set rs = db.OpenRecordset(StrSql, dbOpenDynaset)
Do While (Not rs.EOF)
rs.MoveFirst
rs.MoveLast
MsgBox rs.RecordCount
Loop
exitRoutine:
If Not (db Is Nothing) Then
db.Close
Set db = Nothing
End If
Set WRK = Nothing
End Sub
You should not need a Do While loop to get the RecordCount.
Set rs = db.OpenRecordset(StrSql, dbOpenDynaset)
With rs
If Not (.BOF And .EOF) Then
.MoveLast
End If
MsgBox .RecordCount
End With
However if your goal is only to count the rows from QrySalePatti, you could use a SELECT Count(*) query and read the value returned from that.
StrSql = "SELECT Count(*) AS row_count FROM [QrySalePatti]"
Set rs = db.OpenRecordset(StrSql)
MsgBox rs!row_count
Or you could use a DCount expression.
MsgBox DCount("*", "QrySalePatti")
Here's what I'm trying to do and I apologize if I'm headed the wrong direction. I'm trying to cycle through the filepath's stored in table t_Directory and if the file extension is "xlsx" open the Excel file and update another table called t_SheetInfo with the FileID of the Excel Worksheet and sheet count and the sheet name. Would anyone have a minute to check what I've got so far or steer me in the right direction if there's a more efficient way to do it? I'm not 100% sure that I know what I'm doing. As always, thank you in advance for any help!!
Dim db As DAO.Database
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Private Sub CycleThroughWorkSheets()
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim sSQL1 As String
Dim sSQL2 As String
Dim sSQL3 As String
Dim rsFilePath As String
Dim rsWSName As String
Set db = CurrentDB
sSQL1 = "SELECT t_Directory.FileID, t_Directory.FilePath FROM t_Directory " & _
"WHERE (((t_Directory.FileExtension)=""'xlsx'""))"
Set rs = db.OpenRecordset("sSQL1", dbOpenDynaset)
With rs
rs.MoveFirst
Do While Not rs.EOF
rsFilePath = rs.Fields("[FilePath]")
OpenWorkBook (rsFilePath)
Set rs2 = db.OpenRecordset("t_SheetInfo", dbOpenDynaset)
With rs2
rs2.MoveFirst
Do While Not rs2.EOF
rs2.AddNew
rs2.Fields("FileID") = rs.Fields(1)
rs2.Fields("[SheetIndex]") = WorkSheetCount(rsFilePath)
rs2.Fields("[SheetName]") = WorkSheetName(WorkSheetCount)
rs2.Update
Next
Loop
End With
End With
Set rs = Nothing
Set rs2 = Nothing
End Sub
Public Function WorkSheetCount(rsFilePath As String) As Integer
Set xlWB = xlApp.Workbooks.Open(rsFilePath)
WorkSheetCount = xlWB.Sheets.Count(rsFilePath)
Debug.Print "WorkSheetCount : " & WorkSheetCount
End Function
Public Function WorkSheetName(WorkSheetCount As Integer) As String
Set xlWB = xlApp.Workbooks.Open(rsFilePath)
WorkSheetName = Worksheets(WorkSheetCount).Name
Debug.Print "WorkSheetName : " & WorkSheetName
End Function
Try something on these lines. Step through.
Dim xlApp As New Excel.Application
Dim xlWB As Excel.Workbook
Dim sh As Object ''Some sheets may be charts
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim sSQL1 As String
Dim sSQL2 As String
Dim sSQL3 As String
Dim rsFilePath As String
Dim rsWSName As String
Set db = CurrentDb
xlApp.Visible = True
sSQL1 = "SELECT t_Directory.FileID, t_Directory.FilePath FROM t_Directory " & _
"WHERE t_Directory.FileExtension='.xlsx'"
Set rs2 = db.OpenRecordset("t_SheetInfo", dbOpenDynaset)
Set rs = db.OpenRecordset(sSQL1, dbOpenDynaset)
Do While Not rs.EOF
rsFilePath = rs.Fields("[FilePath]")
Set xlWB = xlApp.Workbooks.Open(rsFilePath)
For Each sh In xlWB.Sheets
rs2.AddNew
rs2.Fields("FileID") = rs.Fields("FileID")
rs2.Fields("[SheetIndex]") = sh.Index
rs2.Fields("[SheetName]") = sh.Name
rs2.Update
Next
rs.MoveNext
xlWB.Close False
Loop
Set rs = Nothing
Set rs2 = Nothing
xlApp.Quit