Access 2013: How to Return All Records With Date Older than X? - sql

My Problem
I have a date field in the table in question. I'm trying to create a query that will only display records where that date field are 120 days old or older.
My Code
Solution Attempt 1
The first solution I tried was simply added criteria to my date field. The criteria formula I used was:
< Date()-120
This removed a few 'random' records leaving me with 714 of my original 905 records. Unfortunately, a quick look through the dates of remaining records in ascending order, it was obvious that I was still getting records more recent that 120 days old.
Based on my 'random' result above, I double checked the format of my field by changing the field to:
DATE: Format([myDtField], "mm/dd/yyyy")
I ran the query again - this reduced the number of records removed, leaving me with 734 of 905 - but my issue persisted - I still had records with dates more recent than 120 old.
Solution Attempt 2
Based on my issues above, I decided to go a different route. This time I created a unique field for my criteria calculation. For the field value I used:
DateDiff: DateDiff("d",[myDtField],Date())
This resulted in values that were very far off from the correct values (ex. a record with a date of yesterday resulted in 43!).
Solution Attempt 3
This was less of a solution and more just troubleshooting, but based on the results I'm getting, I keep thinking my dates aren't being perceived by the system as the date it's displaying (i.e. DateValue() is off compared to displayed value). I spot checked a few of the dates vs their DateValue() and the randomly selected records all seemed to be correct. So again, no luck.
Solution Attempt 4
#Gustov reminded me about the DateValue() function. I've attempted that on the field as well - the field is imported as a text field, thus needs converted to a date value. Similar to the formula Gustov posted, for my field value I used:
DATEDIFF: DateDiff("d",Nz(DateValue([LASTPAYDT]),0),Date())
And then in the criteria I simply used the formula:
>120
This results in the following error:
Data type mismatch in criteria expression
This was probably the closest solution I had, simply because WITHOUT criteria it returns the proper values (i.e. a date of yesterday returned "1", while a date of two days ago returned "2"... etc). So you would think simply limiting records where this field is >120 would work, but then it throws up the error above.
My Question
Does anyone have an idea of how to check if a record field is 120
days old or older?
If either of my above solutions works for question 1, then what might be wrong with my date field that is causing issues if I am going about it the right way?
#Gustov's DateValue() solution is close (i.e. provides the correct values), but adding criteria causes an error. Any solutions?
I'm at a loss. An extra set of eyes on this problem would be greatly appreciated. Thanks!

Hans touches something. If the dates are not dates but text, try this:
Select * From YourTable
Where
IsDate([myDtField])
And
DateDiff("d", DateValue([myDtField]), Date()) > 120

I have tried this and it works, DATAText is the data stored as a text.
SELECT Tabella1.ID, Tabella1.DATAText, Date() AS Espr1
FROM Tabella1
WHERE (cDate(Format(Tabella1.DataText,"yyyy-MM-dd hh:mm:ss")))<Date()-120;

Related

How do I execute the CTRL + H function in a Microsoft Access query automatically?

I have numbers displayed as Ranges Ex. 3-7 Days or 24-72 Hours. I need to change these to just a number like 168 or 72 so I can ultimately do comparisons or if statements. I know i can just click CTRL H and go through each condition to format the data, but I have been trying to find a way to have this happen through the query. I am very new to Access so I may be thinking about this all wrong. I tried typing this Expr1: Replace("0-4 Hours", "0-4 Hours", "4") in the field and sometimes it asks for a parameter but it just creates a column called Expr1 with the parameter in it. I followed the syntax i found on this site for replace function so i must be way off.
Query is looking for a field named 0-4 Hours which of course it can't find, hence the prompt (which should always happen, not just sometimes so that is a mystery). Correct syntax:
Expr1: Replace([fieldname], "0-4 Hours", "4").
However, this calc result will show only for records that have 0-4 Hours value. Dynamically calculating this for every record should be possible with:
SELECT *, Val(Mid([fieldname], InStr([fieldname], "-")+1)) As Num FROM tablename;
Every record must have value because Null will cause error.
If the unit (Days, Hours, etc) is not same for all records, this gets even more complicated. If Days and Hours are the only units involved and you want to convert all to Hours:
Val(Mid([fieldname], InStr([fieldname], "-")+1)) * IIf(InStr([fieldname],"Days")>0,24,1) As Num
Any more complication and a VBA custom function would likely be required.

Check whether a form date field is equal to 1899-12-30 00:00:00.000

