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.
Related
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,
How should I write the name of the recordset correctly? I have a type mismatch error on & rsg & at "sq3=..." line. Thanks in advance.
Dim rsG As DAO.Recordset
Dim sq2, sq3 As String
sq2 = "SELECT * from GeneralTable "
sq2 = sq2 & "where gsede='LION' and (gExclu is null) and (gAda is null) "
sq2 = sq2 & "order by gnomb,gnif;"
Set rsG = CurrentDb.OpenRecordset(sq2)
sq3 = "UPDATE " & rsG & " SET gsede ='AA' WHERE gsede='LION'"
DoCmd.RunSQL (sq3)
You are mixing up totally different ways to update data - UPDATE SQL and VBA recordset.
If you want to update a recordset row by row, you do something like
Do While Not rsG.EOF
If rsG!foo = "bar" Then
rsG.Edit
rsG!gsede = "AA"
rsG.Update
End If
rsG.MoveNext
Loop
Do the update using a single query:
update generaltable
set gsede = 'AA'
where gsede ='LION' and (gExclu is null) and (gAda is null);
If you do the update off of rsG, then you'll likely do a separate update for each row, and that is inefficient.
You can't mix and match SQL and recordset objects. You can either build a full update statement that includes the logic of the first select (as other answer suggests), or you can open a dynamic recordset and loop through the records programmatically to make the updates.
That being said, looping through large recordsets programmatically to make updates is usually better handled by a bulk SQL statement, unless it is essential to consider each row individually inside the code - which in your basic example would not be the case.
MS has a good article on the DAO.Recordset object. There is a dynamic-type Recordset example about halfway down.
I am very new to Microsoft Access.
I would like to select a column from a table based on the value of a parameter (i.e. my table has columns x, y and z and I have a chosencol parameter which is set by the user using a dropdown.
I can select one / all of the columns using a select command, however, I would like to do this using my parameter chosencol instead.
Having read around, I have found a number of references to using the SET and EXEC commands, however, entering them into the SQL command in Access just yields errors.
Please could someone advise me as to how I go about implementing a dynamic-sql query in Access (in fine detail as I think I am writing the commands in the wrong place at the moment...)
First I created an example table in Access.
Next, I created an example form to query your value. The dropdown is called 'chosencol'. Select a value from the Column Select dropdown and press the "Lookup Value" button.
Here is the code under the "Lookup Value" button's On Click event. A SQL statement is dynamically built with the column you chose. The column is renamed to [FieldName] to that it can by referenced.
Private Sub btnLookup_Click()
Dim rsLookup As New ADODB.Recordset
Dim strSQL As String
strSQL = "select " & chosencol.Value & " as [FieldName] from Table1 where ID=1"
rsLookup.Open strSQL, CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
If rsLookup.EOF = False Then
txtValue.SetFocus
txtValue.Text = rsLookup![FieldName]
End If
rsLookup.Close
End Sub
When the button is pushed, the value from whatever column you selected will be returned. For this simple example, I'm always returning row 1's data.
I'm pretty sure you can't do that in straight SQL. However, you can create the SQL string in VBA code and save it as a query.
CurrentDB.CreateQueryDef("MyQueryName", "SELECT " & chosencol & " FROM MyTable")
Now, MyQueryName will be a permanent query in your database and can be referenced wherever you want.
If chosencol is a multi-select dropdown, you'll have to read the selected values into an array and then write the array to one concatenated string and use that instead.
I've had a look around but cannot find the issue with this SQL Statement:
strSQL = "SELECT Directory.DisplayName, Department.DisplayName, Call.CallDate, Call.Extension, Call.Duration, Call.CallType, Call.SubType FROM (((Department INNER JOIN Directory ON Department.DepartmentID = Directory.DepartmentID) INNER JOIN Extension ON (Department.DepartmentID = Extension.DepartmentID) AND (Directory.ExtensionID = Extension.ExtensionID)) INNER JOIN Site ON Extension.SiteCode = Site.SiteCode) INNER JOIN Call ON Directory.DirectoryID = Call.DirectoryID WHERE (Call.CallDate)>=27/11/2012"
Regardless of what I change the WHERE it always returns every single value in the database (atleast I assume it does since excel completely hangs when I attempt this) this SQL statement works perfectly fine in Access (if dates have # # around them). Any idea how to fix this, currently trying to create a SQL statement that allows user input on different dates, but have to get over the this random hurdle first.
EDIT: The date field in the SQL Database is a DD/MM/YY HH:MM:SS format, and this query is done in VBA - EXCEL 2010.
Also to avoid confusion have removed TOP 10 from the statement, that was to stop excel from retrieving every single row in the database.
Current Reference I have activated is: MicrosoftX Data Objects 2.8 Library
Database is a MSSQL, using the connection string:
Provider=SQLOLEDB;Server=#######;Database=#######;User ID=########;Password=########;
WHERE (Call.CallDate) >= #27/11/2012#
Surround the date variable with #.
EDIT: Please make date string unambiguous, such as 27-Nov-2012
strSQL = "SELECT ........ WHERE myDate >= #" & Format(dateVar, "dd-mmm-yyyy") & "# "
If you are using ado, you should look at Paramaters instead of using dynamic query.
EDIT2: Thanks to #ElectricLlama for pointing out that it is SQL Server, not MS-Access
strSQL = "SELECT ........ WHERE myDate >= '" & Format(dateVar, "mm/dd/yyyy") & "' "
Please verify that the field Call.CallDate is of datatype DATETIME or DATE
If you are indeed running this against SQL Server, try this syntax for starters:
SELECT Directory.DisplayName, Department.DisplayName, Call.CallDate,
Call.Extension, Call.Duration, Call.CallType, Call.SubType
FROM (((Department INNER JOIN Directory
ON Department.DepartmentID = Directory.DepartmentID)
INNER JOIN Extension ON (Department.DepartmentID = Extension.DepartmentID)
AND (Directory.ExtensionID = Extension.ExtensionID))
INNER JOIN Site ON Extension.SiteCode = Site.SiteCode)
INNER JOIN Call ON Directory.DirectoryID = Call.DirectoryID
WHERE (Call.CallDate)>= '2012-11-27'
The date format you see is simply whatever format your client tool decides to show it in. Dates are not stored in any format, they are effectively stored as a duration since x.
By default SQL Uses the format YYYY-MM-DD if you want to use a date literal.
But you are much better off defining a parameter of type date in your code and keeping your date a data type 'date' for as long as possible. This may include only allowing them to enter the date using a calendar control to stop ambiguities.
I have a problem converting dates while updating an SQL table in VB under access: here is my code:
'Excel format date conversion
strSQL = "UPDATE tblBlotterINTLControl " & _
"SET tblBlotterINTLControl.TradeDate = CVDate(TradeDate), " & _
"tblBlotterINTLControl.SettleDate = CVDate(SettleDate);"
DoCmd.RunSQL strSQL
I obtain an error for each row: "type conversion error"
I have my tables in the right format though, please help thanks
EDIT:
I have to say that a SELECT request works but an UPDATE request doesn't! why? how?
What are the data types of the TradeDate and SettleDate fields in the Access table tblBlotterINTLControl?
SELECT TypeName(TradeDate) AS TypeOfTradeDate, TypeName(SettleDate) AS TypeOfSettleDate
FROM tblBlotterINTLControl;
Please paste that query into SQL View of a new query in Access, run it and show us what you get back.
The reason I asked is because the SET statements in your UPDATE query puzzle me.
SET tblBlotterINTLControl.TradeDate = CVDate(TradeDate)
If the TradeDate field is Date/Time datatype, using the CVDate() function on it doesn't accomplish anything.
If the TradeDate field is text datatype, CVDate() will give you a variant date, but you can't store that Date/Time value back to your text field.
Maybe you would be better off using the Format() function. Here is a sample I copied from the Immediate Window:
? Format("2011/01/01", "d mmm yyyy")
1 Jan 2011
Try CDate instead of CVDate.
CVDate actually returns a Variant of type vbDate and is only around for backwards comparability. Maybe that's what causing the problems.