Access data conversion issue - ms-access

I'm using Access 2003. Have a table with some date values in a text data column like this;
May-97
Jun-99
Jun-00
Sep-02
Jan-04
I need to convert them to proper date format and into another Date/time column, So create a new Date/Time columns and just updated the values from the Text column into this new column. At first it looked fine, except for years after the year 2000. The new columns converted the dates as follows;
May-97 > 01/05/1997
Jun-99 > 01/06/1999
Jun-00 > 01/06/2000
Sep-02 > 01/09/2010
Jan-04 > 01/01/2010
As you can see any data with year after 2000 get converted to 2010. The same thing happens if I query the data using FORMAT(dateString, "dd/mm/yyyy").
Any ideas why this is so? Do I have to split the month and year and combine them again?
Thanks

Access/Jet/ACE (and many other Windows components) use a window for interpreting 2-digit years. For 00 to 29, it's assumed to be 2000-2029, and for 30-99, 1930-1999. This was put in place to address Y2K compatibility issues sometime in the 1997-98 time frame.
I do not allow 2-digit year input anywhere in any of my apps. Because of that, I don't have to have any code to interpret what is intended by the user (which could conceivably make mistakes).
This also points up the issue of the independence of display format and data storage with Jet/ACE date values. The storage is as a double, with the integer part indicating the day since 12/30/1899 and the decimal part the time portion within the day. Any date you enter is going to be stored as only one number.
If you input an incomplete date (i.e., with no century explicitly indicated for the year), your application has to make an assumption as to what the user intends. The 2029 window is one solution to the 2-digit year problem, but in my opinion, it's entirely inappropriate to depend on it because the user can change it in their Control Panel Regional Settings. I don't write any complicated code to verify dates, I just require 4-digit year entry and avoid the problem entirely. I have been doing this since c. 1998 as a matter of course, and everybody is completely accustomed to it. A few users squawked back then, and I had the "it's because of Y2K" as the excuse that shut them down. Once they got used it, it became a non-issue.

The date is ambiguous, so it is seeing 02 as the day number. Depending on your locale, something like this may suit:
cdate("01-" & Field)
However, it may be best to convert to four digit year, month, day format, which is always unambiguous.

Access seems to be get conduced between MM-YYYY format and MM-DD format. Don't know why it is doing it for dates after the year 2000, but solved it by converting the original string date to full date (01-May-01). Now Access converts the year into 2001 instead of 2010.

If you don't supply a year and the two sets of digits entered into a date field could be a day and month then Access assumes the current year. So your first three dates definitely have a year in them. But the last two don't.
Note that this isn't Access but actually the operating system doing the work. You get the same results in Excel. I had an interesting conversattion with some Microsoft employees on this issue and it's actually OLEAUT32.DLL.

Related

Need a proper input mask for a time field in Microsoft Access

