Reference cell value as string in Excel - excel

In Excel, if the cell A1 has some value that gets formatted in a specific way, is there a way for cell B1 to reference the string displayed in A1?
To clarify:
If A1 displays, for instance, the time 10:31:48, I wish to have B1 reference this outputted string as shown to the user ("10:31:48", not the underlying numerical representation "0.43875").
I'm well aware that there are functions for manually formatting values. However, what I'm looking for is copying an already formatted value from another cell, no matter what format that cell may have.
Is something like this possible?

In fact, Excel stores datetime as a number, so you have to explicitly set format of the cell to see the proper value.
You may want to use TEXT function, but anyway, you have to specify format of output string:
=TEXT(A1,"hh:mm:ss")
Another option is to write your own VBA function, which can convert a value of a cell based on it's format:
Public Function GetString(ByVal cell As Range) As String
GetString = Format(cell, cell.NumberFormat)
End Function
This will give you a result based on source cell's format

So that does not quite work as the VBA Format function isn't compatible with Excel formats.
The table below shows the difference between "GetString()" above, and "GetText()"
Public Function GetText(ByVal cell As Range) As String
GetText = Application.WorksheetFunction.Text(cell, cell.NumberFormat)
End Function
Short Date and Long date are interesting -- they are off by 1 day.
Format Value GetString GetText GetFormat
general 3.141592638 'Ge23eral' '3.141592638' 'General'
number 3.14 '3.14' '3.14' '0.00'
Currency $3.14 '$3.14' '$3.14' '$#,##0.00'
Accounting $3.14 '_($3.14_)' ' $3.14 ' '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(#_)'
Short Date 1/3/1900 '1/2/1900' '1/3/1900' 'm/d/yyyy'
Long Date Tuesday, January 3, 1900 'Tuesday, January 02, 1900' 'Tuesday, January 3, 1900' '[$-F800]dddd, mmmm dd, yyyy'
Time 3:23:54 AM '3:23:54 AM' '3:23:54 AM' '[$-F400]h:mm:ss AM/PM'
Percentage 314.16% '314.16%' '314.16%' '0.00%'
Fraction 3 2/16 '3 ??/16' '3 2/16' '# ??/16'
Scientific 3.14E+00 '3.14E+00' '3.14E+00' '0.00E+00'
Text 3.141592638 '3.141592638' '3.141592638' '#'

Related

How to extract data from a field that is apparently of the date / time format but is not really such a format

I have copied (copy/paste) a part of a home-page into an empty excel. One of the fields looks like this: 3140:01:00. If I check the format, it shows that the category is custom, and that the type is [t]:mm:ss. The problem is that I am only interested in the first 4 digits shown plus digits 6 and 7. If I change the format to e.g. text, I end up with a number. Probably a number, that identifies a specific date. In fact the first 4 digits are the length of a horse race! :-) I'm new at VB, but I have managed to clean up the rest of the information - but not this. Probably a known problem. Please help!
You will need to understand the difference between the value and the representation of your data (note that this is not VBA but Excel related). When you enter 3140:01:00 in a cell in Excel, Excel tries to understand what you enter. With the colon, it looks somehow like a time value, so Excel guesses that this a a time, convert what you enter into a date value (a date in Excel has automatically a time part) and put a number format that displays this date+time as [h]:mm:ss.
As I said, internally, what you entered is converted into a Date. Now a Date in Excel in internally stored as a number. If you set the number format to "Number", the cell will display 130.83402. This is because 3140 hours = 130 days + 20 hours. The 20 hours (plus the 1 minute) are stored as a fraction of a day (0.83402).
If you format the same value as Date/Time, you will see (depending on your regional settings) something like 05/09/1900 20:01:00 - because that is the 130th day in the Excel calendar (day 1 in Excel is 1/1/1900). Note that the value of the cell doesn't change, only the way it is displayed.
If you could prevent Excel to convert your input into a date, the solution would be to do string-handling, eg use the Split-function. When you format a cell as Text and enter 3140:01:00 manually, Excel leaves the string untouched and this would work. However, it seems that when you Paste the value into the cell, the number format is set automatically and the value is converted into a date even if the cell was formatted as Text before. I don't know if there is a way to tell Excel to not convert the data if it is pasted.
So what we can do instead is to convert the date value back into "hours", "minutes" and "seconds" - even if the "hours" are in fact something else (meters? yards? horse length?), and the minutes are probably also not minutes but whatever.
Several ways to do so.
If you don't mind that the strange pseudo-date value remains in your Excel (you can hide the column with that value), use just 2 simple formulas. Assuming your "date" is in D2:
use the formula =TRUNC(24*D2) to get the horse race length (the first number). We cannot use the Hour-formula here as this would return only 20 and not 3140.
use the formula =MINUTE(D2) to get the second number
use the formula =SECOND(D2) to get the third number
If you want to involve VBA:
Sub SplitStrangeDate(cell As Range)
If Not IsDate(cell) Then Exit Sub
Dim d As Date
d = cell.Value
Dim v1 As Long, v2 As Long, v3 As Long
v1 = CLng(d * 24)
v2 = Minute(d)
v3 = Second(d)
Debug.Print v1, v2, v3
End Sub

