How to set the year part of a field using a query - ms-access

Evening,
I have created a query that is suppose to change ONLY the year part of a Date/Time field to 1900 when a person is 89 years or older. The query that follows compiles fine but when run it complains about a Type Conversion failure and removes the entire value from the records affected.
The query:
UPDATE tblTestForDOB
SET tblTestForDOB.[PT_BirthDate] = DateValue( (day([PT_BirthDate])/month([PT_BirthDate])/1900) )
WHERE Year(tblTestForDOB.[PT_BirthDate]) <= Year(Date())-"89";
According to the MS Help (F1 over the function):
The required date argument is normally a string expression representing a date from January 1, 100 through December 31, 9999. However, date can also be any expression that can represent a date, a time, or both a date and time, in that range.
Is that not what I'm doing? I also tried placing the " " & before the values inside the DateValue function and that did the same thing
(to ensure that it was a string that was passed)
So how do I go about it? Should I use CDate to convert the value to a Date and then proceed that way? If so what is the correct syntax for this?
Thanks
P.S The field is of Short Date format. Also note that I don't want to take the long way around and use VBA for the whole thing as that would involve opening record sets and so on...

It appears you're trying to give DateValue a string, but that's not what's happening. There may be more going on that I don't understand, so I'll just show you an Immediate window session which may contain something you can build on.
PT_BirthDate = #1923-6-1#
? PT_BirthDate
6/1/1923
? DateDiff("yyyy", PT_BirthDate, Date())
90
' this throws error #13: Type mismatch ...
? DateValue( (day([PT_BirthDate])/month([PT_BirthDate])/1900) )
' it will work when you give DateValue a string ...
? DateValue("1900-" & Month(PT_BirthDate) & "-" & Day(PT_BirthDate))
6/1/1900
' or consider DateSerial instead ...
? DateSerial(1900, Month(PT_BirthDate), Day(PT_BirthDate))
6/1/1900

Related

SSRS Time expression filter not working with Parameter boolean value

Background:
Trying to achieve a filter in dataset, if the user selects Day shift from the parameter, any data entry between 06:00:00 and 18:00:00 is filter in the report. Furthermore, any data entry between 18:00:00 and 06:00:00 is reflect in the report for Night shift
Process:
I have got a parameter with 2 Boolean values "True" and "False". I have labeled those values as "Day shift" and "Night shift" in the available value Parameter window option. Default value is true.
Converting datetime to time, in the dataset query
SELECT
CONVERT(time, SWITCHOFFSET(CONVERT(datetimeoffset, LastModified),DATENAME(TzOffset, SYSDATETIMEOFFSET()))) as ShiftTime
FROM table abc
Filter expression:=Fields!ShiftTime.Value
Operator: in
Value: =IIf( ( TimeValue(Fields!ShiftTime.Value) >= "06:00:00" And TimeValue(Fields!ShiftTime.Value) <= "18:00:00" ) , Parameters!ShiftType.Value(0), Parameters!ShiftType.Value(1) )
Problem: [BC30516] Overload resolution failed because no accessible
'IIf' accepts this number of arguments
Not sure which part I am going wrong with, I am thinking it is the datatype but unsure.
Solution which I built on
I'm not sure what report designer you are using, but using the Report Designer extension for Visual Studio gives me very different errors.
And it gives errors both in the output window, and the expression window when building it.
Firstly to debug this, add it as a column to your report before you try and implement it as a filter.
Then check the relevant documentation for the function. It turns out the TimeValue function takes a string, not a DateTime, and returns a datetime.
Then, you can't access the available parameter values from the parameter, you can only access the selected parameter values. So instead of Parameters!ShiftType.Value(0) (which has a red line under it) you should just have true (or false depending on which way around your logic is) i.e. the value of the parameter.
Finally, I don't know what implicit conversion SSRS does from strings to a time, so I would do an explicit time compare instead of a string compare. Given we know that TimeValue returns a DateTime with the minimum date value and the time component we can compute the required limites for day/night shift.
The following is what worked for me:
=IIf(TimeValue(Fields!ShiftTime.Value.ToString()) >= DateTime.MinValue.AddHours(6) And TimeValue(Fields!ShiftTime.Value.ToString()) <= DateTime.MinValue.AddHours(18), true, false)
And actually re-visiting it, thats way too convoluted, you are already returning a time value which we can compare directly as
=IIf(Fields!ShiftTime.Value >= new TimeSpan(6,0,0) And Fields!ShiftTime.Value <= new TimeSpan(18,0,0), true, false)
And then your filter should be:
Filter expression: {as shown above}
Operator: =
Value: =Parameters!ShiftType.Value
Note: when you say "between" I don't know whether the intention is to include both 6am and 6pm within the day shift window, but I haven't modified your logic in that regard.