I know this should be simple but after hours of googling I am still failing...
I have a vb.net form application. Basically I have an SQL database with an Employee table with an EmpFinish column in datetime, null format (Employee Finish Date). The data is imported from a linked SQL DB (populated from an external app). Any "blank" dates show as 1899-12-30 00:00:00.000 in SQL.
The Employee table data is shown on a datagridview form, a row is selected, then I want to perform a check to test whether that rows EmpFinish date from the form is earlier or equal to today and is not equal to it's "blank" value i.e. has the employee left employment.
Code excerpt:
Dim currentDateTime = DateTime.Now
Dim selectedEmpFinishDate As DateTime =
EmployeesDataGridView.SelectedRows(0).Cells(5).Value
If selectedEmpFinishDate.CompareTo(currentDateTime) <= 0 Then
' code to do
End If
I didn't start out using the CompareTo() above util I started Googling this issue and it seems this is the best way to compare dates. Yes???
This test works for actual dates e.g. yesterday but also catches all 1899 dates, I have tried lots of tests (using 1 If statement of separate ones) to check for the 1899 blank dates but cannot get anything to work. If I debug the code at the test line, selectedEmpFinishDate supposedly equals #12/30/1899#. If I show the field value onscreen via
MsgBox("selectedFinDate = " & selectedEmpFinishDate) it reports as 00:00:00
I know this must be possible but cannot figure it out.
Could someone please offer a solution as I am running out of hair to pull out.
I have followed djv's advice (I had the same thought last night) and done an override to set these date values to NULL. I was then able to use IsDBNull() successfully.
To clarify where these dates came from... Data is imported into this database from another SQL DB created by a huge business software application. Not sure if they want the dates stored this way or whether the import sets them to be this "blank" default 1899 date.
They actually showed on all forms as 1899 etc so resetting them to NULL is the best option all around.
To anyone else who has these 1899 dates I would advise to update them to NULL.
Thank you to everyone who responded especially djv.

Excel Forumla/VBA to skip blank columns for calculation