Convert Date to Text without losing the format in Excel?

I have a column in Excel Sheet which contains all the dates in custom dd-mm-yyyy format. I need to convert all these dates to text without losing the format. If I am changing the cell format to Text, I am losing the format. I tried to copy the cell values as values but did not work. I searched a lot on the internet, but did not find any useful resource. What's the possible solution?
Try using the TEXT function.
=TEXT(A1,"dd-mm-yyyy")
Use this formula for keeping the long date format from "A1" cell in another cell (exp: "B1"):
=TEXT(A1,"[$-F800]dddd, mmmm dd, yyyy")
The cell "A1" is a cell contains a date (such as today date with «today()» formula) with long date format.
Also, you can use this VBA code for getting same format with specify font and size in print's header:
ActiveSheet.PageSetup.RightHeader = "&""Arial Rounded MT Bold,Regular""&16" & Range("B1").Value
This code will shows the "B1" cell (as a text from "A1" cell) in Right of Header in Print.

Date format dd/mm/yyyy read as mm/dd/yyyy

I have a spreadsheet with a column formatted as:
Category: Date
Type: *dd/mm/yyyy
Location: UK
When I read the data in this column via VBA, it reads in the format mm/dd/yyyy.
For example, 10/06/2014 (10 June 2014) is reading 06/10/2014 (06 Oct 2014).
My code: sDate = SourceSheet.Range("AB" & CurRow.Row).Value
I have this issue with my forms too and the best method for me is to format the textbox like this:
sDate = format(SourceSheet.Range("AB" & CurRow.Row).Value, "mm/dd/yyyy")
Even though the date format is wrong in VBA, it seems to work the right way round in Excel. It's weird, I can't explain why it happens, but this fixes it for me. Whenever I go from VBA to Excel, I almost always find this issue if the value is stored as a date.
Consider:
Sub luxation()
Dim sDate As Date, CurRow As Range
Set SourceSheet = ActiveSheet
Set CurRow = Range("A1")
ary = Split(SourceSheet.Range("AB" & CurRow.Row).Text, "/")
sDate = DateSerial(ary(2), ary(1), ary(0))
MsgBox Format(sDate, "dd mmmm yyyy")
End Sub
This question of mine - .NumberFormat sometimes returns the wrong value with dates and times - gives some background which may help.
I first encountered this VBA bug many years ago and it is worse than it seems. I noticed that many - but not all - dates in a worksheet that I had been updating for a year were wrong. It took me a long time to diagnose the problem. Those dates that could be interpreted as middle endian dates had been corrupted but those that could not be interpreted as middle endian dates were unchanged. So 12/06/2014 will become 6 December but 13/06/2014 will remain 13 June. If 13/06/2014 had been rejected as an invalid date or left as a string, I would have spotted the error immediately. The dual interpretation so every date was imported as a date - the wrong date but still a date - ensured I did not notice until much later maximising the cost of correcting for the bug.
Excel holds dates and times as numbers. "17 June 2014" is held as 41807 and "1 January 1900" is held as 1. In both cases, the value is the number of days since 31 December 1899. Times as held as a fraction:
number of seconds since midnight
--------------------------------
seconds in a day
So 06:00, 12:00 and 18:00 are held as 0.25, 0.5 and 0.75.
This bug is encountered when the transfer of a date involves a conversion to and from string format. I have not discovered a single case in which the conversion from date to string has been wrong. It is the conversion from string to date that hits this bug.
I can see that SilverShotBee's solution will avoid the bug but it would not appeal to me. I no longer use any ambiguous dates ever.
One choice is to transfer the value as a number. If cell A3 contains the date and time "17 June 2014 9:00" then CDbl(Range("A3").Value) returns 41807.375. When you store this number in a cell you will need to set the cell's NumberFormat to the date format of your choice but that might be a good thing.
If I were going to use middle endian dates, I would be explicit. #13/06/2014# is always interpreted as middle endian.
I prefer unambiguous strings. "2014-06-13" or "13 June 2014" are not misinterpreted by VBA or by a human reader.
Have just come up against this issue! Reading records from a .csv and storing in an .xls
I found the following sequence works to overcome the misinterpreted dates:
Read the date field from the .csv file
Store it into a cell in the .xls file
Read it back into vba
Store into its required destination in the .xls
Date is in original format
I found this issue to be incredibly complex and was trying to keep it as simple as possible but have indeed left a few vital details out! Apologies. Here is a fuller version of what I found:
First of all I should explain I was reading dates (and other fields) from a .csv and storing back into an .xls
I am on Office 2002 running on Windows/7
Using 2 example dates: 27/4/2015 and 7/5/2015 in dd/mm/yyyy string format (from the csv)
What I found was:
Reading the 27/4/2015 text date field from csv into a variable dimensioned as STRING and storing into an xls field in dd/mm/yyyy DATE format produces a cell that reads 27/4/2015 but converting it into a cell formatted as Number also produces 27/4/2015. 7/5/2015 on the other hand produces a string that reads 7/5/2015 and converting it into a cell formatted as Number produces 42131.
Reading the 27/4/2015 text date field from csv into an undimensioned variable and storing into an xls field in dd/mm/yyyy DATE format produces a cell that reads 27/4/2015 but converting it into a cell formatted as Number also produces 27/4/2015 while 7/5/2015 reads 5/7/2015 and converting it into a cell formatted as Number produces 42190.
Reading the 27/4/2015 text date field from csv into a variable dimensioned as DATE and storing into an xls field in dd/mm/yyyy DATE format produces a cell that reads 27/4/2015 and converting it into a cell formatted as Number produces 42121. 7/5/2015 on the other hand produces a string that reads 5/7/2015 and converting it into a cell formatted as Number produces 42190.
The first 3 scenarios above therefore do not produce the desired results for all date specifications.
To fix this I do the following:
Input_Workbook.Activate
ilr = Range("A5000").End(xlDown).End(xlDown).End(xlDown).End(xlUp).Row
For i = 1 To ilr
Input_Workbook.Activate
If IsDate(Cells(i, 1).Value) Then
d1 = Cells(i, 1).Value
d1 = Replace(d1, "/", "-")
ThisWorkbook.Activate
Cells(14, 5).Value = d1
d1 = Cells(14, 5).Value
If VarType(d1) = vbString Then
d1 = CDate(d1)
End If
Cells(i, 1).Value = d1
End If
Next
The cell used to store the date initially is formatted GENERAL and the ultimate target cells is formatted as DATE (dd/mm/yyyy).
I don't have enough brain cells left to fully explain what happens to the dates during this process but it works for me and of course the choice of target cells is completely random in the above code block.
The problem was VBA was opening the csv with the reverse dates for single digit days.
This way of opening the workbook worked the same as when I did it manually so had the correct dates in dd/mm/yyyy format. Then copied across correctly:
Workbooks.OpenText FileName:=fpathO, datatype:=xlDelimited, comma:=True, local:=True

