Restrict Find To Limited Number of Records Loop - sql

The following code works to extract the first name and email from a database and send via CDOSys and email to records found.
My hosting service limits the number of recipients to 10 so I'm thinking would it be poosible to restrict the find to the first 10 records, then send and then find the next 10 records and send and so on and so on until the end of the table is reached?
<%
Set OBJdbConnection = CreateObject("ADODB.Connection")
OBJdbConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("myData.mdb")
SQLQuery = "SELECT FirstName, Email_Address FROM MyTable"
Set Result = OBJdbConnection.Execute(SQLQuery)
if Not Result.EOF then
Do While Not Result.EOF
SendMail Result("FirstName"), Result("Email_Address")
Result.MoveNext
Loop
end if
OBJdbConnection.Close()
Set OBJdbConnection = Nothing
Sub SendMail(TheName, TheAddress)
Dim objMessage, Rcpt
If (TheName <> "" AND TheAddress <> "") Then
smtpServer = "mail.mydomain.com"
body = "Hello World"
Rcpt = Chr(34) & TheName & Chr(34) & "<" & TheAddress & ">"
set objMessage = Server.CreateObject("CDO.Message")
set cdoConfig = Server.CreateObject("CDO.Configuration")
cdoConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
cdoConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtpServer
cdoConfig.Fields ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
cdoConfig.Fields ("http://schemas.microsoft.com/cdo/configuration/sendusername") ="smtp#mydomain.com"
cdoConfig.Fields ("http://schemas.microsoft.com/cdo/configuration/sendpassword") ="123456"
cdoConfig.Fields.Update
set objMessage.Configuration = cdoConfig
objMessage.Subject = "This Month's Sales"
objMessage.From = """Acme Sales"" <me#mydomain.com>"
objMessage.To = Rcpt
objMessage.HTMLBody = body
objMessage.Send
End If
End Sub
set objMessage = Nothing
set cdoConfig = Nothing
%>

I think it can be what you want to do.
<%
if Not Result.EOF then
i = 0
Do While i<10
SendMail Result("FirstName"), Result("Email_Address")
Result.MoveNext
i= i+1
Loop
....
%>

Related

update if true and add new if false, criteria problem

Here is what i want: I'm making a code to generate invoices data automatically for me when i select month and year then click cmdbtn; but if customerID with the selected date ([Forms]![F_Reports_Slct]![MnthSlct]) and (....![YrSlct]) exists, then update the values instead of creating new record.
Everything here works fine except editing records if matched criteria..
my data is being recreated again when clicked.
I guess I have some problem with criteria.
Note that rsM and rsY are queries, and that the table's recordset ( rs ) has a primary key field with auto numbering [CrId].
Dim msg1 As Variant
Dim db As Database
Dim qdM As QueryDef
Dim qdY As QueryDef
Dim rs As Recordset
Dim rsM As Recordset
Dim rsY As Recordset
Dim lngID As Long
Dim Mcr As String
Dim Ycr As String
Dim strCriteria As String
If IsNull([Forms]![F_Reports_Slct]![YrSlct]) Or IsNull([Forms]![F_Reports_Slct]![MnthSlct]) Then
MsgBox "please enter data"
Cancel = True
Else
Set db = CurrentDb
Set qdM = db.QueryDefs("QC_MonthlyAm4CuID_Tr")
Set qdY = db.QueryDefs("QC_YrlyAm4CuID_Tr")
qdM.Parameters(0).Value = [Forms]![F_Reports_Slct]![YrSlct].Value
qdM.Parameters(1).Value = [Forms]![F_Reports_Slct]![MnthSlct].Value
qdY.Parameters(0).Value = [Forms]![F_Reports_Slct]![YrSlct].Value
qdY.Parameters(1).Value = [Forms]![F_Reports_Slct]![MnthSlct].Value
Mcr = qdM.Parameters(1).Value
Ycr = qdM.Parameters(0).Value
Set rs = db.OpenRecordset("T_CrofServices", dbOpenDynaset)
Set rsM = qdM.OpenRecordset(dbOpenDynaset)
Set rsY = qdY.OpenRecordset(dbOpenDynaset)
msg1 = MsgBox("sure?", vbYesNo + vbExclamation, "Are You Sure?")
If msg1 = vbNo Then
Cancel = True
ElseIf msg1 = vbYes Then
If Not rsM.BOF Then
rsM.MoveFirst
Do Until rsM.EOF
lngID = rsM!CuId & Mcr & Ycr
strCriteria = rs!TrDtCuID = " & lngID"
rs.FindFirst strCriteria
If rs.NoMatch Then
rs.AddNew
Else
rs.Edit
End If
rs![CuId] = rsM![CuId]
rs![CollectorID] = rsM![CollectorID]
rs![Amount] = rsM![MonthlyAm]
rs![DateofCr] = rsM![DateofCr]
rs![TrDtCuID] = rsM!CuId & Mcr & Ycr
rs![TrDt] = rsM![DtTr]
rs.Update
rsM.MoveNext
Loop
End If
If Not rsY.BOF Then
rsY.MoveFirst
Do Until rsY.EOF
lngID = rsY!CuId & Mcr & Ycr
strCriteria = "[TrDtCuID]=' & lngID'"
rs.FindFirst strCriteria
If rs.NoMatch Then
rs.AddNew
Else
rs.Edit
End If
rs![CuId] = rsY![CuId]
rs![CollectorID] = rsY![CollectorID]
rs![Amount] = rsY![YrlyAm1]
rs![DateofCr] = rsY![DateofCr]
rs![TrDtCuID] = rsY!CuId & Mcr & Ycr
rs![TrDt] = rsY![DtTr]
rs.Update
rsY.MoveNext
Loop
End If
rs.close
rsM.close
rsY.close
Set rs = Nothing
Set rsM = Nothing
Set rsY = Nothing
Set db = Nothing
Set qdM = Nothing
Set qdY = Nothing
MsgBox "Done.", vbInformation, "Succeed"
End If
End If
I guess I have some problem with criteria.
Yes. You must make up your mind, if you wish to use a Long or a String. Here, you are casting back and forth between these:
lngID = rsM!CuId & Mcr & Ycr
strCriteria = rs!TrDtCuID = " & lngID"
Also, it should read:
strCriteria = "TrDtCuID = " & lngID & ""
Or, if you turn the ID into a string:
strCriteria = "TrDtCuID = '" & strID & "'"

Trying to make code more efficient and stable

I have a program, that works, I just feel that it is running slower than it should and I feel that it is a bit more unstable than it should be. I am looking for tips on writing "better" code and making my program more stable.
I am looking to better this part of my code for now:
Private Sub Worksheet_Activate()
Application.ScreenUpdating = False
'Removes shapes already there that will be updated by the getWeather function
For Each delShape In Shapes
If delShape.Type = msoAutoShape Then delShape.Delete
Next delShape
'Calls a function to get weather data from a web service
Call getWeather("", "Area1")
Call getWeather("", "Area2")
Call getWeather("", "Area3")
'Starting to implement the first connection to a SQL Access database.
Dim cn As Object
Dim rs As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn = CreateObject("ADODB.Connection")
Set sqlConnect = New ADODB.Connection
Set rs = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn.Open sqlConnect
'Set rs.Activeconnection to cn
rs.ActiveConnection = cn
'Get a username from the application to be used further down
Brukernavn = Application.userName
'This part of the code re-arranges the date format from american to european
StartDate = Date
EndDate = Date - 7
midStartDate = Split(StartDate, ".")
midEndDate = Split(EndDate, ".")
StartDate2 = "" & midStartDate(1) & "/" & midStartDate(0) & "/" & midStartDate(2) & ""
EndDate2 = "" & midEndDate(1) & "/" & midEndDate(0) & "/" & midEndDate(2) & ""
'SQL statement to get data from the access database
rs.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] = '" & Brukernavn & "' AND [Loggtype] <> 'Beskjed' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn, adOpenStatic
'Start to insert data from access database into a list
Dim i As Integer
Dim u As Integer
If Not rs.EOF Then
rs.MoveFirst
End If
i = 0
With lst_SisteFeil
.Clear
Do
If Not rs.EOF Then
.AddItem
If Not IsNull(rs!refnr) Then
.List(i, 0) = rs![refnr]
End If
If IsDate(rs![Meldt Dato]) Then
.List(i, 1) = Format(rs![Meldt Dato], "dd/mm/yy")
End If
.List(i, 4) = rs![nettstasjon]
If Not IsNull(rs![Sekundærstasjon]) Then
.List(i, 2) = rs![Sekundærstasjon]
End If
If Not IsNull(rs![Avgang]) Then
.List(i, 3) = rs![Avgang]
End If
If Not IsNull(rs![Hovedkomponent]) Then
.List(i, 5) = rs![Hovedkomponent]
End If
If Not IsNull(rs![HovedÅrsak]) Then
.List(i, 6) = rs![HovedÅrsak]
End If
If Not IsNull(rs![Status Bestilling]) Then
.List(i, 7) = rs![Status Bestilling]
End If
If Not IsNull(rs![bestilling]) Then
.List(i, 8) = rs![bestilling]
End If
i = i + 1
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
End With
endOfFile:
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
'Starts to connect to SQL access database again to get different set of data. This must be possible to make more efficient?
Dim cn2 As Object
Dim rs2 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn2 = CreateObject("ADODB.Connection")
Set sqlConnect2 = New ADODB.Connection
Set rs2 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect2.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn2.Open sqlConnect
'Set rs.Activeconnection to cn
rs2.ActiveConnection = cn2
'Second SQL statement
rs2.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] <> '" & Brukernavn & "' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn2, adOpenStatic
'Inserting into second list
If Not rs2.EOF Then
rs2.MoveFirst
End If
u = 0
With lst_AlleFeil
.Clear
Do
If Not rs2.EOF Then
.AddItem
If Not IsNull(rs2!refnr) Then
.List(u, 0) = rs2![refnr]
End If
If IsDate(rs2![Meldt Dato]) Then
.List(u, 1) = Format(rs2![Meldt Dato], "dd/mm/yy")
End If
.List(u, 4) = rs2![nettstasjon]
If Not IsNull(rs2![Sekundærstasjon]) Then
.List(u, 2) = rs2![Sekundærstasjon]
End If
If Not IsNull(rs2![Avgang]) Then
.List(u, 3) = rs2![Avgang]
End If
If Not IsNull(rs2![Hovedkomponent]) Then
.List(u, 5) = rs2![Hovedkomponent]
End If
If Not IsNull(rs2![HovedÅrsak]) Then
.List(u, 6) = rs2![HovedÅrsak]
End If
If Not IsNull(rs2![Status Bestilling]) Then
.List(u, 7) = rs2![Status Bestilling]
End If
If Not IsNull(rs2![bestilling]) Then
.List(u, 8) = rs2![bestilling]
End If
u = u + 1
rs2.MoveNext
Else
GoTo endOfFile2
End If
Loop Until rs2.EOF
End With
endOfFile2:
rs2.Close
cn2.Close
Set rs2 = Nothing
Set cn2 = Nothing
'Starting to connect to the database for the third time
Dim cn3 As Object
Dim rs3 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn3 = CreateObject("ADODB.Connection")
Set sqlConnect3 = New ADODB.Connection
Set rs3 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect3.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn3.Open sqlConnect
'Set rs.Activeconnection to cn
rs3.ActiveConnection = cn3
'third sql statement
rs3.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato], [Sekundærstasjon], [Avgang], [Beskrivelse], [Til Dato] FROM [tblDatabase]" & _
"WHERE [Loggtype] = 'Beskjed' AND [Meldt Dato] >= DateAdd('d',-30,Date())" & _
"ORDER BY [Meldt Dato] DESC;", _
cn3, adOpenStatic
'Inserting data in to third list
If Not rs3.EOF Then
rs3.MoveFirst
End If
j = 0
With lst_beskjeder
.Clear
Do
If Not rs3.EOF Then
.AddItem
If Not IsNull(rs3!refnr) Then
.List(j, 0) = rs3![refnr]
End If
If IsDate(rs3![Meldt Dato]) Then
.List(j, 1) = Format(rs3![Meldt Dato], "dd/mm/yy")
End If
.List(j, 4) = rs3![nettstasjon]
If Not IsNull(rs3![Sekundærstasjon]) Then
.List(j, 2) = rs3![Sekundærstasjon]
End If
If Not IsNull(rs3![Avgang]) Then
.List(j, 3) = rs3![Avgang]
End If
If Not IsNull(rs3![beskrivelse]) Then
.List(j, 5) = rs3![beskrivelse]
End If
j = j + 1
rs3.MoveNext
Else
GoTo endOfFile3
End If
Loop Until rs3.EOF
End With
endOfFile3:
rs3.Close
cn3.Close
Set rs3 = Nothing
Set cn3 = Nothing
End Sub
Here is the function I have used to get weather data.
Public Sub getWeather(APIurl As String, sted As String)
Dim i As Integer
i = 0
Dim omraade As String
omraade = ""
omraade = sted
If sted = "Area1" Then
i = 4
ElseIf sted = "Area2" Then
i = 6
ElseIf sted = "Area3" Then
i = 8
End If
Dim WS As Worksheet: Set WS = ActiveSheet
Dim delShape As Shape
Dim city As String
Dim Req As New XMLHTTP
Req.Open "GET", "" & APIurl & "", False
Req.Send
Dim Resp As New DOMDocument
Resp.LoadXML Req.responseText
Dim Weather As IXMLDOMNode
Dim wShape As Shape
Dim thisCell As Range
For Each Weather In Resp.getElementsByTagName("current_condition")
Set thisCell = WS.Range(Cells(2, i), Cells(2, i))
Set wShape = WS.Shapes.AddShape(msoShapeRectangle, thisCell.Left, thisCell.Top, thisCell.Width, thisCell.Height)
wShape.Fill.UserPicture Weather.ChildNodes(4).Text 'img
Cells(3, i).Value = "" & Weather.ChildNodes(7).Text * 0.28 & " m/s" 'windspeedkmph
Cells(4, i).Value = Weather.ChildNodes(9).Text 'Direction
Cells(5, i).Value = Weather.ChildNodes(1).Text & " C" 'observation time
Next Weather
End Sub
Feel free to point out any poor coding and tips on how to improve it. I am currently using the Worksheet Activate sub to activate changes in the tables and get new data, but I suspect that is not the best solution. I am just not sure how else to do it seeing as I want it to be as "automatic" as possible, and use as few buttons to refresh as I can.
Thank you for all the help.
-Thomas
Some tips, but none will affect performance, only help make your code more succinct.
1.
rs.Open "SELECT ..."
If Not rs.EOF Then
rs.MoveFirst
End If
.MoveFirst is unnecessary. After opening a recordset, you are always on the first record, if there are records.
When building complex SQL in VBA, have a look at How to debug dynamic SQL in VBA.
2.
Don't do a Do ... Until loop for recordsets:
Do
If Not rs.EOF Then
' do stuff for each record
' ...
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
endOfFile:
rs.Close
Instead use Do While Not rs.EOF :
Do While Not rs.EOF
' do stuff for each record
' ...
rs.MoveNext
Loop
rs.Close
For an empty rs, the loop will not be entered. You don't need the If/Else and the Goto.

Sending email if the SQL query result is empty

This script run correctly for send email SQL query result, but I need script to stop send email if the SQL query result is empty.
'Declare Constants
Const CDO_SCHEMA = "http://schemas.microsoft.com/cdo/configuration/"
Const CDO_MAIL_HEADER = "urn:schemas:mailheader:"
'Method used to send mail
Const CDO_SEND_USING_REMOTE = 2 'Send using Remote SMTP Server
'Security method used on remote SMTP server
Const CDO_ANONYMOUS = 0 'Use no authentication
Const CDO_BASIC = 1 'Use the basic (clear text) authentication
Const CDO_NTLM = 2 'Use the NTLM authentication
'Delivery Status Notifications
Const cdoDSNDefault = 0 'No DSN commands are issued
Const cdoDSNNever = 1 'No DSN commands are issued
Const cdoDSNFailure = 2 'Return a DSN if delivery fails
Const cdoDSNSuccess = 4 'Return a DSN if delivery succeeds
Const cdoDSNDelay = 8 'Return a DSN if delivery is delayed
Const cdoDSNSuccessFailOrDelay = 14 'Return a DSN if delivery succeeds, fails, or is delayed
'Set method of sending
strSendMethod = CDO_SEND_USING_REMOTE
'Remote SMTP Server Settings
strSmtpServer = "smtp.abc.com" 'Name or IP of SMTP Server
intSmtpPort = 25 'SMTP Server Port; typically 25
intSmtpTimeout = 60 'Number of seconds to try establishing a connection to the SMTP Server
strAuthenticationMethod = CDO_ANONYMOUS
'SMTP Server Authentication - IF BASIC or NTLM; NOT needed for ANONYMOUS
strUserName = ""
strPassword = ""
strUserSSL = False 'True if SMTP Server uses SSL; False if Not
'Message Settings
strTo = "asdf#abc.com"
'Separate multiple addresses with a semi-colon (;)
strCC = ""
strBCC = ""
strFrom = "no-reply-SalesInfo#abc.com"
strSubject = "Pending Sales Order - Perlu di follow up"
strBodyType = "TEXT"
strAttachment = "D:\File.txt" 'Attachment Path i.e. C:\Temp\File.txt
strDSNotification = cdoDSNDefault 'Delivery Status Option Change as needed
'WScript.Echo "Connecting to database..."
'Connect to database & select all from Table
Set objDB = DBConnect()
Set oRS = objDB.Execute("SELECT S_ORDER 'SO# ',CUSTOMER_NAME'CUSTOMER ',DATE 'Tanggal ',USERID 'INTERNAL ',CALLING 'Approval from ',LIMIT 'LIMIT ',TERM 'TERM ' from abc")
'Dump Records from Table
strOutput = "Please Check This Report :" & vbCrLf
nRec = 1
Do While Not oRS.EOF
strOutput = strOutput & "----- " & nRec & " -----" & vbCrLf
nRec = nRec + 1
For Each oFld In oRS.Fields
strOutput = strOutput & oFld.Name & " = " & oFld.Value & vbCrLf
Next
oRS.MoveNext
Loop
SendEmail strOutput
'WScript.Echo "Script Finished"
'This function sets up DB Connection using specified DSN
Function DBConnect
Set objDB = CreateObject("ADODB.Connection")
objDB.Open "DSN=SQL;uid=sa;pwd=12345"
'Set Conn = Server.CreateObject("ADODB.Connection")
'Conn.open "SQL","sa","12345"
Set DBConnect = objDB
End Function
Sub SendEmail(strBody)
'Create Objects
Set objConfig = CreateObject("CDO.Configuration")
Set objEmail = CreateObject("CDO.Message")
'Prepare email configuration
With objConfig.Fields
.Item(CDO_SCHEMA & "sendusing") = strSendMethod
.Item(CDO_SCHEMA & "smtpserver") = strSmtpServer
.Item(CDO_SCHEMA & "smtpserverport") = intSmtpPort
.Item(CDO_SCHEMA & "smtpconnectiontimeout") = intSmtpTimeout
.Item(CDO_SCHEMA & "smtpauthenticate") = strAuthenticationMethod
If.Item(CDO_SCHEMA & "smtpauthenticate") <> 0 Then
.Item(CDO_SCHEMA & "sendusername") = strUsername
.Item(CDO_SCHEMA & "sendpassword") = strPassword
.Item(CDO_SCHEMA & "smtpusessl") = strUserSSL
End If
.Update
End With
'Create email and send
With objEmail
Set.Configuration = objConfig
.To = strTo
If strCC <> "" Then
.CC = strCC
End If
If strBCC <> "" Then
.BCC = strBCC
End If
.From = strFrom
.Subject = strSubject
If strBodyType = "HTML" Then
.HTMLBody = strBody
ElseIf strBodyType = "TEXT" Then
.TextBody = strBody
End If
If strAttachment <> "" Then
.AddAttachment strAttachment
End If
If strDSNotification <> 0 And strDSNotification <> 1 Then
.Fields(CDO_MAIL_HEADER & "disposition-notification-to") = strFrom
.Fields(CDO_MAIL_HEADER & "return-receipt-to") = strFrom
.DSNOptions = strDSNotification
.Fields.update
End If
.Send
End With
End Sub
Simply make sending email depend on whether your query returned records or not.
Change this line:
SendEmail strOutput
into this:
If nRec > 1 Then SendEmail strOutput
by putting the following condition
if oRS.RecordCount>0 or oRS is Not Nothing then
you will be able to control the email sending.
try the following:
Const CDO_SCHEMA = "http://schemas.microsoft.com/cdo/configuration/"
Const CDO_MAIL_HEADER = "urn:schemas:mailheader:"
'Method used to send mail
Const CDO_SEND_USING_REMOTE = 2 'Send using Remote SMTP Server
'Security method used on remote SMTP server
Const CDO_ANONYMOUS = 0 'Use no authentication
Const CDO_BASIC = 1 'Use the basic (clear text) authentication
Const CDO_NTLM = 2 'Use the NTLM authentication
'Delivery Status Notifications
Const cdoDSNDefault = 0 'No DSN commands are issued
Const cdoDSNNever = 1 'No DSN commands are issued
Const cdoDSNFailure = 2 'Return a DSN if delivery fails
Const cdoDSNSuccess = 4 'Return a DSN if delivery succeeds
Const cdoDSNDelay = 8 'Return a DSN if delivery is delayed
Const cdoDSNSuccessFailOrDelay = 14 'Return a DSN if delivery succeeds, fails, or is delayed
'Set method of sending
strSendMethod = CDO_SEND_USING_REMOTE
'Remote SMTP Server Settings
strSmtpServer = "smtp.abc.com" 'Name or IP of SMTP Server
intSmtpPort = 25 'SMTP Server Port; typically 25
intSmtpTimeout = 60 'Number of seconds to try establishing a connection to the SMTP Server
strAuthenticationMethod = CDO_ANONYMOUS
'SMTP Server Authentication - IF BASIC or NTLM; NOT needed for ANONYMOUS
strUserName = ""
strPassword = ""
strUserSSL = False 'True if SMTP Server uses SSL; False if Not
'Message Settings
strTo = "asdf#abc.com"
'Separate multiple addresses with a semi-colon (;)
strCC = ""
strBCC = ""
strFrom = "no-reply-SalesInfo#abc.com"
strSubject = "Pending Sales Order - Perlu di follow up"
strBodyType = "TEXT"
strAttachment = "D:\File.txt" 'Attachment Path i.e. C:\Temp\File.txt
strDSNotification = cdoDSNDefault 'Delivery Status Option Change as needed
'WScript.Echo "Connecting to database..."
'Connect to database & select all from Table
Set objDB = DBConnect()
Set oRS = objDB.Execute("SELECT S_ORDER 'SO# ',CUSTOMER_NAME'CUSTOMER ',DATE 'Tanggal ',USERID 'INTERNAL ',CALLING 'Approval from ',LIMIT 'LIMIT ',TERM 'TERM ' from abc")
if oRS.RecordCount>0 or oRS is Not Nothing then
'Dump Records from Table
strOutput = "Please Check This Report :" & vbCrLf
nRec = 1
Do While Not oRS.EOF
strOutput = strOutput & "----- " & nRec & " -----" & vbCrLf
nRec = nRec + 1
For Each oFld In oRS.Fields
strOutput = strOutput & oFld.Name & " = " & oFld.Value & vbCrLf
Next
oRS.MoveNext
Loop
SendEmail strOutput
end if
'WScript.Echo "Script Finished"
'This function sets up DB Connection using specified DSN
Function DBConnect
Set objDB = CreateObject("ADODB.Connection")
objDB.Open "DSN=SQL;uid=sa;pwd=12345"
'Set Conn = Server.CreateObject("ADODB.Connection")
'Conn.open "SQL","sa","12345"
Set DBConnect = objDB
End Function
Sub SendEmail(strBody)
'Create Objects
Set objConfig = CreateObject("CDO.Configuration")
Set objEmail = CreateObject("CDO.Message")
'Prepare email configuration
With objConfig.Fields
.Item(CDO_SCHEMA & "sendusing") = strSendMethod
.Item(CDO_SCHEMA & "smtpserver") = strSmtpServer
.Item(CDO_SCHEMA & "smtpserverport") = intSmtpPort
.Item(CDO_SCHEMA & "smtpconnectiontimeout") = intSmtpTimeout
.Item(CDO_SCHEMA & "smtpauthenticate") = strAuthenticationMethod
If.Item(CDO_SCHEMA & "smtpauthenticate") <> 0 Then
.Item(CDO_SCHEMA & "sendusername") = strUsername
.Item(CDO_SCHEMA & "sendpassword") = strPassword
.Item(CDO_SCHEMA & "smtpusessl") = strUserSSL
End If
.Update
End With
'Create email and send
With objEmail
Set.Configuration = objConfig
.To = strTo
If strCC <> "" Then
.CC = strCC
End If
If strBCC <> "" Then
.BCC = strBCC
End If
.From = strFrom
.Subject = strSubject
If strBodyType = "HTML" Then
.HTMLBody = strBody
ElseIf strBodyType = "TEXT" Then
.TextBody = strBody
End If
If strAttachment <> "" Then
.AddAttachment strAttachment
End If
If strDSNotification <> 0 And strDSNotification <> 1 Then
.Fields(CDO_MAIL_HEADER & "disposition-notification-to") = strFrom
.Fields(CDO_MAIL_HEADER & "return-receipt-to") = strFrom
.DSNOptions = strDSNotification
.Fields.update
End If
.Send
End With
End Sub

Mail details with Entry Id

I have an Outlook mail Entry ID.
I want details of that Entry Id such as To, Subject ,Body, etc.
Emails are still in Inbox not moved anywhere.
Private Sub CommandButton4_Click()
i = 0
j = 1
Dim path, FileName As String
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
Set currentMail = objNameSpace.GetItemFromID("000000000AB85207D8C3664BA439B3CE1603D186070019BED8705003484BACA686B84F9C6E880000006DE67E000019BED8705003484BACA686B84F9C6E880000428CEF9B0000")
MailTo = currentMail.To
MailSubject = currentMail.Subject
MailBody = currentMail.Body
MailDateTime = currentMail.CreationTime
attcount = currentItem.Attachments.Count
For j = 1 To attcount + 1
'FileName = "\\wipfs01\ES Quality\Personal Folders\Mahesh\Tools\Sorting-Telus\Attachment\" & Atmt.FileName
'Atmt.SaveAsFile FileName
Set chk = UserForm2.Controls("chkn" & j)
If chk.Value = True Then
path = SaveAttachment("\\wipfs01\ES Quality\Personal Folders\Mahesh\Tools\Sorting-Telus\Attachment\PO\")
FileName = path & currentItem.Attachments(j).FileName
currentItem.Attachments(j).SaveAsFile FileName
Set currentMail = currentItem
MailTo = currentMail.To
MailSubject = currentMail.Subject
MailBody = currentMail.Body
MailDateTime = currentMail.CreationTime
chk.Visible = False
End If
Next j
'MsgBox MailTo & vbCrLf & MailSubject & vbCrLf & MailBody & vbCrLf & MailDateTime
End Sub
Use Namespace.GetItemFromID to open the message using its entry id.

Application-Defined or Object-Defined Error Using Access

I'm trying to send automated emails through outlook from Access, but I've run into an issue where if a user does not have their email open already, I will get the Application-Defined or Object-Defined Error. I'm using a late binding to avoid the .dll's since I have users on both Office 2003 and Office 2010.
Is there anyway around this error and still allowing the emails to go through? Or possibly "forcing" outlook to open if it is not already?
Thanks in advance
Sure thing, here's the whole code to the email.
When I step through it fails at Set appOutlookRec = .Recipients.Add(myR!Email)
Option Explicit
Function SendEmail(strDep, strIssue, strPriority, strDate, strDesc, wonum, user)
Const olMailItem = 0
Const olTo = 1
Const olCC = 2
Dim sqlVar As String
Dim strSQL As String
If strDep = "Cycle" Then
ElseIf strDep = "Fabrication" Then
sqlVar = "Fabricator"
ElseIf strDep = "Facility" Then
sqlVar = "Facility"
ElseIf strDep = "Gage" Then
sqlVar = "Gage"
ElseIf strDep = "IT" Then
sqlVar = "IT"
ElseIf strDep = "Machine Shop" Then
sqlVar = "Machine_Shop_Manager"
ElseIf strDep = "Safety" Then
sqlVar = "Safety"
ElseIf strDep = "Maintenance" Then
sqlVar = "Maintenance_Manager"
ElseIf strDep = "Supplies Request" Then
sqlVar = "Supplies"
Else:
End If
Dim myR As Recordset
'Refers to Outlook's Application object
Dim appOutlook As Object
'Refers to an Outlook email message
Dim appOutlookMsg As Object
'Refers to an Outlook email recipient
Dim appOutlookRec As Object
'Create an Outlook session in the background
Set appOutlook = CreateObject("Outlook.Application")
'Create a new empty email message
Set appOutlookMsg = appOutlook.CreateItem(olMailItem)
'Using the new, empty message...
With appOutlookMsg
strSQL = "SELECT Email FROM Employees WHERE " & sqlVar & " = True"
Set myR = CurrentDb.OpenRecordset(strSQL)
Do While Not myR.EOF
Set appOutlookRec = .Recipients.Add(myR!Email)
appOutlookRec.Type = olTo
myR.MoveNext
Loop
strSQL = "SELECT Email FROM Employees WHERE '" & user & "' = Username"
Set myR = CurrentDb.OpenRecordset(strSQL)
Set appOutlookRec = .Recipients.Add(myR!Email)
appOutlookRec.Type = olCC
.Subject = wonum
.Body = "Department: " & strDep & vbNewLine & vbNewLine & _
"Issue is at: " & strIssue & vbNewLine & vbNewLine & _
"Priority is: " & strPriority & vbNewLine & vbNewLine & _
"Complete by: " & strDate & vbNewLine & vbNewLine & _
"Description: " & strDesc
.Send
End With
Set myR = Nothing
Set appOutlookMsg = Nothing
Set appOutlook = Nothing
Set appOutlookRec = Nothing
End Function
Try using .Save before .Send. I was scheduling outlook code through MS Access.
After the line Set appOutlook = CreateObject("Outlook.Application"), add the following:
set NS = appOutlook.GetNamespace("MAPI")
NS.Logon
So what appears to be happening is your reference to the Outlook.Application is- well. stagnant- for lack of a better word. You don't just want to create an Outlook Session - you want to connect to an existing running application.
I'm not a pro on Access, so I'll just suggest generalities: Try to Obtain a handle on an already running Outlook Application, otherwise have it open Outlook (Give it time to fully startup using sleep/wait and a DoEvents command) and try again to obtain that handle.
I was using VBA within Outlook attempting to read the sender names (also getting the same error). Traced it down to my method of obtaining the current outlook application handle.
Instead of:
Set appOutlook = CreateObject("Outlook.Application");
I had to:
Set appOutlook = ThisOutlookSession;
Hope this helps!