Home » excel » excel – Time format in automated email is "general" rather than hh:nn AM/PM

excel – Time format in automated email is "general" rather than hh:nn AM/PM

Posted by: admin May 14, 2020 Leave a comment


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?

How to&Answers:

Use 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 Time1).
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:

  1. Don’t declare Time1 As Object but 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 Time1.

  2. Or alternatively make sure that when writing it back into the cell, that Excel will understand it as Text and 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.