Update Query - update to day before next date - ms-access

I am trying to create a query which will update a blank "To Date" field with the day prior to next updated date.
Example, an [Item Number] standard cost was updated ([From Date]) on 01/03/2019, then again on 01/07/2019 and then again on the 01/01/2020.
I would like an adjacent column which is updated with [To Date] of 30/06/2019, 31/12/2019.
I will run a subsequent query which updates blanks (i.e. current cost as there is no next [From Date]) to Today End of Month date (I assume I need a separate query for this rather than an IIF which can populate Blanks as part of this update query?)
Currently I have below, but it is updating the [To Date] with day prior to the newest date in all instances (i.e 31/12/2019 for first 2 rows), I understand that I need a SORT within the below query:
Many thanks in advance from this first time poster!
UPDATE
Standards
INNER JOIN
Standards AS Standards_1
ON
(Standards.[Item number] = Standards_1.[Item number]) AND (Standards.[From date] < Standards_1.[From date])
SET
Standards.[To Date 2] = Standards_1.[From date]-1;

This might work, but the performance migth be a bit slow:
UPDATE Standards
SET [To Date] = Nz(
DateAdd("d", -1,
DMin("[From Date]", "Standards", "[Item Number]=" & [Item Number] & " AND [From Date] > #" & [From Date] & "#")
)
, DateSerial(Year(Date()), Month(Date())+1, 0)
)
Start from the DMin function, which will lookup the next date greater than the current date for the item.
DateAdd function will subtract one day from this date.
Nz will use the value returned by the DateSerial function if the DateAdd function result is Null.
DateSerial function returns the end date of the current month.
# are added because of the date value of the [From Date] field in the criteria of the DMin.
Instead of using the [From Date] field in the DMin function criteria, you can consider using the Autonumber Primary Key field. You'll need to remove the # in the criteria.
Everything between Nz(...) will need to be on one line.
This solves both of your requirements, just test the performance.

Related

MS Access DateDiff Ambiguous Dates (Day Month order) Returning bad results

tblDurations
TaskID : Number
Assigned Date : Date/Time
Start Date : Date/Time
End Date : Date/Time
SELECT TaskID,
Count(TaskID) As [Task Count],
Min(Nz([Start Date], [Assigned Date])) as [Min of Start Date],
Max([End Date]) as [Max of End Date],
DateDiff("d", Min(Nz([Start Date], [Assigned Date])), Max([End Date])) + 1 as [Date Range]
FROM tblDurations
GROUP BY TaskID
Output:
TaskID Task Count Min of Start Date Max of End Date Date Range
1 3 16/08/2018 10/01/2019 1
2 2 4/09/2017 07/09/2017 4
3 3 13/09/2017 08/01/2018 118
I am getting the occasional row as shown in row 1 (TaskID = 1) which should equal 148!
After a lot of checking I determined this occurs for dates that are ambiguous. By that I mean where the day and months values can be confused for each other.
I'm in Australia where the date formnat is dd/mm/yyyy. However I believe the datediff function is confusing the day and month order and returning Zero (plus my 1 = 1).
How can I overcome this issue?
The problem was not the ambiguous dates. Looking closer I found various non ambiguous dates returning bad values.
The problem was the use of an Nz function which I was using like this :
Min(NZ([Start Date], [Assigned Date]))
Which I took to mean take the Min of either the Start Date, but if the start date does is NULL then the min of the Assigned Date.
What does work is this :
Nz(Min([StartDate], Min(Assigned Date))
All fixed.
Which begs the question. Why only sometimes? As it was not related to Start Dates being NULL or not NULL.
Thanks everyone for feed back!

MS Access Update Query with an IIF and DATEADD functions

I have 6 fields in my "table1".
Current Date
Next Adjustment Date
Months Elapsed
Index 0
Index 1
Index 2.
I'm trying to create an update query for Index 1 where if the (Current Date+Months Elapsed) < Next Adjustment Date then Index 1 is Index 0 if not I want Index 1 to stay at whatever value it currently has.
I tried this
iif(DateAdd("m",[Table1]![Months Elapsed],[Table1]![Current Date])<[Table1]![Next Adjustment Date], [Table1]![Index 0]
As soon as I put in the [Table1]![Next Adjustment Date] in the iif formula I receive "The expression you entered contains invalid syntax" error.
iif( is not matched by a closing )
Work out the syntax in a SELECT query. Then use that working field expression in your UPDATE. Here is my suggestion ...
SELECT
IIf
(
DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date],
t1.[Index 0]
)
FROM Table1 AS t1;
Note your IIf lacked the third argument, which is the value to return when the condition (the first argument) is not True. The database engine will not complain and will return Null in that situation. See also this answer.
However your description suggests you may actually want this ...
IIf
(
DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date],
t1.[Index 0],
t1.[Index 1]
)
... but for an UPDATE, it makes more sense to me to move that condition to the WHERE clause and update only those rows ...
UPDATE Table1 AS t1
SET t1.[Index 1] = t1.[Index 0]
WHERE DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date];
You don't have the false part of the IIf specified. Try this;
IIf(DateAdd("m",[Table1]![Months Elapsed],[Table1]![Current Date])< [Table1]![Next Adjustment Date], [Table1]![Index 0], [Table1]![Index 1])
However I'm concerned that you have apparently fields stored for Current Date and Months Elapsed. Aren't these both calculated on the fly? They should be.

