Data type mismatch error in opening Record Set - vba

I wrote the following code in VBA
Option Compare Database
Option Explicit
Private Sub MainButt_Click()
Dim mydb As Database
Dim Frs As DAO.Recordset
Dim Srs As Recordset
Dim strsql As String
strsql = "SELECT * FROM Firstable WHERE TransferDate <'" & Date & "'"
Set Frs = CurrentDb.OpenRecordset(strsql)
Set Srs = CurrentDb.OpenRecordset("secondtable")
and the compiler gives me an error of a data mismatch error
and stops at the line before the end
if i didn't use the where condition every thing goes well
so i need to know where is the error

Your problem is due to the fact that when you concatenate Date into the SQL string, you need to wrap it in octothorpes ("#") rather than single quotes:
strsql="SELECT * FROM Firsttable WHERE TransferDate<" & Format(Date,"\#mm\/dd\/yyyy\#")
In addition, with dates, you need to ensure that they are unambiguous (is 06/07/20 6th July or 7th June), hence the inclusion of the Format. As you are just using the current date, there is actually no need to concatenate the date:
strsql="SELECT * FROM Firsttable WHERE TransferDate<Date();"
Finally, you may run into problems by using Set frs=CurrentDb.openRecordset, as this may go out of scope. Far better to declare a database object, and then use that:
Dim db As DAO.Database
Set db=DBEngine(0)(0)
Set frs=db.OpenRecordset(strsql)
Regards,

Related

Access subtract form value from another query

In MS Access using VBA trying to subtract a calculated value (time between dates) from a total amount of time in another table.
The query holding the total amount of time is QryScsBatchHandler the field I want to subtract the value from is FreezerLifeUsed and the match condtion is BatchID
The query holding the value I want to subtract is QrySCSMaterialFreezerLog or the form is Frm_MaterialFreezerLog.. the value is AccumilatedTime and the Match condition is Batch ID
Private Sub BkInFrzr_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb()
strSQL = "SELECT FreezerLifeUsed FROM QryScsBatchHandler WHERE [BatchID] = BatchID"
Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
With rst
.MoveFirst
.Edit
FreezerLifeUsed = -AccumilatedTime
.Update
End With
End Sub
I can’t seem to get this simple subtraction to work… any suggestions on what’s not right?
Any help will be greatly appreciated..
At least 3 issues with code.
concatenate reference to form field/control for dynamic criteria in SQL:
strSQL = "SELECT FreezerLifeUsed FROM QryScsBatchHandler WHERE [BatchID] = " & Me.BatchID
The VBA needs to use dot or bang when referencing controls or fields and qualifying with prefix is advised:
!FreezerLifeUsed
Me.AccumilatedTime
Nothing is subtracted from anything, so consider:
!FreezerLifeUsed = !FreezerLifeUsed - Me.AccumilatedTime
However, if query is expected to return only one record, don't bother with loop. Also, instead of opening a recordset, an UPDATE action would work.

How do you use VBA to make a form jump to the nearest future date in Access?

I'm trying to get an MS Access database to open a form either to today's date if it's in the date field in the database, or the nearest date in the future. I tried the code here, but it doesn't work. It just highlights the date field and goes to the first record instead of the nearest one in the future.
The Date field is WorshipDate and the table is wp_elements. (I am a pastor using this table to plan Sunday Worship).
Private Sub Form_Load()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Dim TheDate As Date
Set db = CurrentDb
strSQL = "SELECT TOP 1 * FROM wp_elements WHERE wp_elements.WorshipDate >= Date() ORDER BY wp_elements.WorshipDate;"
Set rst = db.OpenRecordset(strSQL)
TheDate = rst.Fields(0)
WorshipDate.SetFocus
DoCmd.FindRecord TheDate, , True, , True
Set rst = Nothing
Set db = Nothing
'DoCmd.RunCommand acCmdRecordsGoToLast
End Sub
I know the SQL code I included works because I am using it in a Python script that's working quite well.
What am I missing? Or is there some other, easier way to do this?
You should only require one line of code:
me.RecordSet.FindFirst "Date() >= WorshipDate"

VBA TextBox Input for Searching Records Gives Error 3464 Data type mismatch

I have an issue using SQL with OpenRecordset command in VBA in order to run through my data. This is my code:
Dim SQL as string
Dim db As DAO.Database
Dim rs as DAO.Recordset
Dim File as String
Dim i as integer
SQL="SELECT * FROM MyTable WHERE [Manager no]=" & Forms!Form!TxtManagerNo
Set rs=db.OpenRecordset(SQL)
rs.MoveLast
rs.MoveFirst
For i=0 to rs.Recordset-1
File=File & rs.Fields("Code Nu")
rs.MoveNext
Next i
rs.Close
db.Close
It gives me Error 3464 as the data type mismatch. However, if I put the TxtManagerNo value manually, it works perfectly fine:
SQL="SELECT * FROM MyTable WHERE [Manager no]= '443212'"
Could anyone help me with what the issue could be?
Your single quotes in your SQL statement indicates that the expected datatype is not an integer or INT type.
Either change the data type in the database to INT or modify your SQL statement to:
SQL="SELECT * FROM MyTable WHERE [Manager no]='" & Forms!Form!TxtManagerNo &'"
NOTE
Forms!Form!TxtManagerNo is not being sanitised for anything that may be harmful. If you're using MS Access as the back-end, it's not too bad as it'll not accept two statements as once with a semicolon ;. If you're using another database though, you might want to consider using parameters instead.

Get data from Access given only the primary key of the Table