My table field is date/time and formatted like this:
mm/dd/yyyy hh:nn:ss
I want the user to see this (with the space appearing between date and time
__/__/__ __:__:__
I want an input mask that demands:
Either 1 or 2 digits for the month
Either 1 or 2 digits for the dat
All 4 digits for the year
SHOWS the space but just jumps over it for the user
Either 1 or 2 digits for each of Hours, Minutes and Seconds
Further, when setting up a DB, is it just smarter to have two separate fields for Date and Time. A collegue encouraged me to break them out ... seems sensible?
00/00/0000##00:00:00
See the outcome in the image
Controlled user input is not an easy task in Access, as it is optimised for the opposite: To be tolerant and accept many input sequences for date and time.
For the cases where controlled input is mandatory, I've written two articles including full code (too much to post here) and demo, that may give you some ideas:
Entering ISO formatted date with input mask and full validation in Microsoft Access
Current code at VBA.DateEntry.
and
Entering 24-hour time with input mask and full validation in Microsoft Access.
Current code at VBA.TimeEntry.

Excel changes time-format to datetime with MSQuery

I make with Excel a MSQuery to obtain some fields from a table in MySql what is working fine but there is one column which has in MySQL a time-format and Excel delievers me this in datetime-format.
I can format the cell in Excel so that it shows me the time in format hh:mm that is not the problem but I had to use these fields from the database to do some calculations in Excel which leads to my problem: I can't make a sum over these fields when the sum is greater then 24 hours, because then I get only the value of the hours and not from the days multiplied with 24 (e.g. instead of 25:15 I get only 1:15).
Normally I use for this format [hh]:mm so there will be displayed all values (even for more then 24 hours) but this doesn't work here, because I get a very high value (for example: 1017144:15). The reason for this is, that Excel adds for every field to the time the acrtual date of today (e.g. 12:00 will be 12.01.2016 12:00) and with this for every time in the sum the value for the date will be add additionally.
I tried it with the following statement in the MSQuery:
SELECT
DATE_FORMAT(entry.timeBegin, '%h:%i') AS 'Beginn',
entry.timeEnd AS 'Ende',
TIME(entry.pause) AS 'Pause'
FROM timetable.entry entry<br>
All 3 columns have in the database in MySQL the format hh:mm. Ende and Pause behaves like described above and Beginn is formatted in the right way (just without formatting the field by Excel) but the content of the field has type string and with this, Excel always use 0 (zero) for these fields when calculating with them, so I get allways 0 as sum.
I know that I can build the sum in MySQL, but this is no solution for me because the user could set some filters in Excel and this is to complicated to build in the query, espacially this is only one part of a more difficult construct.
Ok, here are a few examples. 'Beginn' allways delivers 0:00 (as described above) and 'Ende' and also 'Pause' are allways equal together. So we have to consider Ende or Pause with hh:mm and [hh]:mm format:
0:00 leads to 0:00 / 1017144:00
1:30 leads to 1:30 / 1017145:30
20:00 + 3:00 leads to 23:00 / 2034311:00
21:30 + 3:00 leads to 0:30 / 2034312:30
I didn't try PowerQuery because I don't know it till now and I don't know if it is inside of Excel or MS. I don't want to install an additional tool on the PC for every user. If I had only to take it into my Excel-sheet so it could be a solution if it is functions right.
Supplement: I looked after PowerQuery and see that this will bring me problems, because the most users uses MS Office 2010 and the requirement with Excel 2010 is Microsoft Office 2010 Professional Plus mit Software Assurance and the feature Software Assurance is not present in our company.
Added: For more clearness I add a screenshot from Excel:screenshot of Excel
I get column A from SQL displayed in format h:mm.
Column B is the same just in number-format.
D2 and E2 are the Sum from A1:A10 in format h:mm respectively [h]:mm:ss.
D3 and E3 are the Sum from A1:A23 in format h:mm respectively [h]:mm:ss.
As you can see SQL delievers the Time 5:30:00 via MSQuery and Excel shows me 14.01.2016 05:30:00 which I can format in the right way (column A). Building the sum is possible (look D2) as long as it is smaller than 24 hours else I get only the hours (< 24) which are greater than a entire day. The reason for this you can see in D3 and E3.
What can I do to get the right values? I suppose the easiest way would be at the point of getting the data from MSQuery.

Need Savings totals by month to pull data correctly and display in Chart

My data and this SSRS chart have a ton of problems, I'll try to keep my question(s) succinct.
First, as you can see by this chart and this screenshot of my data (just showing date and April Savings), my expression/chart is not summing all of the savings within a month, which is my goal.
It appears to be picking one amount within the correct month and using it. I set up a tool tip for April so I could see what number it's pulling (since clearly the chart columns are not representing the data whatsoever - another issue).
You'll see in the SQL data screenshot that it does indeed pull $1,230 from the April 2013 Savings. How can I get this to Sum within the month AND still do a running value from the beginning of time data began to current, this often will include multiple years.
Here's my Chart Data (note that my Team Goal works perfectly, and is even charted correctly - but if anyone knows how to force that line to go from end to end on my chart, feel free to let me know.) :
To summarize, how can I sum each month's data, while still do a running value across the months AND years?
Here's my Expression for Implementable Savings:
=RunningValue(Sum(Fields!ImplementableSavings.Value), Sum, nothing)
(obviously if I can get one working, I can get both)
My Expression for ImplementedSavingsMonth:
=MonthName(Month(Fields!ImplementedSavingsDate.Value))
My Expression for ImplementedSavingsYear:
=Year(Fields!ImplementedSavingsDate.Value)
Let me know if there's anything else I can provide.
Quick sidebar question: WHY does my chart column collect one piece of data. IE: see the tool tip $1,230 for April 2013), but the chart column displays that the number is around $1.7M? And in this scenario, both of my blue and yellow columns are displaying the same number, so why does blue always appear to be a higher number? I will ask this as a 2nd question if it's inappropriate for me to ask here.
I would use this Expression for Implementable Savings:
= RunningValue ( Fields!ImplementableSavings.Value, Sum, "Chart1")
.. assuming your Chart's name is Chart1.

MS Access 2003: User was able to enter an invalid value; how?