Excel 2010 - change US dates to UK format

I have imported a CSV file with 2 long columns of dates. These dates are in the US format Aug/28/2013 and I want them to be in the standard UK dd/mm/yyyy format.
I have tried formatting the cells as US dates and then converting them to number-only formats, and various other permutations within the Date format box, but with no success.
Can anyone rid me of these awful US dates please?
Another solution without using a formula:
Select the relevant columns
Choose Data → Text to Columns…
Select “Delimited” and click Next
Untick all delimiters and click Next
Select data column format “Date: MDY” and click Finish
The dates should now be converted to UK dates.
The problem is that a US date can parsed by Excel as a UK date when the day is less than 13. When this happens Excel converts it to the localized UK serial (date) number.
So 03/19/2014 is obviously a US date of the 19th of March. However 05/03/2014 is ambiguous so Excel parses it the local date format as the 5th of March, rather than the US 3rd of May. Any formula has to check if Excel has stored the US Date as a UK date. A UK date will be stored in Excel as a number.
=IF(ISNUMBER(A2),DATE(TEXT(A2,"yyyy"),TEXT(A2,"dd"),TEXT(A2,"mm")),DATE(RIGHT(A2,4),LEFT(A2,FIND("/",A2)-1),MID(A2,FIND("/",A2)+1,2)))
(For a US date in cell A2 and PC date is dd/mm/yy).
If ISNUMBER is true, the US date looks like a UK date and Excel has serialized it as a number. So can format the date as text and back to a date again. Note day is passed to the month parameter of the first DATE function to perform the conversion.
If ISNUMBER is false, its stored as a string as Excel doesn't convert a date string with >12 months. So use string functions to split it up for the DATE function.
I'm assuming that the date you received is formatted as text and that simply formatting it as date is not changing anything. You can run the following formula on the date:
=(MID(A1,FIND("/",A1)+1,FIND("/",A1,FIND("/",A1)+1)-FIND("/",A1)-1)&"-"&LEFT(A1,FIND("/",A1)-1)&"-"&RIGHT(A1,4))*1
If you get numbers, you just need to format it as dd/mm/yyyy and it should be good.
I tried some of the other suggestions but none seemed to work for me. In my case I was importing US dates in the form M/d/yyyy hh:mm:ss. If you don't mind using some VBA in your spreadsheet then the following function did the job for me:
Public Function USDate(ds As Variant) As Variant
Dim sp() As String
Dim spt() As String
Dim spt2() As String
If ds = vbNullString Then
USDate = ""
ElseIf IsNumeric(ds) Then
' Convert numeric US dates wrongly interpreted as UK i.e. 1/7/2017 as 7th January 2017
USDate = DateSerial(Year(ds), Day(ds), Month(ds))
Else
sp = Split(ds, "/") ' split the date portion
spt = Split(sp(2), " ") ' split the time from the year
spt2 = Split(spt(1), ":") 'split the time hms
USDate = DateSerial(spt(0), sp(0), sp(1)) + TimeSerial(spt2(0), spt2(1), spt2(2))
End If
End Function
Thanks for https://stackoverflow.com/users/845584/peterx pointing out - you will need to create the function in a VBA code module to use this technique.
Simply use it in a spreadsheet formulae for example =USDate(A2)
Related to this, the below simply formula can be helpful for changing a date from
"MM/DD/YYYY"
into
"DD/MM/YYYY".
=VALUE(TEXT(B2,"mm/dd/yyyy"))
We can get best of both world with this more concise formula:
=IF(ISNUMBER(A2),VALUE(TEXT(A2,"mm/dd/yyyy")),DATE(RIGHT(A2,4),LEFT(A2,FIND("/",A2)-1),MID(A2,FIND("/",A2)+1,2)))
Can't find anything shorter.
There was one more issue for me, as somehow the raw data was supposed to be read as a number, but it did not. Hence, i updated the formula with 1 final case:
=IFERROR(IF(ISNUMBER(A2),VALUE(TEXT(A2,"mm/dd/yyyy")),DATE(RIGHT(A2,4),LEFT(A2,FIND("/",A2)-1),MID(A2,FIND("/",A2)+1,2))),DATE(RIGHT(A2,4),LEFT(A2,FIND("/",A2)-1),MID(A2,FIND("/",A2)+1,1)))
This can be tricky when the dates in mixed format eg. UK and US in the same column. I have found an effective if inelegant solution:
Step1) Select the column containing the dates to be converted;
Step2) Format, Cells, Text;
Step3) Format, Cells, Date, US;
Step4) Data, Text to column, Next, Delimited, Next, delete all delimiters, Next, select format MDY;
Step5) Format, Cells, Date, UK.
Step4 had been suggested elsewhere, but that on it's own didn't do it for me. I am hoping to combine these steps into a macro but no success this far.
I couldn't get the most common answer to work, the process that worked for me was:
For date 10/04/2018 11:49:20, right-click cell and "Format Cells", "Number" tab and select "Custom" Category and then select mm/dd/yyyy hh:mm.
Assuming that you start with a string (and not an internal excel date number that is just formatted as US format - which is an easy fix), can someone tell me why this method doesn't work?
Use the DATEVALUE / TIMEVALUE functions to convert it into an excel internal formatted date number (You might need to MID() the string in case there are extra bits before or after).
Just make sure that your regional settings match the input date format (otherwise DATEVALUE will fail and you will get a #VALUE error).
Then set the cell format to display the way you want it (Custom format e.g. "dd/mm/yyyy hh:mm:ss").
If you also want to change the timezone, you can add on (hours/24) to the internal Excel excel formatted date number.
The above look impressively complex! Why any country should settle on a non-sequential date format escapes me! Say you have a US-format date (mm/dd/yy) in cell A1. To convert this to dd/mm/yy format as in the UK, just do:
=CONCATENATE(MID(A1,4,2),"/",MID(A1,1,2),"/",MID(A1,7,2))
This certainly works in LibreOffice and I hope also in Excel.

EXCEL VBA CSV Date formatting issue

I am an Excel VBA newbie. My apologies if I am asking what seems to be an obvious question.
I have a CSV text file I am opening in an Excel worksheet. One row of the file contains date information formatted as "YY-MMM', (ie: 9-FEB, or 10-MAY). When the Excel spreadsheet opens the file the date information is changed to "mm/dd/yyyy" format and reads as 02/09/2009 or 05/10/2009 where the YY-MMM is now MM/YY/2009, (ie: the 9-FEB becomes 02/09/2009, and the 10-MAY becomes 05/10/2009).
I would like to know if it is possible to reformat the field from YY-MMM to mm/01/yyyy.
I have tried to parse the date field after converting it to text with
Range("B11", "IV11").NumberFormat = "text"
However, then the value is a serial date and non-parsable.
I have been unsuccessfully looking for a list of the NumberFormat options.
If you can point me in a direction it will be much appreciated.
Just to answer a part of your question, here is the list of date formatting options (excluding time):
d = day of month, e.g. 7
dd = zero-padded day of month, e.g. 07
ddd = abbreviated day name, e.g. Thu
dddd = full day name, e.g. Thursday
pretty much the same for month...
m = month number, e.g. 7
mm = zero padded month number, e.g. 07
mmm = abbreviated month name, e.g. Jul
mmmm = full month name, e.g. July
years are simpler...
yy = 2 digit year number, e.g. 09
yyyy = 4 digit year number, e.g. 2009
you can combine them and put whatever separators you like in them
e.g.
YY-MMM, 09-FEB
DDDD-DD-MMM-YY, Wednesday-04-Feb-09
dd/mm/yyyy, 04/02/2009
mm/dd/yyyy, 02/04/2009
I've just been trying a few things out and I think your best bet is to change the format in the text file to conform to a more standard date arrangement. If you can reverse them (e.g. MMM-YY) you'll be fine, or split them into separate columns (what if when you import you define - as a separator as well as comma?). This is one case where Excel trying to be clever is a pain.
HTH
If you are currently using File > Open to open the CSV file then try Data > Import External Data > Import Data instead. This brings up the text import wizard which might give you more flexibility in how to import the file. Specifically, it lets you declare a column in the file as being text so that Excel does not try to parse the value
As Simon has explained, your terminology for the current date format is not correct. 9-FEB corresponds to d-mmm format and 02-19-2009 (NB deliberately changed to an unambiguous date for this example; 02-09-2009 is 9th Feb in the US but 2nd Sept in the UK) corresponds to mm-dd-yyyy
If you wanted to change the NumberFormat to text for the range starting in cell B11 and ending in cell IV11 then you would use:
Range("B11:IV11").NumberFormat = "#"
# signifies text format and you need the : operator to indicate a contiguous range of cells. Your original example of Range("B11","IV11") actually indicates the union of cells B11 and IV11 and thus would only have affected two cells
It is unusual to have your data structured in rows rather than columns. Rather than having your dates in row 11, it would be more common to have them in column K instead so that you would use Range("K2:K65535") or just Rows("K") Most of the built-in Excel stuff like Sort and AutoFilter assume that your data is laid out in columns anyway. Row 1 traditionally contains the column names and then each subsequent row contains an individual record. You might want to look at how your CSV file is being generated to see if you can switich it to a more usable column-based structure
If you have a date like 19-FEB as text in a cell then, assuming that you always want the year part to be the current year, you can change it to the first day of the month in mm/dd/yyyy format in VBA. This example only changes one cell but you can use it as the basis for a wider solution:
Option Explicit
Sub main()
Dim strOrigValue As String
With ThisWorkbook.Worksheets("Sheet1").Range("B11")
strOrigValue = .Value
.NumberFormat = "mm/dd/yyyy"
.Value = DateSerial(Year(Date), Month(strOrigValue), 1)
End With
End Sub
DateSerial creates a date serial number from the given year, month and day. Year(Date) extracts the year part from the current system date, Month(strOrigValue) takes the month part from the data that's already in the cell and we want the first day of the month
In order to read in a date, you can do something like this:
myDate = DateValue(dateText)
although there are caveats to how excel may interpret dates, and what technical limits it has in what dates it may store. (you may need to read up on maximum and minimum dates, and how excel interprets two-digit years >30 vs <30, among other things)
In order to format the date, you can use one of three functions:
myDateText = DatePart("yyyy", myDate) & "/" & DatePart("mm", myDate) & "/" & DatePart("dd", myDate)
or this
Format (myDate, "yyyy/mm/dd")
or this
FormatDateTime(#1/1/2020#, vbShortDate)
You can search google for more documentation on each function. For the format function, you will want to find a good reference -- I've seen some rather incomplete ones. MSDN tends to have good ones, but not always. Feel free to bump this answer if you want more details.
This assumes your 2 digit year is 2000. Once you end up with your incorrect date 9-Feb = 02/02/2009, you can convert this to the date you want with the formula: =DATE(Day(B11)+2000,Month(B11),1)

Resources