Problem reading Excel cells containing datetime in VBA
Some background: For a project I'm working on (building an XML DOM from a given excel spreadsheet of customer data), I need to be able to read the contents of a cell with a datetime in it. The cell in question contains "7/22/2011 0:00," and when I r开发者_StackOverflow社区ight-click->format cells, it tells me the category is "Custom" (not in the standard date category), and of type "m/d/yyyy h:mm." Yet when I select the cell, the formula pane displays it as "7/22/2011 12:00:00AM." So all three of these attempts to categorize the datatypes don't match up.
The problem: When I display the cell contents using ActiveWorkbook.ActiveSheet.Cells(x,y) in a MsgBox for debugging purposes, it only shows 7/22/2011 (cutting off the time). It can't be the space in between the date and time that throws it off, as I am successfully reading cells with spaces in them elsewhere in the spreadsheet.
Can anyone tell me why this is happening, or point me in the right direction for a VBA/Excel method that doesn't do this weird cropping thing that Sheet.Cells(x,y) is doing? Thanks. If only I had a penny for every time datetime datatypes caused problems for me..
Internally, Excel stores dates as numbers. It doesn't implement a date type. The number is the number of days since some point in the past (1900 or 1904, depending on the operation system, with some mistakes built-in regarding leap years). Time is represented as the fractional part of the number.
To make it look like a date to the user, you have to assign the cell a date format. Then the number is displayed as a date in the cell. (Excel assigns a date format automatically if you enter somethings that looks like a date to Excel.)
When you use ActiveWorkbook.ActiveSheet.Cells(x,y)
, you create a Range
object and call its default property, which is Value
. Value
has a lot of magic built-in. In your case, it looks at the cell format and - seeing a date format - in converts the internally stored number into a Variant
of subtype date. When you display it using a message box, the next trick happens. If the time is 0:00, the date is converted to a string without time. If the time were different from 0:00, it would be converted to a string with date and time. The date format is taken from your user's settings. Its independent of the date format you have assigned to the Excel cell.
If you use Value2
instead of Value
(e.g. by using a messag box to display ActiveWorkbook.ActiveSheet.Cells(x,y).Value2
), then you'll see the internal representation of the date, namely a number.
When you edit a cell, Excel uses yet another date format so you can see and edit all parts of the date: year, month, day and possibly hour, minutes and seconds. This is because your cell's date format could be restricted to just the month name.
Another complexity is added by internationalization. Certain date formats aren't applied directly but are a hint for using a date format from the current user's settings. So the format is first replaced with another date format and then applied. Furthermore, certain parts of the date and time formats are affected by the user's settings. And finally, the patterns of the date format are translated (in English, yyyy
stands for the year, in German it's jjjj
). When the Excel spreadsheet is saved, these formats are stored in the English form so that the sheet can be opened by user's and Excel installations with any language. In your case, internationalization probably affects the date format used when you edit the cell (putting month before day and using 12-hour display with AM/PM looks like Northern America).
I don't quite understand why Excel displays "7/22/2011 12:00:00AM" (instead of "7/22/2011 0:00:00AM"). I'm pretty sure your date/time has a time part of "0:00". But the internal number (as reveal by Value2
) will tell you for sure.
It's like a formula, in the cell it will show the result, in the formula bar it will show the formula. The cell you can format, the formula bar you cannot. So you can change the cell's format to however you would like it to look like.
So, if you want to format the msgbox then you would need to do the following:
MsgBox (Format(ActiveWorkbook.ActiveSheet.Cells(x,y), "m/d/yyyy h:mm")
精彩评论