3061 Error, Too Few Parameters, 2 Expected.
Chain of queries - earliest query at beginning contains "[Enter Area:]" (AREA field in LOCALITY table) and "Enter Year" (e.g. 2015-16) (YEAR field in DATA table) leading to final query containing email addresses.
Want onClick button event to send email but suspect it's not picking up earlier two parameters hence 3061 error - any advice gratefully received.
Private Sub Command566_Click()
'Opens the current access database
Dim db As DAO.Database
Set db = CurrentDb
Dim RS As DAO.Recordset
Dim EmailAdd As String
'Mail Message MM
Dim MM As String
Dim qrySQL As String
Set db = CurrentDb
'Creates the SQL string - query contains just email addresses
qrySQL = "SELECT QRY_N_M109.EMAIL FROM QRY_N_M109;"
'creates a recordset (table) based on the sql Statement above
Set RS = db.OpenRecordset(qrySQL, dbOpenDynaset)
Do Until RS.EOF
'creates the email string by reading the email from each record
EmailAdd = EmailAdd & " ; " & RS!EMAIL
'move next record RS!EMAIL
RS.MoveNext
Loop
'creates Email body in HTML Format
MM = "Dear Delegates,"
MM = MM & "Blah blah blah"
'create new email
Set olook = CreateObject("outlook.application")
Set oMail = olook.createitem(0)
'Set parameters
With oMail
.bcc = EmailAdd
.htmlbody = MM
.subject = "Our title here"
.cc = "address#address.com"
.display
End With
End Sub
You can try to use SetParameter:
' Creates the SQL string - query contains just email addresses.
qrySQL = "SELECT QRY_N_M109.EMAIL FROM QRY_N_M109;"
' Set parameter values.
DoCmd.SetParameter "[Enter Area:]", "'" & InputBox("Enter Area:") & "'"
DoCmd.SetParameter "[Enter Year:]", "" & InputBox("Enter Year:") & ""
' Creates a recordset (table) based on the sql Statement above.
Set RS = db.OpenRecordset(qrySQL, dbOpenDynaset)
Related
I am trying to open form X through form Y, where docid = docid
form X's table has a primary key column named "abcid" (the matching id)
I am trying to pass the label name of form Y's textbox's label "abcid" as string "abcid", the idea is to pass the column name dynamically whatever the used form is ==> in VBA OpenForm WHERE condition, but it doesn't execute properly or opens a blank form. code below:
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim checklistformName As String
Dim viewdocformName As String
Dim currentformName As String
currentformName = Screen.ActiveForm.Name
'Debug.Print currentformName
Dim docidcolumnName As String
docidcolumnName = Forms(currentformName).Controls(docid).Caption
Debug.Print docidcolumnName
Set rs1 = CurrentDb.OpenRecordset("SELECT DISTINCT checklistformname FROM CyclesDefinitions WHERE cycledefid = " & Forms(currentformName)![cycledefid])
Do Until rs1.EOF = True
checklistformName = rs1(0)
rs1.MoveNext
Loop
rs1.Close
Set rs1 = Nothing
Set rs2 = CurrentDb.OpenRecordset("SELECT DISTINCT viewdocformname FROM CyclesDefinitions WHERE cycledefid = " & Forms(currentformName)![cycledefid])
Do Until rs2.EOF = True
viewdocformName = rs2(0)
rs2.MoveNext
Loop
rs2.Close
Set rs2 = Nothing
Debug.Print currentformName & " - " & checklistformName & " - " & viewdocformName
DoCmd.OpenForm viewdocformName, , , " & docidcolumnname & " = " & Forms(checklistformName)![docid], acFormReadOnly
alright, I solved the OpenForm with string dilemma with the following solution after testing a statically predefined string:
DoCmd.OpenForm viewdocformName, , , "" & docidcolumnName & " = " & Forms(checklistformName)![docid], acFormReadOnly
it just needed the proper concatenation, and instead of messing with the forms!frmname syntax, because I can't find the proper return value, I set the label name on form to pkcolname and recalled it in VBA like this:
docidcolumnName = Me.pkcolname.Caption:
now everything is working as expected and required.
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'm trying to open a record set using a SQL string. I get run time error 3061 "Too Few Parameters." any help would be appreciated.
Dim stAppName As String
Dim stURL As String
Dim rst As Recordset
Dim dbs As Database
Dim stringToSearch As Integer
Dim strSQL As String
Set dbs = CurrentDb
stringToSearch = InputBox("What is your route #?", "Enter route #: ")
strSQL = "SELECT ESRP.* FROM ESRP WHERE ESRP.Route=stringToSearch"
Set rst = dbs.OpenRecordset(strSQL)
Please change the code line of strSQL as follows, as suggested by Fionnuala you need to use variable outside the quotes.
Assuming Route field is Text data type, we need to put single quote for strings, if its number no single quote, for dates put # instead of single quote
strSQL = "SELECT ESRP.* FROM ESRP WHERE ESRP.Route='" & stringToSearch & "'"
It's a little sample, maybe it can help you
Public Function fn_SQL_dbOpenRecordset(Optional vsql As String = "") As Recordset
Dim dbs As DAO.Database
Dim rs As Recordset
On Error GoTo END_CODE
'Set the database
Set dbs = CurrentDb
Set rs = dbs.OpenRecordset(vsql, dbOpenForwardOnly) 'you can use: dbOpenDynamic; dbOpenSnapshot; dbOpenTable
Set fn_SQL_dbOpenRecordset = rs
Exit Function
END_CODE:
Set fn_SQL_dbOpenRecordset = Nothing
End Function
Public Sub Program_Test()
On Error GoTo ERROR_SUB
Dim rs As Recordset
Dim sName As String
sName = "Joe"
sName = "'" & sName & "'" 'WARNING: BE CAREFUL WITH SQL INJECTION !!! Google it
Set rs = fn_SQL_dbOpenRecordset("select * from table1 d where PersonName = " & sName)
Dim i As Long
i = 0
While Not rs.EOF
Debug.Print rs(0).Value & " - " & rs(1).Value
rs.MoveNext
Wend
ERROR_SUB:
On Error Resume Next
If Not rs Is Nothing Then rs.Close
Set rs = Nothing
End Sub
first off I am brand new to iMacros and not great with VBA (I know not a great start)
So my end game is to use iMacros to go to a site fill in a form on the site with a name from a table in access enter the name and grab some resulting text from that site grab the text and put it in a table. I will have to do this for each record in the table. So far this is what I have:
Dim Rs As DAO.Recordset 'recordset for list of names from VcWAuditUsers
Dim db As DAO.Database
Dim SQL As String
Dim Sql2 As String
Dim STRErr As String
Dim sTableName As String
Dim serverName As String
Dim dbName As String
Dim strUserCnt As Integer
Dim UserName As Variant
Dim StrSql As String
Dim iim1, iret
Set iim1 = CreateObject("imacros")
iret = iim1.iimInit
iret = iim1.iimPlayCode("URL GOTO=https://www.sam.gov/portal/public/SAM/)
sTableName = "vCPpAuditUsers"
serverName = GetLinkedServer(sTableName)
dbName = GetLinkedDatabase(sTableName)
SQL = "Select Distinct FName, LName from " & sTableName
Set db = CurrentDb
Set Rs = db.OpenRecordset(SQL)
If (Not Rs.EOF And Not Rs.BOF) Then
Rs.MoveLast
Rs.MoveFirst
With Rs
Do While (Rs.EOF = False)
UserName = Trim(![FName]) & " " & Trim(![LName])
MsgBox ("New Name: " & UserName)
strUserCnt = Rs.recordCount
MsgBox ("Number of rows: " & strUserCnt)
'set iMacros variables
iret = iim1.iimSet("CONTENT", UserName)
iret = iim1.iimPlay("Y:\Data\FS01-M\Healthcare\SAM_iMacro\SAMiMacro.iim")
If iret < 0 Then
MsgBox iim1.iimGetLastError()
End If
StrSql = "Insert Into ExceptionResults Values('" & UserName & "','" & iim1.iimGetExtract(1) & Now & "')"
MsgBox ("Test SqlInsert: " & StrSql)
.MoveNext
Loop
End With
Rs.Close
db.Close
End If
I know that I am missing some key stuff but I have been unable to find a good example to base what I am doing on.
Any help is greatly appreciated!
Thanks.
What I came up with:
Option Compare Database
Option Explicit
Private Sub cmdGetExceptions_Click()
Dim YNMess As String
YNMess = MsgBox("Do you wish to truncate results table ExceptionResults?", vbYesNo, "TRUNCATE?")
If YNMess = vbYes Then
Call ClearExceptionTable
Call RunExceptionTable
End If
If YNMess = vbNo Then
Call RunExceptionTable
End If
End Sub
Private Sub RunExceptionTable()
Dim Rs As DAO.Recordset 'recordset for list of names from VcWAuditUsers
Dim db As DAO.Database
Dim SQL As String
Dim sTableName As String
Dim serverName As String
Dim dbName As String
Dim strUserCnt As Integer
Dim UserName As Variant
Dim StrSql As String
Dim ExceptStat As String
On Error GoTo ErrHandler
Dim iim1, iret
' Creates iMacros object and gives the starting webpage
Set iim1 = CreateObject("imacros")
iret = iim1.iimInit
iret = iim1.iimPlayCode("URL GOTO=https://www.sam.gov/)
'Sets the source table name
sTableName = "[SourceTable]"
'Sets the SQL string to grab the names of people to be inserted into website input section
SQL = "Select Distinct FName, LName from " & sTableName
'Starts the recordset for the source table and recordset
Set db = CurrentDb
Set Rs = db.OpenRecordset(SQL)
'resets the RS to start at the begining
If (Not Rs.EOF And Not Rs.BOF) Then
Rs.MoveLast
Rs.MoveFirst
'Grabs the total record count to use for end user messaging.
strUserCnt = Rs.recordCount
'MsgBox ("Number of rows: " & strUserCnt)
'Opens RS and starts while loop to open first record of the source table
With Rs
Do While (Rs.EOF = False)
'Creates new UserName by combining first and last name
UserName = Trim(![FName]) & " " & Trim(![LName])
'MsgBox ("New Name: " & UserName)
'set iMacros variables This subs the spot in the iMacros code where you manually entered information (there should be {{USERNAME}} in the iMacros where you want to enter data.
iret = iim1.iimSet("USERNAME", UserName)
'Plays the iMacro you recorded and altered earlier.
iret = iim1.iimPlay("Location of your iMacros goes here.iim")
'Checks for errors in the iMacros(anything in the negative is considered an error)
If iret < 0 Then
MsgBox iim1.iimGetLastError()
End If
'grabs the extracted data from recorded iMacro. the extracted data is stored in an (1) based array. Makes substitutions for the text that it extracts to convert to 1 or 0
If Left(iim1.iimGetExtract(1), 2) = "No" Then
ExceptStat = 0
Else
ExceptStat = 1
End If
'For each record in the source the extracted data is entered into the insert statement below along with the employee name and date. then warnings are suppressed and each is inserted into a local access table, Loop and move to the next.
StrSql = "Insert Into ExceptionResults Values('" & UserName & "'," & ExceptStat & ",'" & Now & "')"
DoCmd.SetWarnings False
DoCmd.RunSQL (StrSql)
DoCmd.SetWarnings True
.MoveNext
Loop
End With
MsgBox ("ExceptionResults table is complete and has " & strUserCnt & " Records")
'Clean up
Rs.Close
db.Close
End If
'Clean up
Set db = CurrentDb
Set Rs = db.OpenRecordset(SQL)
Set iim1 = Nothing
strUserCnt = 0
ErrHandler:
MsgBox "ERROR" & vbCrLf & Err.Description, vbCritical, "CmdGetExceptions"
End Sub
Private Sub ClearExceptionTable()
Dim StrSql2 As String
StrSql2 = "Delete from ExceptionResults"
DoCmd.SetWarnings False
DoCmd.RunSQL (StrSql2)
DoCmd.SetWarnings True
MsgBox ("All records from ExceptionResults have been truncated")
End Sub
Database Structure:
UserName String
Location String
Price Number
Requirement:
I have listbox with some items into it say 100. The user will select only 10 randomly in the listbox (after changing the MULTISELECT to 2fmMultiselect property). I will have search button. Once I select and click Search, the total price of selected items has to be calculated and displayed.
My search code ( Thanks to Alex sir)
enter code here
Private Sub CommandButton4_Click()
Dim Cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sName As String
Set Cn = New ADODB.Connection
Cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=d:\test2.accdb;Persist Security Info=False"
Cn.ConnectionTimeout = 40
Cn.Open
Set rs = New ADODB.Recordset
sName = Replace$(TextBox1.Text, "'", "''")
rs.Open "Select * from SampleTable where UserName = '" & sName & "'", Cn, adOpenForwardOnly, adLockReadOnly, adCmdText
If (rs.EOF) Then
MsgBox "no match"
Else
TextBox3.Text = rs("UserName") & " " & rs("Location")
rs.Close
End If
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
That code was just to search and display in a textbox.
Now, I need to total the price of what all UserName field selected by the user from listbox.
Try this, but make sure the bound column in your list box is the ID field of your table.
Private Function SelectedListString(lstSelected As Access.ListBox) As String
'Loop though a list and get the IDs of all the selected items
'Assumes the bound column is the contains the ID field
Dim sList As String
Dim vSelected As Variant
With lstSelected
For Each vSelected In .ItemsSelected
sList = sList & .ItemData(vSelected) & ","
Next
End With
If sList <> "" Then sList = Left(sList, Len(sList) - 1) 'trim trailing coma
SelectedListString = sList
End Function
you can use the result in an IN statement in your SQL
Dim sSql As String
If myListbox.ItemsSelected.Count > 0 Then
sSql = "SELECT * FROM table WHERE IDField IN (" & SelectedListString(myListbox) & ")"
End If