I have an Excel spreadsheet that lists dates in one column and times in another.
My Outlook VBA code pulls the dates/times and puts them in an email.
In the spreadsheet, they are formatted as “1:30 PM” (for example), using the “Format Cells” feature in Excel.
If I just pull the values from the spreadsheet using, for example,
.Body = xlSht.Range("A2")
It shows up as 0.375, or another number in “general” form.
If I first format the time using this code,
Dim Time1 As Object Set Time1 = xlSht.Range("B2") Time1 = Format(Time1, "hh:nn AM/PM") '[...] .Body = Time1
It still shows up in the email as 0.375.
Is there a different way I should be approaching this?
Format$ to apply your format:
.Body = Format$(xlSht.Range("B2").Value, "hh:mm AM/PM")
Datetimes are just numbers in Excel; applying formatting in Excel doesn’t change the underlying value, hence the need for
Format$ if you’re reading the value from a cell.
Note, this answer is (additionally to BigBen’s answer) meant as an explanation why your code did not work as expected:
So what actually happens with the following code
Dim Time1 As Object Set Time1 = xlSht.Range("B2") Time1 = Format(Time1, "hh:nn AM/PM") .Body = Time1
is that it is more precisely written exactly the same as …
Dim Time1 As Object Set Time1 = xlSht.Range("B2") 'now Time1 is a Range object Time1.Value = Format(Time1, "hh:nn AM/PM") .Body = Time1.Value
If you declare
Dim Time1 As Object and then
Set Time1 = xlSht.Range("B2") the
Time1 variable is a reference to the cell B2. That means from now on writing
Time1 is actually exactly the same as writing
xlSht.Range("B2") just shorter!
That means if you now convert the value of that cell
0.375 into a string
Format(Time1, "hh:nn AM/PM") which is
09:00 AM then
Time1 = Format(Time1, "hh:nn AM/PM") writes this string back into the cell B2 (represented by
It is actually the same as writing:
xlSht.Range("B2") = Format(Time1, "hh:nn AM/PM")
And now happens what happens when Excel starts thinking and guessing:
Excel sees you writing that string
09:00 AM and thinks: “Ah, the user want’s to write a time/date, so let’s be smart and convert that string into a date value (so we can calculate with it).” So it converts it into a number which is actually
0.375 and whoops you are back where you started!
Now there are 2 ways to get around that issue:
Time1 As Objectbut as String.
Dim Time1 As String Time1 = xlSht.Range("B2").Value 'no Set!
So the line
Time1 = Format(Time1, "hh:nn AM/PM")does not write it back into the cell but only into the variable
Or alternatively make sure that when writing it back into the cell, that Excel will understand it as
Textand does not try to convert it into a time/date again by adding a
'as first character (this will not show up in the cell):
Dim Time1 As Range 'spcifying it as range instead of object is more precise (a range is an object) Set Time1 = xlSht.Range("B2") Time1 = "'" & Format(Time1, "hh:nn AM/PM") 'this will write the date as text into the cell
Note that is highly not recommended to write a date/time as text into a cell. You cannot calculate with it anymore. So I recommend to the first option.