How to use expression builder to create a file name with date even for the first day of the month

I have an SSIS package that runs each morning to pull the previous days file from an FTP server. I am using the code below to create the file name using the previous date. Everything works great with this except when today's date is the first day of the month. for example, if ran today (3/1/2021) this returns name_of_file_20210328.xml.gz, however yesterday's date is 2/28/2021 not 3. How do i update this to say if today's date is beginning of month return mm - 1?
"name_of_file_" + (DT_STR,4,1252)(DATEPART("yyyy",GETDATE())) + (LEN((DT_STR,2,1252)(DATEPART("MM",GETDATE()))) == 2 ? (DT_STR,2,1252)(DATEPART("MM",GETDATE())) : "0" + (DT_STR,2,1252)(DATEPART("MM",GETDATE()))) + (LEN((DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE())))) == 2 ? (DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE()))) : "0" + (DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE())))) +
".xml.gz"
Create a variable, Yesterday of type DateTime. Specify that it uses an expression and use the following expression. This provides a consistent reference point you can test against and if you disable the expression, allows you to specify a date for boundary/special case checking (like a leap year 2020-03-01)
DATEADD("DAY", -1, #[System::StartTime])
The next steps, especially if you're starting out, is to build the date parts in separate variables. It doesn't cost any extra to use lots of variables in your package and makes troubleshooting so much easier.
Add a new variable, YearString of type String.
(DT_WSTR, 4)datepart("YYYY", #[User::Yesterday])
That was easy.
Now we need to deal with create a zero, left padded string. Right now, your expression looks like it's trying to determine if day or month has 2 digits. I have a cleaner expression.
We're going to convert the day/month to a string and then prepend a zero to it. For Jan-Sep, we'll end up with a 2 character expression, Oct-Dec, we'll have a three character expression e.g. 011. For Day, similar bit where it's 01-09 or 010-031. We will then take the last two characters from the string. For the two character strings, it's a no-operation and for the three character variant, it gets us what we want.
Add Variable MonthString, as type string, to your package
RIGHT("0" + (DT_WSTR, 2)datepart("MONTH", #[User::Yesterday]), 2)
Add Variable DayString, as type string, to your package
RIGHT("0" + (DT_WSTR, 2)datepart("DAY", #[User::Yesterday]), 2)
Take a moment and look at your Variable collection. You can see that you have all the building blocks needed to properly construct your YYYYMMDD string. If something is wrong, it's small enough snippet to play with it. If not, break it up into smaller Variables.
Now that we have defined #Yesterday and then built YearString, MonthString and DayString off of Yesterday, all we have to do is bring it all together with the concatenation + operator
Back to the Variable well, creating #CurrentFileName of type string
"name_of_file_" + #[User::YearString] + #[User::MonthString] + #[User::DayString] + ".xml.gz"
Results in a value of name_of_file_20210216.xml.gz
Not addressed in this answer but things you should think about
What happens when the job doesn't run at all today (server fails horrifically, the data source is down, etc)? To pick up and process 2 days ago file, you would need to edit this package, run it through whatever change review process is applicable, deploy to prod, run it and then go back to the process yesterday file package.
That's not fun to type much less consider. You certainly aren't going to change the server time to trick the expression into being yesterday.
I am an advocate for passing the run date to the package (mechanism depends on how you deploy/run packages). In that situation, it's been my experience that it's a far easier bureaucracy fight to change the calling parameter (because no "code" has changed) than to get an emergency code change run through.

MS Access Date/Time format issue?

This might be a possible duplicate, but I have a strange issue with MS Access DB.
When I update a Date/Time value for my column req_date, I'm facing a problem.
10-03-2017
is getting updated as below
10-03-2017
where as
10-18-2017
is getting updated as below
18-10-2017
I'm using the following code in c# to Execute the query:
query = "update gb_jobs set req_delivery=myDate"
myCMD = new OleDbCommand(query, con, trans);
int tempCnt = myCMD.ExecuteNonQuery();
where as myDate is already converted to string from date time,
As per the solution by Albert, I concatenated my myDate to #myDate# but it is throwing following error:
query = "update gb_jobs set req_delivery=#myDate#"
Error : Data type mismatch in criteria expression.
You don’t mention where/when/how you are updating that column in question.
As a general rule, if the VBA variable type is an actual DATE type variable then you can assign such values directly to a control or recordset in code.
However if ANY of your code uses a string result, then you MUST format the string as USA format regardless of your computer's regional settings. Your regional settings will thus transform the date display to whatever floats your boat.
So any of your date formats have to be of mm/dd/yyyy. Given your examples, it looks like you are following that format. This suggests that you have your DISPLAY set to DD/MM/yyyy. So in theory what you have given so far is correct behaviour.
What this suggests is that your result of 10-03-2017 ACTUALLY means 03/10/2017. So it is in fact March and not October.
Thus in VBA code to update (or query) some data, you have to go:
dtStart as date
dtEnd as date
If you set the value of above two dates, then to query the data, you MUST go:
strWhere = "InvoiceDate >= #" & format(dtStart,'mm/dd/yyyy') & "#" & _
" and InvoiceDate <= #" & format(dtEnd,"mm/dd/yyyy") & "#"
Docmd.OpenReport "rptInvoice",acViewPreview,,strWhere
So any code that will query, or update values with SQL has to re-format the data to USA format (mm/dd/yyyy). What the control and forms will display is as noted whatever you have in windows regional panel, but ALL internal code must format strings as mm/dd/yyyy.
So it not clear how you are making the change, but from what you have given so far, your DISPLAY of info is dd/mm/yyyy, but you are entering the data as mm/dd/yyyy which is correct. If you are entering this data on a form and not using code, then from what you have given your date format as set by windows is dd/mm/yyyy.

Classic ASP, DATE difference between IIS6 and IIS8

I am helping to migrate a classic asp website (front end) and ms access database (back end) from a Windows 2003 IIS6 server to a Windows 2012 IIS 8.5 server. I am having a problem with this query in particular;
sqlquery1 = "Select RentalNum, CarID, RentalStatus, StartDate, EndDate from table where CDate(EndDate) <= CDate('"&Date()&"') order by CDate(EndDate) desc"
On the existing system all is ok. On the new system the returned results are not <= "todays date". The results show some dates before today and some after. The database date fields are just "text" (I didn't set it up) and whilst my initial thoughts were to change the schema to proper dates, I would like to understand the problem, particularly as there are many of parts of the system using similar queries using date() and CDate. Are there underlying dates differences between IIS servers? I have looked at browser locality and all is ok there.
Any pointers?
Examine this expression used in your query:
CDate('"&Date()&"')
The Date() function returns the system date as a Date/Time value. But then that expression adds quotes before and after the Date/Time value, which transforms it to a string value. And then CDate() takes that string and transforms it back to a Date/Time value again.
Hopefully that description convinces you those manipulations are at best wasted effort. However if the two servers have different date format settings, the dates resulting from that full CDate() expression could be different.
I'm not positive that is the source of your problem, but you can easily eliminate the possibility. The Access db engine supports the Date() function, so you can use it directly without first transforming it to a string and then back into a Date/Time value.
sqlquery1 = "Select RentalNum, CarID, RentalStatus, StartDate, EndDate " & _
"from [table] where CDate(EndDate) <= Date() order by CDate(EndDate) desc"
If that change does not solve the problem, next examine those EndDate text values and make sure they're interpreted as the date you expect:
SELECT EndDate, CDate(EndDate) AS EndDate_as_date
FROM [table];
You mentioned your "initial thoughts were to change the schema to proper dates". I think that is the best way to go because developement based on dates as Date/Time is saner than with dates as strings.

Converting user-typed dates from date picker

I have a report that uses date params (so have to be datetime in SSRS, which sucks to start with). When the user enters a date such as "5/1" it creates a DateTimeOffset data type and I can't find anyway to cast it to anything else, format it, or concatenate in a text box. I tried casting to a date to a string, etc. All I get is:
Conversion from type 'DateTimeOffset' to type 'String' is not valid. ('String' is replaced by anything I try to cast it to)
Surely there must be a way to have a text box show "From 5/1/2013 to 5/31/2013" when the user types "5/1" and "5/31" in the date field? Does Microsoft really think computer-literate people want to pick up the mouse to use their date picker instead of using tab?
Try the following expression:
="From " & Format(Parameters!Param1.Value.DateTime, "M/d/yyyy") & " to ..... etc"
To test this expression I've created a fresh report, added a DateTime parameter, and entered "5/1" in the textbox, hit enter. The report comes up with the following textbox:
From 1/5/2013 to ..... etc
For my locale, this is correct, because when entering DateTime values days are assumed to come before months. When the report is viewed the textbox will also update and show:
5-1-2013 0:00:00 +01:00
From this you should be able to extrapolate and use it for a second parameter as well, extending the expression to show the exact string you need in your report.
The Parameters!Param1.Value.DateTime helped when the user omits the year, but it broke down when the user decides to include the year. I couldn't get it to work under both conditions.
Try this.
Include the date parameter value as a field in your resultset. Your SQL might look like:
SELECT field1, field2, Convert(date, #FromDate) [FromDate_param] FROM table
Then you can create an expression in SSRS like:
="From " & Format(First(Fields!FromDate_param.Value), "M/d/yy")