Access SQL Date Format Inconsistent

I currently have a table in my database keeping track of a start date and end date for a service. I need to compare a date entered by the user to see if it is between the start and end dates. My issue right now is that in the table, access stores that start date as DD/MM/YYYY, the textbox in my form that the user puts their date in is formated as DD/MM/YYYY. However, once I hit VBA and run an SQL query, it reads the date as MM/DD/YYYY.
My query is:
SELECT * FROM table WHERE #09/01/2018# BETWEEN startDate AND endDate
My test entry is:
table:
startDate endDate service
08/01/2018 02/02/2018 ABC
This should return this entry, however as it reads it as MM/DD/YYYY it does not. If I enter #13/01/2018# it returns the entry as it detects that 13 is the date and cannot be a month. How could I correct this so that it takes 09/01/2018 and returns the entry as well?
If this is an VBA query then your observations are correct. In the Query designer these will work as expected.
Review Allen Browne's excellent explanation here; http://allenbrowne.com/ser-36.html
with solutions as well.
Your query should use either the "reverse" US sequence or the ISO sequence:
SELECT * FROM table WHERE #2018/01/09# BETWEEN startDate AND endDate
or, if you build it from code:
SearchDate = SomeDateValue
SQL = "SELECT * FROM table WHERE #" & Format(SearchDate, "yyyy\/mm\/dd") & "# BETWEEN startDate AND endDate"
or, if you always search for today:
SQL = "SELECT * FROM table WHERE Date() BETWEEN startDate AND endDate"

Dsum Function in Query Field not working properly

I have a date based query that returns two fields, Week Ending Date and L2N, and I want to add a third field that provides a rolling total of the L2N field. I have tried using DSum as follows:
RunL2N: DSum("[L2N]","Occupied Apts & L2N", "Week Ending Date=" & "'" & [Week Ending Date] & "'")
In the code above, L2N is the field I want to sum, and Occupied Apts & L2N is the query that returns the fields. The query asks for a Week Ending Date and then delivers all of the records that equal or proceed the given Week Ending Date.
It no worky right. My goal is for the RunL2N field to show a rolling total of the L2N field for each record. In other words, if the query returns multiple records, I want it to show the L2N field result, and then show the Run2L2N field, which sums the L2N fields of the records above and the current record.
So if the query returns a 1 in the L2N field, then a 3 for the next record, then a 5 for the next record and lastly a 7 for the final record, I want the RunL2N field to show 1 for the first record, 4 for the next record, 9 for the next record and lastly 16 for the final record.
Since the field name includes spaces, bracket it like this: [Week Ending Date]
Assuming it's Date/Time type, use # delimiters before and after the date value.
Finally I think you want to get the sum from rows where [Week Ending Date] <= the date in the current row.
DSum("[L2N]","Occupied Apts & L2N", "[Week Ending Date]<=" & Format([Week Ending Date], "\#yyyy-m-d\#"))
However if you use a correlated subquery, instead of DSum(), to compute the running sum of L2N, you won't have to bother about delimiters for the date value.
SELECT
y1.[Week Ending Date],
y1.L2N,
(
SELECT Sum(y2.L2N)
FROM [Occupied Apts & L2N] AS y2
WHERE y2.[Week Ending Date] <= y1.[Week Ending Date]
) AS RunL2n
FROM [Occupied Apts & L2N] AS y1;

Adding an automatic date range to a query in VBA access

This is my first question, please be kind. I am writing a macro in access and I want a series of reports to run one after another. the problem is all report have a date range that needs to be entered. Some are for the previous week some are for the previous month.
Is there a way in VBA or the macro creator to automatically calculate a date range for the previous month or week and populate the field to fully automate the process without manually entering the date range each time.
I am a new to VBA. Any help would be great, just point me in the right direction. Have a good day.
This query is created using the query design window in MS Access and then cut from SQL view. It will show records for last week, where ww is week number, in table1
SELECT Table1.AKey, Table1.atext, Table1.ADate,
Format([ADate],"ww") AS Week, Month([ADate]) AS [Month],
Year([ADate]) AS [Year]
FROM Table1
WHERE (((Format([ADate],"ww"))=Format(Date(),"ww")-1)
AND ((Year([ADate]))=Year(Date())));
You will notice that one column is called Month. You can use this to set a previous month in a similar way to setting the previous week. For example, both last week and last month:
SELECT Table1.AKey, Table1.atext, Table1.ADate,
Format([ADate],"ww") AS Week, Month([ADate]) AS [Month],
Year([ADate]) AS [Year]
FROM Table1
WHERE (((Format([ADate],"ww"))=Format(Date(),"ww")-1)
AND ((Year([ADate]))=Year(Date())))
OR (((Month([ADate]))=Month(Date())-1)
AND ((Year([ADate]))=Year(Date())));
The SQL could be written much more neatly, but you may as well start with the query design window.
i guess the date has a own field in the database you open
then you can do something like this
strSQL = "SELECT * FROM reports WHERE Date >= " & now() -7
rs.open(strSQL)
' for the last week
strSQL = "Select * FROM reports WHERE Date >= " & now() - 30
rs.open(strSQL)
' for the last month
but you will need to format now() to the same format as it is in your Table
and that is just kinda the rawest code. i had to handle something similar and this worked out quite well