I have a strange phenomen I can't explain nor reproduce and I'm hoping you have an idea how it was possible for the user to enter an invalid value.
I have an Access-MDB with a form containing an edit field that should only accept time values without any date-information.
The relevant properties of that edit field are as below:
bound to a Date/Time database value (since access know no time-only datatype)
Format: "Time, 24hrs"
Input Format: "99:99"
(I use the german version of Access, so the property names may be a little different, but you see the pattern)
Now I found out that a user was able to enter a date value into that field. I'm nearly 100% sure that it was an accident and no "clever hack" in the form of directly opening the table and editing the corresponding Date/Time field. Since the entry was made back in 2009 (nobody spotted the error), I have no chance to ask the user how it was done.
I found two wrong entries with the dates "01.06.2000" and "01.07.2000" and I guess the user wanted to enter the times "06:00" and "07:00".
I tried every input I can imagine (like "6.0", "6;0", "6,0", copy&paste) but I was unable to trick access and enter anything except digits and the colon.
Do you have any idea what is going on and how the user was able to enter these dates accidentially?
A Jet/ACE Date/Time value is never stored "without any date information". If you attempt to store only the time component, it will actually be stored with the same time on day zero (Dec 30, 1899).
We can only speculate how the incorrect data was added back in 2009. If you want the database engine to require your Date/Time values to be stored with day zero as the date component, you can add a table-level validation rule. From the table property sheet, try this for Validation Rule:
DateValue([your_date_field])=CDate("1899/12/30")
If you want to allow Null for your_date_field, try this version:
IsNull([your_date_field]) Or DateValue([your_date_field])=CDate("1899/12/30")
Several possibilities:
A developer (you?) did it by accident when looking at the raw table
The client Access software went momentarily crazy and corrupted the entry. This has happen to us (fortunately very rarely) where our Access tables will end up with non-ASCII characters in a string field.
A bug in Access runtime allowed the problem in the past, but has been corrected in a service pack.
Finally, if you put in 90 hours, does it overflow into 4 days and something? That might do it.

How to store approximate dates in MySQL?

I need to store dates such as 'Summer 1878' or 'Early June 1923', or even 'Mid-afternoon on a Tuesday in August'. How would you suggest I do this?
I have considered breaking the date and time up into separate (integer) columns, and giving each column an ancillary (integer) column containing a range (0 if exact; NULL if unknown). But I'm sure there's other ways...
Thanks!
Since 'Mid-afternoon on a Tuesday in August' ("A Sunday Afternoon on the Island of La Grande Jatte"?) doesn't specify a year, the only real solution is your table of all date and time components, all nullable.
Other wise, you're conflating your data.
You have two (admittedly related) things here: a human readable string, the date_description, and a range of possible dates.
If you can specify at least a range, you can do this:
create table artwork {
artwork_id int not null primary key,
name varchar(80),
... other columns
date_description varchar(80),
earliest_possible_creation_date datetime
latest_possible_creation_date datetime
}
insert into artwork(
name,
date_description,
earliest_possible_creation_date,
latest_possible_creation_date
) values (
'A Sunday Afternoon on the Island of La Grande Jatte',
'Mid-afternoon on a Tuesday in August'
'1884-01-01',
'1886-12-31'
), (
'Blonde Woman with Bare Breasts',
'Summer 1878'
'1878-05-01',
'1878-08-31'
), (
'Paulo on a Donkey',
'Early June 1923',
'1923-06-01'
'1923-06-15'
);
This allows you to display whatever you want, and search for:
select * from artwork
where #some_date between
earliest_possible_creation_date and latest_possible_creation_date;
And obviously, "creation date" (the date the artist created the work) is entirely differnet from "date depicted in work", if the latter can be determined at all.
I'm using Postgres, and I wanted to do the same thing. Perhaps you can do it the same way as I did it, if MySQL has some similar geometric types: http://www.electricwords.org/2008/11/fuzzy-date-matching-in-postgresql/
Almost no matter what you do, you almost certainly won't be able to get the database to do the heavy lifting for you. So you are left with two options:
1 - Use natural strings as you have described
2 - Store a precise data as well as the precision of that date
For example, you could store "5:10:23pm on Sep 23,1975", "plus or minus 6 months", and when someone wants to search for records that occured in that timeframe this could pop up.
This doesn't help with queries, because to the best of my knowledge MySQL doesn't provide any support for tolerances ( nor do any others I know of ). You have to basically query it all and then filter out yourself.
I don't think any native MySQL date representation is going to work for you. Your two-column solution would work well if paired with a Unix time stamp (generated with the UNIX_TIMESTAMP() function with a MySQL date as the argument). Use the second column (the range width) for an upper and lower bound in your selects, and make sure the date column is indexed.
In the end I decided upon: a column for each of the date components (year, month, day, hour, minute, second), and accompanying columns for the range of each of these (year_range, month_range, day_range, hour_range, minute_range, second_range), mainly because this method allows me to specify that I know for sure that a particular photo was taken in August (for instance) in the late '60s (year=1868, year_range=2, month=8, month_range=0).
Thank you all for your help!
create a table with a list of values that you could want, like "Early" or "Summer". then whatever you have setting up the data could have an algorithm that sets a foreign key depending on the date.
Going with Chris Arguin's answer, in the second column just have another datetime column that you can use to store the +/-, then you should be able to write a query that uses both columns to get an approximate datetime.
Use two dates and determine the start and end date of the fuzzy region. For stuff like Summer 1878, enter 18780621 to 18780920. For Early June 1923 you have to decide when early ends, maybe 19230601 to 19230610. This makes it possible to select against the values. You might still want to filter afterward but this will get you close.
For the ones without years, you'll have to find a different system.