So I have a question regarding data referencing in Access using VBA and SQL. I have a table in my dataset with like 50 columns, and I need to make a query that a user can run that will manipulate the data in like 30 of these columns with a not-so straightforward algorithm. So the query will prompt the user for the primary key and then run a vba function for getting the value that the user wants, I was just wondering if it was possible that It could be done like this
SELECT Hardware_Type,
Func32(Hardware_Type)
FROM Table1
WHERE (([Hardware_Type]) = [Hardware_Type]);
where Hardware_type is the primary key and Func32 is a Visual Basic Function.
So now Func32 only takes Hardware_type as an Input but needs to use 30 pieces of Data that are in the Row of that specific Hardware_Type. I just need to know that does there exist a way to do this and if there does, I would request a hint, because I really don't want to type in 30 different fields in the query and the function. Oh, and all of this is in Microsoft Access!
Thanks in Advance!
You can avoid passing a whole bunch of parameters to your VBA function but it will cost you one database hit for each time the function is called (i.e., once per row in the query that calls the function). Your function could do something like:
Option Compare Database
Option Explicit
Public Function Func32(HardwareType As String) As Variant
Dim cdb As DAO.Database, qdf As DAO.QueryDef, rst As DAO.Recordset
Dim sql As String
Set cdb = CurrentDb
sql = ""
sql = sql & "PARAMETERS prmHardwareType TEXT(255);"
sql = sql & "SELECT * FROM Table1 WHERE Hardware_Type=[prmHardwareType]"
Set qdf = cdb.CreateQueryDef("", sql)
' assign the PK argument as the query parameter and open it as a Recordset
qdf!prmHardwareType = HardwareType
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
' do your calculations and assign the return value to the function name
Func32 = rst!Field1 + rst!Field2 + rst!Field3
rst.Close
Set rst = Nothing
Set qdf = Nothing
Set cdb = Nothing
End Function

Date Subtraction within Select Statement

I am currently working on an MS Access database, and am having problem with date subtraction.
Essentially I am trying to create a target date for example:
Target Date = Deadline - Lead Time
i.e. the lead time could be 30 days, therefore the target date should be 30 days prior to the deadline.
The code I am trying to use is this:
strSQL = "INSERT INTO dbo_DEALER_TASK ( Dlr_Number, Action_Id, Task_Id, Area_Id,
Task_Deadline_Date, Responsible_Person_Id, Alternate_Person_Id, Priority, Comment,
Suppress_Email, Dealer_Type ) "
strSQL = strSQL & "SELECT dbo_DEALER_ACTION.Dlr_Number, dbo_DEALER_ACTION.Action_Id,
qryAllTasksToAdd.Task_Id, qryAllTasksToAdd.Area_Id, Deadline_Date - Deadline_adjustment
AS 'Task_Deadline_Date', qryAllTasksToAdd.Person_Responsible_Id,
qryAllTasksToAdd.Alternate_Responsible_Id, qryAllTasksToAdd.Priority,
qryAllTasksToAdd.Comment, qryAllTasksToAdd.Suppress_Email,
qryAllTasksToAdd.Applies_To_Dealer_Type "
strSQL = strSQL & "FROM dbo_DEALER_ACTION LEFT JOIN qryAllTasksToAdd ON
(dbo_DEALER_ACTION.Dealer_Type = qryAllTasksToAdd.Applies_To_Dealer_Type) AND
(dbo_DEALER_ACTION.Action_Id = qryAllTasksToAdd.Action_Id) "
strSQL = strSQL & WHERE (((qryAllTasksToAdd.Task_Id)=" & Me.Task_Id & ") AND
((dbo_DEALER_ACTION.Date_Completed) Is Null));"
DoCmd.RunSQL strSQL
When the VBA code executes the statement, everything is updated correctly, except for the Task_Deadline_Date field, which is being left blank.
What is really confusing me though is if I run this SQL statement standalone it is working as expected. After trying a number of different ideas I tried to replace "Deadline_Date - Deadline_adjustment AS 'Task_Deadline_Date'" with a string literal date and the statement then worked fine
Does anybody have any ideas what is going wrong?
Thanks,
Chris
You have quoted the alias, you should not do that:
Deadline_Date - Deadline_adjustment AS Task_Deadline_Date
Not
Deadline_Date - Deadline_adjustment AS 'Task_Deadline_Date'
When you add the quotes, the name of the field is 'Task_Deadline_Date'
Depending on the data type of your date field and whether or not you are using SQL Server, you may need to use DateAdd, for example:
DateAdd("d",-[Deadline_adjustment],[Deadline_Date])
In Access' query designer, start with the version of your query which works and convert it to a parameter query.
WHERE
qryAllTasksToAdd.Task_Id=[which_id]
AND dbo_DEALER_ACTION.Date_Completed Is Null;
You can also add a PARAMETERS statement at the start of the query to inform the db engine about the data type of your parameter. Examples ...
PARAMETERS which_id Text ( 255 );
PARAMETERS which_id Long;
Once you get that query working, save it and give it a name. Then your VBA procedure can use that saved query, feed it the parameter value, and execute it.
Dim db As DAO.database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.QueryDefs("YourQuery")
qdf.Parameters("which_id").value = Me.Task_Id
qdf.Execute dbFailOnError
Set qdf = Nothing
Set db = Nothing
This should be much easier than trying to recreate that SQL statement in VBA code each time you need to execute it.
It sounds like the data type of the column you are inserting in dbo_DEALER_TASK is not actually a datetime field.
I tried to replace "Deadline_Date - Deadline_adjustment AS 'Task_Deadline_Date'" with a string literal date and the statement then worked fine
If you mean '02/20/2012' (as you would correctly use on SQL Server, for example) then this shouldn't work in Access and only will if your output column is a text (= varchar/char)) data type. Date constants in Access are specified like #02/20/2012#
Please confirm the data type of Task_Deadline_Date in your output table.