I have a particular data set that consists of information for projects our company works on. Each project can go through five different statuses and we have a column that records each date the project is put into that particular status.
Now for the Excel part. We are trying to calculate the days in each status and find the total project time. The total is easy to do, because I can use network days between the project submitted date and the project go live date. The statuses, however, are giving me issues because sometimes a project will skip a status, leaving the date field empty. So what happens is a project goes from status B to status D, the formula for days in status "B" look for a date in column "C" to use as the second date in a NETWORKDAYS formula. When it is empty, the IF argument tells the formula to use TODAY() as the second date. What I need it to do is the search the columns to the right (within the given range of A:E for that row) and use that date if it exists. If not, then it can default to TODAY() because this would be an "active" project that has not moved on.
=IF(IF(OR([#STALLED]<>"",[#CANCELED]<>""),"",IF([#INTAKEDATE]="","",IF([#SCOPEATE]="",NETWORKDAYS([#INTAKEDATE],TODAY()),(NETWORKDAYS([#STATUSADATE],[#SCOPEATE])))))<0,"",(IF(OR([#STALLED]<>"",[#CANCELED]<>""),"",IF([#INTAKEDATE]="","",IF([#SCOPEATE]="",NETWORKDAYS([#INTAKEDATE],TODAY()),(NETWORKDAYS([#STATUSADATE],[#SCOPEATE])))))))
This is done for each of the statuses so the table looks something like this:
PROJECTID PROJECTNAME INTAKEDATE SCOPEATE BUILDDATE TESTDATE GOLIVEDATE INTAKEDAYS SCOPEDAYS BUILDDAYS TESTDAYS
If there is any Macro or better formula someone could help me figure out, I'd appreciate it. There is also another field that gives the current status or if the project is considered live if that helps at all. I have excel-block right now and cant think of anything that makes sense for this.
So I figured it out using MIN and by adjusting the IF formulas a bit. Whoever it was that posted about MAX earlier, really helped me out getting me down this path. Kudos to you sir/madam.
I had to add the check to see if SCOPEDATE=BUILDDATE because without that it was returning 1 if the dates matched, with was adding one more day when compared to running the networkdays from INTAKEDATE to GOLIVEDATE.
=IF(OR([#STALLED]<>"",[#CANCELED]<>""),"",
IF([#SCOPEDATE]="","",
IF([#SCOPEDATE]=[#BUILDDATE],0,
IF(NETWORKDAYS([#SCOPEDATE],(MIN([#BUILDDATE],[#TESTDATE],[#GOLIVEDATE])))<0,NETWORKDAYS([#SCOPEDATE],TODAY()),NETWORKDAYS([#SCOPEDATE],(MIN([#BUILDDATE],[#TESTDATE],[#GOLIVEDATE])))))))
I hope this is helpful for someone else.

Access Query / Report - Error: This expression is typed incorrectly or it is too complex to be evaluated on calculated field

So after reading 9 posts about the same error on Stack I didn't really find an answer to my problem, hence me posting this question.
So in my Access I have a query that inherits from several other queries. With this query a User can get information with a certain Date range. This data is put in a report where the records are shown and internally (in the report) some calculation is done of the record fields.
The problem is, when A user wants data until the date 2016-4-22 the report shows up fine. Though when the User wants data until the date 2016-4-30 (from day 23 and on it just gives the same errors) the report tries to load but after a while fails with the error:
This expression is typed incorrectly or it is too complex to be evaluated
So this made me test a few things which I have list down below:
First I thought the Query itself or the given WHERE clause were corrupted / not good so I put the Report recordsource with the WHERE clause in a separate test query and executed it. This all worked fine (no errors).
This made me believe that perhaps a single record was corrupted so I went to the date from which on it gave the error (2016-4-23) and checked this record. Nothing weird was found.
Then I thought it could be some field on the report that was giving the error so I removed several fields and after removing a few Calculated Sum(total) fields the error disappeared.
So I created another query and did the Sum in this query as well based on my created test query - this gave the same error.
After these tests I was pretty sure that perhaps the calculated data was just too much to calculate. I also copied the queries data into Excel and did a SUM of the field there as well. The outcome was roughly 15 million. I can hardly imagine that a number of 15 million is too complex to be evaluated...
Besides that, I also tried to create another SUM query on the specific field but with the date based on 2016-4-22 (so the one that initially DID work). But now it also givers the error on this date... So there goes my theory..
Anyone has a clue what is going wrong?
The 'base' query in question is:
SELECT qryOHW6Verdicht.*
, CStr([nummer] & "." & [qryOHW6Verdicht].[positie]) AS NummerPos
, [ArbeidTot]+[MateriaalTot]+[UitbesteedTot] AS Kosten
, CDbl([AangenomenprijsPositie])+CDbl([MeerwerkPrijsPositie]) AS OpdrachtSom
, IIf([nacalculatie],[Kosten],IIf(IsNull([kostenverwacht]),(100-[otwinstpercentage])/100*[opdrachtsom],[kostenverwacht])) AS VerwachteKosten
, IIf([nacalculatie],[kosten],IIf([Kosten]<[VerwachteKosten],[Opdrachtsom]-[VerwachteKosten],[Opdrachtsom]-[Kosten])) AS VerwachteWinst
, [Kosten]-[VerkoopTot] AS WaardeOHW
, DatePart("yyyy",[gereeddatum]) AS GereedJaar
, [OtOverhead]*[VerkoopTot]/100 AS Overhead
, qryVCBoekingenVerdicht.KostenVerwacht
FROM qryOHW6Verdicht LEFT JOIN qryVCBoekingenVerdicht
ON (qryOHW6Verdicht.[Positie] = qryVCBoekingenVerdicht.[Positie])
AND (qryOHW6Verdicht.[Nummer] = qryVCBoekingenVerdicht.[Offerte])
The report opens with the previous query as recordsource and with this WHERE filter:
1=1 AND (Gereeddatum is null OR Gereeddatum>=#2016-4-30# )
AND Project IS NULL AND NOT (WaardeOHW=0 AND Kosten=0) AND GarantieOrder=0
In the report I got a few Calculated fields and one of them that goes wrong is:
=Sum([OpdrachtSom])

pulling current date queue

I have a view that lists employee (EmpID), request number (ReqNo), date request was opened (OpenDate) and the date it was moved to the next step in the process (AssignDate). What I am trying to do is get an average of the daily queue size. If EmpID 001 has 20 requests on 1/1/13, then has 24 on 1/2/13, 21 on 1/3/13 the average over 3 days should be 21.66, rounded up to 22. I have the following view:
CREATE VIEW EmpReqs
AS
SELECT [EmpID], [OpenDate], [AssignDate], [ReqID]
FROM [Metrics].[dbo].[Assignments]
WHERE OpenDate BETWEEN '01/01/2013' AND '12/31/2013' AND
[EmpID] IS NOT NULL AND
[ReqNo] NOT LIKE 'M%'
I then wrote a query to pull individual employee's queues per day:
/* First attempt to generate daily queue #s */
SELECT * FROM BLReqs
WHERE [BusLiaison] LIKE 'PN' AND
[OpenDate] <= '11/15/2013' AND
[AssignDate] > '11/15/2013'
Because no one has attempted to pull this information before, I have no way of verifying how accurate the above is. I tried using current dates, since I can see those in our database to compare but the code doesn't work, nothing is returned when I change the dates to 2014 and run my query.
What is the easiest way to verify that my code is correct, short of manually counting a day's queue?
Can anyone see any issues with the above scripts?
Is there a way to get the above code to work with current dates?
This question is really hard to answer because it is kind of broad and has little information at the same time. I'll try anyway:
Because no one has attempted to pull this information before, I have
no way of verifying how accurate the above is.
Try checking the result of this query for a few sampled dates.
I tried using current dates, since I can see those in our database to
compare but the code doesn't work, nothing is returned when I change
the dates to 2014 and run my query.
So clearly, the query is not working. You should probably find out why. Run the query for a date of which you know that it should return results but doesn't. Remove conditions one by one to see which one is incorrectly removing all rows. This should be enough to identify the bug.
Can anyone see any issues with the above scripts?
No, looks fine. A very simple query. That's why I said that we have too little information. There is some key piece of information missing that allows us to find the bug.
Is there a way to get the above code to work with current dates?
Stop staring at the code and hoping for a revelation. Debug it. Experiment.