My query does not return any values even though the table has the records. I am trying to retrieve an employeed id based on the name entered. I keep getting the message "No employee id". I am a new learner as far as Access VBA is concerned. I have worked with Access tables and other tables without issues. I did validate that the form field has the correct value and is being captured in the variable strEmpName
Set cnn1 = New ADODB.Connection
mydb = "C:\accesssamp\Documents\Tasks.accdb"
strCnn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & mydb
cnn1.Open strCnn
'This statement added here just to indicate that I am getting the value
strEmpName = cboEmployeeName.Text ' Getting employee name from form field
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = CurrentProject.Connection
.CommandText = "SELECT [EmployeeId] FROM [Employees] " & _
"WHERE [EmployeeName] = [strEmpName]"
.CommandType = adCmdUnknown
.Parameters.Append cmd.CreateParameter( _
"[strEmpName]", adChar, adParamInput, 50)
.Parameters("[strEmpName]") = strEmpName
End With
' Execute the Query and return the employeeId
Set rstEmp = cmd.Execute
If rstEmp.RecordCount < 1 Then
MsgBox "No Employee Id"
Else
MsgBox rstEmp(0).Value
End If
Your sample had multiple issues. I'm unsure whether this is exactly what you want, but it works without error on my system.
With cmd
'.ActiveConnection = CurrentProject.Connection
.ActiveConnection = cnn1
.CommandText = "SELECT [EmployeeId] FROM [Employees] " & _
"WHERE [EmployeeName] = [strEmpName]"
.CommandType = adCmdUnknown ' or adCmdText; either works
.Parameters.Append cmd.CreateParameter( _
"strEmpName", adVarChar, adParamInput, 255, strEmpName)
End With
' Execute the Query and return the employeeId
Set rstEmp = cmd.Execute
'If rstEmp.RecordCount < 1 Then
If rstEmp.BOF And rstEmp.EOF Then
MsgBox "No Employee Id"
Else
MsgBox rstEmp(0).value
End If
Notes:
I assumed you want to run your query from the cnn1 connection to that other database instead of from CurrentProject.Connection.
Supply a compatible data type for CreateParameter. And for a text parameter, supply a value for its maximum length. Finally include the value for the parameter.
rstEmp.RecordCount was returning -1, which is less than 1, so your code displayed "No Employee Id" even when the recordset was not empty. Instead of checking RecordCount, check whether the recordset is empty.
Related
I currently have the below VBA to insert new records into my SQL Server from Excel.
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sCustomerId, sFirstName, sLastName As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;Data Source=AUSWIDECUSTOMERS\SQL2012;Initial Catalog=Customers;Integrated Security=SSPI;"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
sCustomerId = .Cells(iRowNo, 1)
sFirstName = .Cells(iRowNo, 2)
sLastName = .Cells(iRowNo, 3)
'Generate and execute sql statement to import the excel rows to SQL Server table
conn.Execute "insert into dbo.Customers (CustomerId, FirstName, LastName) values ('" & sCustomerId & "', '" & sFirstName & "', '" & sLastName & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
End Sub
What I am wanting to do is if anything changes with the sCustomerId record I inserted that I can come back in and update it.
So for example
current data set:
sCustomerId = 15 sFirstName = David SLastName = Smith
So from excel I want it to be able type in sCustomerID = 15 then update the record SLastName = Warner
Any ideas on how to make this change would be great.
Something like this should work.
In the example only prints the SQL in the Immediate Pane of the debugger. Since the OP is already familiar with reading from the database, updating it is left to the OP.
Updated to actually update the database.
The code presented below should be in the worksheet module for the worksheet containing the data.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rChangableData As Range
Dim rUpdatedData As Range
' Column headings A1, B1, C1
' CustomerId in Column A
' Range of data that can affect the change B2:C100
' This would be better implemented as a named range,
' but it is less transparent in the source code what it refers to
' * Simply entering a CustomerId, does not add a row
Set rChangableData = Me.Range("B2:C100")
' rUpdatedData is the range of changed data (Target),
' intersecting with the range of changable data (rChangeableData).
' If the two ranges do not intersect, rUpdatedData is Nothing and the event can be ignored
Set rUpdatedData = Intersect(rChangableData, Target)
If Not rUpdatedData Is Nothing Then
' Iterate over the range of changed data
' Obtain the CustomerId, FirstName and LastName values from the worksheet
' Provide to functions to perform the updates
' Also added a delete function where there is a CustomerId and no values for FirstName and LastName
Dim numRows As Long
Dim rowcounter As Long
Dim firstRow As Long
Dim lastRow As Long
Dim result As Integer
' Since the code needs to refer back to data on the worksheet,
' it keeps track of the row numbers in on the worksheet, rather than the changed data
numRows = rUpdatedData.Rows.Count
firstRow = Target.Row - rChangableData.Row + 1
rowcounter = firstRow
lastRow = firstRow + numRows
While rowcounter < lastRow
Dim CustomerId As Long
Dim FirstName As String
Dim LastName As String
Dim sql As String
CustomerId = rChangableData.Offset(0, -1).Cells(rowcounter, 1)
FirstName = rChangableData.Cells(rowcounter, 1)
LastName = rChangableData.Cells(rowcounter, 2)
If Trim(CustomerId) <> "" And Trim(FirstName) <> "" And Trim(LastName) <> "" Then
' The data has changed and there are non-blank values for CustomerId, FirstName and LastName;
' insert or update the customer
result = Customer_Update(CustomerId, FirstName, LastName)
If result = 0 Then
MsgBox "No rows were inserted or updated.", vbExclamation, "Customer Update"
Else
If result > 1 Then
MsgBox "Multiple rows were updated.", vbExclamation, "Customer Update"
End If
End If
Else
If Trim(CustomerId) <> "" And Trim(FirstName) = "" And Trim(LastName) = "" Then
' The data has changed and there is a non-blank value for CustomerID and
' blank values for FirstName and LastName;
' delete the customer
Customer_Delete CustomerId
If result = 0 Then
MsgBox "No rows were deleted", vbExclamation, "Customer Delete"
End If
End If
End If
rowcounter = rowcounter + 1
Wend
End If
End Sub
The code presented below should be in separate module in the same VBA project. This code handles connecting to and updating the customers.
Option Explicit
Private Function CreateSQLConnection() As ADODB.Connection
' Create an ADODB Connection.
' Settings depend on your own specific environment
Dim provider As String
Dim source As String
Dim database As String
Dim credentials As String
Dim connectionString As String
Dim sqlConn As ADODB.Connection
' Original Connection String
' "Provider=SQLOLEDB;Data Source=AUSWIDECUSTOMERS\SQL2012;Initial Catalog=Customers;Integrated Security=SSPI;"
provider = "SQLOLEDB"
source = "AUSWIDECUSTOMERS\SQL2012"
database = "Customers"
credentials = "Integrated Security=SSPI"
connectionString = "" & _
"Provider=" & provider & ";" & _
"Data Source=" & source & ";" & _
"Initial Catalogue=" & database & ";" & _
credentials & ";"
Set sqlConn = New ADODB.Connection
sqlConn.Open connectionString
sqlConn.DefaultDatabase = database
Set CreateSQLConnection = sqlConn
End Function
Public Function Customer_Update(CustomerId As Long, FirstName As String, LastName As String) As Integer
' Update or Insert a customer.
' * Creates a connection
' * Performs an update to the customer
' * Checks the number of rows affected
' * If no rows are affected, inserts the customer instead
Dim sqlConn As ADODB.Connection
Dim sqlCmd As ADODB.Command
Dim sqlParam As ADODB.Parameter
Dim rowsUpdated As Long
Set sqlConn = CreateSQLConnection()
Set sqlCmd = New ADODB.Command
sqlCmd.ActiveConnection = sqlConn
sqlCmd.CommandType = adCmdText
sqlCmd.CommandText = "update customer set FirstName = ?, LastName = ? where CustomerId = ?"
sqlCmd.Parameters.Append sqlCmd.CreateParameter("FirstName", adVarChar, adParamInput, Size:=255, Value:=FirstName)
sqlCmd.Parameters.Append sqlCmd.CreateParameter("LastName", adVarChar, adParamInput, Size:=255, Value:=LastName)
sqlCmd.Parameters.Append sqlCmd.CreateParameter("CustomerId", adInteger, adParamInput, Value:=CustomerId)
sqlCmd.Execute recordsAffected:=rowsUpdated
Set sqlCmd = Nothing
Customer_Update = Handle_UpdateInsertDeleteRows(rowsUpdated)
If Customer_Update = 0 Then
Dim rowsInserted As Long
Set sqlCmd = New ADODB.Command
sqlCmd.ActiveConnection = sqlConn
sqlCmd.CommandType = adCmdText
sqlCmd.CommandText = "insert into customer ( CustomerId, FirstName, LastName ) values ( ?, ?, ? )"
sqlCmd.Parameters.Append sqlCmd.CreateParameter("CustomerId", adInteger, adParamInput, Value:=CustomerId)
sqlCmd.Parameters.Append sqlCmd.CreateParameter("FirstName", adVarChar, adParamInput, Size:=255, Value:=FirstName)
sqlCmd.Parameters.Append sqlCmd.CreateParameter("LastName", adVarChar, adParamInput, Size:=255, Value:=LastName)
sqlCmd.Execute recordsAffected:=rowsInserted
Customer_Update = Handle_UpdateInsertDeleteRows(rowsInserted)
Set sqlCmd = Nothing
End If
sqlConn.Close
Set sqlConn = Nothing
End Function
Public Function Customer_Delete(CustomerId As Long) As Integer
' Delete a customer.
' * Creates a connection
' * Performs an delete on the customer table
Dim sqlConn As ADODB.Connection
Dim sqlCmd As ADODB.Command
Dim sqlParam As ADODB.Parameter
Dim rowsDeleted As Long
Set sqlConn = CreateSQLConnection()
Set sqlCmd = New ADODB.Command
sqlCmd.ActiveConnection = sqlConn
sqlCmd.CommandType = adCmdText
sqlCmd.CommandText = "delete customer where CustomerId = ?"
sqlCmd.Parameters.Append sqlCmd.CreateParameter("CustomerId", adInteger, adParamInput, Value:=CustomerId)
sqlCmd.Execute recordsAffected:=rowsDeleted
Set sqlCmd = Nothing
Customer_Delete = Handle_UpdateInsertDeleteRows(rowsDeleted)
sqlConn.Close
Set sqlConn = Nothing
End Function
Private Function Handle_UpdateInsertDeleteRows(recordsAffected As Long) As Integer
' Returns:
' * 0 for no rows
' * 1 for single row
' * 2 for multi row
Select Case recordsAffected
Case Is <= 0
Handle_UpdateInsertDeleteRows = 0
Case Is = 1
Handle_UpdateInsertDeleteRows = 1
Case Is > 1
Handle_UpdateInsertDeleteRows = 2
End Select
End Function
I'm trying to query a MySQL database from VBA in Excel by means of a stored procedure with some parameters. My problem is that I only get a maximum of one row in my (ADO) resultset. After hours of searching and troubleshooting I have given up. I've done a lot of research online (of course also on SO as there seem to be a lot of related issues, but none of which is mine - as far as I have seen). I can already inform you what does / does not work:
I see a lot about DAO ResultSets where the rs.moveLast has not been called. However, I'm using an ADO resultset, so this is not the problem.
When I use a SELECT * FROM some_table, everything works fine. It is specifically the StoredProcedure call that gives me headaches. :)
the parameters passed are valid. When I change them, I do see a different (and correct) result, though just one record. (the SP also check the validity and will change them when empty). I have even implemented special Debug stored procedures and a logging table in the database to log the passed parameters and the way they are handled. All is fine there.
when I run the same SP manually with the same parameters, I get 3 records.
I have changed the CursorLocation via the ADODB.Connection object to adUseClient and I've tried different means of retreiving the resultset (via the ADODB.ResultSet.Open method, via the ADODB.Connection object, via the PreparedStatement). The result stays the same. The CursorType is adOpenStatic (With a different CursorType, the recordCount would give me -1).
I have checked for multiple result sets (there shouldn't be any) and there are none extra.
In an attempt to provide a Minimal Reproducible Example I've created a new sample Stored Procedure with some testdata, which gives me exactly the same results (i.e. only one row of the table that I would get running the query in HeidySQL or MySQL Workbench):
for instance:
When I enter "S8" in B2 (without the quotes), I should expect three rows - on a new sheet in the same workbook (in line with the data set given below, the result should be: {{S8, apple, red}, {S8, grapes, white}, {S8, banana, yellow}}). Instead, I only get {S8, grapes, white} - strangely enough, this would be the middle record in both SQL clients?
Option Explicit
Enum enums 'necessary because of late binding
adUseClient = 3 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/cursorlocationenum?view=sqlallproducts-allversions
adCmdStoredProc = 4 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/commandtypeenum?view=sqlallproducts-allversions
adVarChar = 200 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum?view=sqlallproducts-allversions
adParamInput = 1 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/parameterdirectionenum?view=sqlallproducts-allversions
End Enum
Sub excelmysql()
Dim conn As Object
Dim spCommand As Object
Dim param1 As Object
Dim rs As Object
Set conn = CreateObject("ADODB.Connection")
Set spCommand = CreateObject("ADODB.Command")
Set param1 = CreateObject("ADODB.Parameter")
Set rs = CreateObject("ADODB.Recordset")
' conn.CursorLocation = adUseClient
conn.Open "DRIVER={MySQL ODBC 8.0 Unicode Driver}" _
& ";SERVER=" & credentials.getServer _
& ";DATABASE=" & credentials.getDB _
& ";UID=" & credentials.getUsername _
& ";PWD=" & credentials.getPassword
' Set spCommand = New ADODB.Command
spCommand.Prepared = True
spCommand.CommandText = "`testProc`"
spCommand.CommandType = adCmdStoredProc
spCommand.CommandTimeout = 30
spCommand.ActiveConnection = conn
Set param1 = spCommand.CreateParameter("inputCode", adVarChar, adParamInput, 2, Range("B1").Value)
spCommand.Parameters.Append param1
Set rs = spCommand.Execute()
Sheets.Add
ActiveSheet.Range("A2").CopyFromRecordset rs
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Sub
To be complete, here is my SQL SP (which runs just fine):
To define a testing table:
CREATE TABLE `testTable` (
`someCode` VARCHAR(2) NOT NULL COLLATE 'utf8mb4_general_ci',
`text` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
`color` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci'
)
COMMENT='testTable meant for testing'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
To fill the testing table:
INSERT INTO db.`testTable`
(`someCode`, `text`, `color`)
VALUES
('S8', 'apple', 'red'),
('S8', 'banana', 'yellow'),
('PB', 'car', 'black'),
('S8', 'grapes', 'white'),
('TR', 'car', 'purple'),
('PB', 'car', 'orange');
and finally, to add a Stored Procedure:
DELIMITER //
CREATE DEFINER=`admin`#`%` PROCEDURE `testProc`(IN `inputCode` VARCHAR(2))
LANGUAGE SQL
DETERMINISTIC
READS SQL DATA
SQL SECURITY DEFINER
COMMENT 'test procedure'
BEGIN
DECLARE validCode varchar(1);
SET validCode = IF((COALESCE(inputCode, '') = '') OR (inputCode = '0'), 'N', 'Y');
SELECT * FROM db.`testTable`
WHERE (`someCode` LIKE if(validCode = 'Y', inputCode, '%'))
ORDER BY `color` ASC;
END //
DELIMITER ;
Online Demo
I'm grateful for any help, since I'm at a loss.
Please find an alternative way of retrieving the rows (which does not change the outcome unfortunately):
Option Explicit
Enum enums 'necessary because of late binding
adUseClient = 3 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/cursorlocationenum?view=sqlallproducts-allversions
adOpenStatic = 3 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/cursortypeenum?view=sqlallproducts-allversions
adCmdStoredProc = 4 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/commandtypeenum?view=sqlallproducts-allversions
adVarChar = 200 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum?view=sqlallproducts-allversions
adParamInput = 1 'https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/parameterdirectionenum?view=sqlallproducts-allversions
End Enum
Sub excelmysql()
Dim conn As Object
Dim spCommand As Object
Dim param1 As Object
Dim rs As Object
Set conn = CreateObject("ADODB.Connection")
Set spCommand = CreateObject("ADODB.Command")
Set param1 = CreateObject("ADODB.Parameter")
Set rs = CreateObject("ADODB.Recordset")
conn.CursorLocation = adUseClient
conn.Open "DRIVER={MySQL ODBC 8.0 Unicode Driver}" _
& ";SERVER=" & credentials.getServer _
& ";DATABASE=" & credentials.getDB _
& ";UID=" & credentials.getUsername _
& ";PWD=" & credentials.getPassword
' Set spCommand = New ADODB.Command
spCommand.Prepared = True
spCommand.CommandText = "`testProc`"
spCommand.CommandType = adCmdStoredProc
spCommand.CommandTimeout = 30
spCommand.ActiveConnection = conn
Set param1 = spCommand.CreateParameter("inputCode", adVarChar, adParamInput, 2, Range("B1").Value)
spCommand.Parameters.Append param1
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
On Error Resume Next
On Error GoTo 0
If (MsgBox("This will clear Sheet: ""test"" in the activeWorkbook if it exists. Do you wish to continue?", vbYesNoCancel + vbExclamation, "Delete Sheet test?") = vbYes) Then
Sheets("test").Delete
If Err <> 0 Then
Err.Clear
End If
Else
MsgBox "User cancelled execution. Please rename your sheet 'test' to something else if it exists and try again.", vbOKOnly + vbInformation, "Execution stopped"
conn.Close
Exit Sub
End If
Set rs = spCommand.Execute()
Sheets.Add after:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = "test"
Dim row As Long
Dim i As Long
row = 1
rs.moveLast
rs.moveFirst
Do While Not rs.EOF
For i = 0 To rs.Fields.Count - 1
If (row = 1) Then
Sheets("test").Cells(row, i + 1) = rs.Fields.Item(i).Name
Else
Sheets("test").Cells(row, i + 1) = rs.Fields.Item(i).Value
End If
Next
If (row > 1) Then
rs.moveNext
End If
row = row + 1
Loop
' ActiveSheet.Range("A2").CopyFromRecordset rs
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Sub
Thank you for your time!
Cheers,
Niels
I am creating an interface where users can use excel to seamlessly alter an SQL database. I can retrieve data fine however when updating records I get an 'invalid parameter type'.
It works fine with just concatenating values into the query, however to prevent SQL injections I require a parameterised query. I have tried substituting in the ADO datatype with the value however this has not changed anything. I have tried unnamed parameters which just always submits a value of 16 to the database instead of the desired string value
Private Sub Worksheet_Change(ByVal Target As Range)
ID = Cells(Target.Row, 1).Value
Dim locValue As String
locValue = Cells(Target.Row, 2).Value
Dim Cm As ADODB.Command
Set Cm = New ADODB.Command
Cm.NamedParameters = True
Cm.CommandText = "UPDATE issues SET " _
& "location = #location " _
& "WHERE id = " & ID
Dim locationParameter As ADODB.Parameter
Set locationParameter = Cm.CreateParameter("#location", adVarChar, adParamInput, 255)
Cm.Parameters.Append locationParameter
locationParameter.Value = locValue
SqlConnection(Cm)
End Sub
(I am aware that ID is not yet parameterized, the issue is with the location)
Public Function SqlConnection(Cm As ADODB.Command) As ADODB.Recordset
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Server_Name = "127.0.0.1" ' Enter your server name here
Database_Name = "issues_and_outages" ' Enter your database name here
User_ID = "root" ' enter your user ID here
Password = "password" ' Enter your password here
Set Cn = New ADODB.Connection
Cn.Open "Driver={MySQL ODBC 8.0 ANSI Driver};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
Cm.CommandType = adCmdText
Cm.ActiveConnection = Cn
Set SqlConnection = Cm.Execute
End Function
The server is MySQL with an issues_and_outages table, having columns with:
id (integer, unsigned, key, auto_increment)
location (varchar(255), nullable)
When updating a cell, which should update the location column, an error of
"Run-time error '-2147217887 (80040e21)':
[MySQL][ODBC 8.0(a) Driver][mysqld-8.0.16] Invalid parameter type"
is given, with an error on the Cm.Execute line. However the database has a column of type varchar of size 255, which should be an adVarChar so I do not expect an error.
As regularly discussed and concluded with this SO answer, the ADO API for most providers/drivers does not support named parameters for non-stored procedure SQL statement. Instead use the qmark, positional parameter style.
Set Cm = New ADODB.Command
With Cm
.ActiveConnection = Cn
.CommandType = adCmdText
.CommandText = "UPDATE issues SET location = ? WHERE id = ?"
.Parameters.Append .CreateParameter("loc_param", adVarChar, adParamInput, 255, locValue)
.Parameters.Append .CreateParameter("id_param", adInteger, adParamInput,, ID)
.Execute
End With
I have a access table that I am doing a search by date range on. In the form I have a text box TxtTotal that I want to display the number of records in the filtered range the code I have. keeps giving me the complete number of records and not the range filtered.
This is my module
Function FindRecordCount(strSQL As String) As Long
Dim db As Database
Dim rstRecords As Recordset
'On error GoTo ErrorHandler
Set db = CurrentDb
Set rstRecords = db.OpenRecordset("TblPurchases")
If rstRecords.EOF Then
FindRecordCount = 0
Else
rstRecords.MoveLast
FindRecordCount = rstRecords.RecordCount
End If
rstRecords.Close
db.Close
Set rstRecords = Nothing
Set db = Nothing
End Function
This is my code for the TxtTotal text box on the form
Sub Search()
Dim strCriteria, task As String
Me.Refresh
If IsNull(Me.TxtPurchaseDateFrom) Or IsNull(Me.TxtPurchaseDateTo)
Then
MsgBox "Please enter the date range", vbInformation, "Date Range
Required"
Me.TxtPurchaseDateFrom.SetFocus
Else
strCriteria = "([Date of Purchase] >= #" & Me.TxtPurchaseDateFrom &
"# and [Date of Purchase] <= #" & Me.TxtPurchaseDateTo & "#)"
task = "select * from TblPurchases where( " & strCriteria & ") order
by [Date of Purchase] "
DoCmd.ApplyFilter task
Me.TxtTotal = FindRecordCount(task)
End If
End Sub
the results keeps giving me the complete number of records and not the range filtered.
I believe the main issue is this line:
Set rstRecords = db.OpenRecordset("TblPurchases")
You are setting the Record set to use the table as its source instead of your SQL string. No matter what your input dates are, if you are looking at the whole table, it will return the whole table xD.
As for finding the total count of items from a query result, it might make sense to use the SQL COUNT function eg: SELECT COUNT(<Column>) FROM <table> WHERE <criteria>; This will provide you the number of data entries that are provided from that query.
I would also recommend using the QueryDef Object for your SQL definitions since it makes things a little cleaner. But again, this is just a recommendation EG:
Function FindRecordCount(dateFrom As Date, dateTo As Date) As Long
Dim db As DAO.Database
Dim QDF As DAO.QueryDef
Dim rstRecords As DAO.Recordset
Dim SQL As String
SQL = "SELECT COUNT(*) FROM TblPurchase WHERE([Date of Purchase] >= ##dateFrom# AND [Date of Purchase] <= ##dateTo#)"
Set db = CurrentDb
Set QDF = db.QuerDefs(SQL)
QDF.Paramaters("#dateFrom").Value = dateFrom
QDF.Paramaters("#dateTo").Value = dateTo
Set rstRecords = QDF.OpenRecordset("TblPurchases")
If rstRecords.EOF Then
FindRecordCount = 0
Else
rstRecords.MoveLast
FindRecordCount = rstRecords.RecordCount
End If
rstRecords.Close
QDF.Close
db.Close
Set rstRecords = Nothing
Set QDF = Nothing
Set db = Nothing
End Function
Best Regards.
You could replace all this with a DCount expression in the ControlSource of the textbox txtTotal:
=DCount("*","TblPurchase ","[Date of Purchase] Between #" & Format(Nz(Me!TxtPurchaseDateFrom.Value,Date()), "yyyy\/mm\/dd") & "# And #" & Format(Nz(Me!TxtPurchaseDateTo.Value,Date()), "yyyy\/mm\/dd") & "#")
How do you insert multiple values into a Lookup Field in an Access database using ASP?
(I've tried a few approaches, so I'm not even sure which code to show as an attempt.)
For a sample table named [Agents] with a multi-value Lookup Field named [Languages] ...
the following VBScript code represents one way to add a new Agent named "Maria" who speaks both English and Spanish
Option Explicit
Dim con, cmd, rst, newID
Const adInteger = 3
Const adVarWChar = 202
Const adParamInput = 1
Const adOpenStatic = 3
Const adLockOptimistic = 3
Set con = CreateObject("ADODB.Connection")
con.Open _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Users\Public\Database1.accdb"
' insert all fields *except* multi-value Lookup Field
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandText = "INSERT INTO Agents (AgentName) VALUES (?)"
cmd.Parameters.Append cmd.CreateParameter("?", adVarWChar, adParamInput, 255, "Maria")
cmd.Execute
Set cmd = Nothing
' get AutoNumber ID of newly-inserted record
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT ##IDENTITY", con, adOpenStatic, adLockOptimistic
newID = rst(0).Value
rst.Close
Set rst = Nothing
' insert multi-value Lookup Field values
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandText = "INSERT INTO Agents (Languages.Value) VALUES (?) WHERE AgentID=?"
cmd.Parameters.Append cmd.CreateParameter("?", adVarWChar, adParamInput, 255)
cmd.Parameters.Append cmd.CreateParameter("?", adInteger, adParamInput)
cmd.Prepared = True
cmd.Parameters(1).Value = newID
' first value
cmd.Parameters(0).Value = "English"
cmd.Execute
' second value
cmd.Parameters(0).Value = "Spanish"
cmd.Execute
Set cmd = Nothing
con.Close
Set con = Nothing
While this may answer the immediate requirements of the question, it is important to note that:
Access SQL support for manipulating Lookup Fields is incomplete and can be inconsistent from one development environment to another,
"Microsoft strongly recommends against using Access in web applications" (ref: here), and
Seasoned Access developers recommend against using Lookup Fields (ref: here) except in very specific circumstances (e.g., for integration with SharePoint).