Date Formatting in Excel VBA - vba

I have written a long procedure in VBA to manipulate a data set. Part of this involves using and formatting dates, and I can't get it to work properly.
The initial data as downloaded has dates in the format "yyyy-mm-ddThh:mm:ssZ" - e.g. 2014-12-11T04:59:00Z.
I then convert these into a date in UK format of "dd/mm/yyyy". Looping over all relevant cells, I use the following method:
initial_date = Range("A1").Value
Dim publish_date As Date
publish_date = DateValue(Mid(initial_date,9,2) & "/" & Mid(initial_date,6,2) & "/" & Mid(initial_date,1,4))
Range("A1").Value = publish_date
This seems to work fine. The cell automatically changes format to "Date" and when I calculate the difference between these dates and dates in another column, it works fine.
I then pick up these dates again and add to an array:
feed(1, 8) = Range("A1")
and then transfer this value into another array:
new_array(7, 1) = feed(1, 8)
Finally, I insert the value from the new array into a different cell. Having used UK date formatting thus far, I now want this value to display in the form "mm/dd/yyyy".
Range("E1") = new_array(7, 1)
Range("E1").NumberFormat = "mm/dd/yyyy"
This is where it goes wrong.
Running the code as above, the dates are all displayed as "dd/mm/yyyy" format. Excel changes the format of the cells to "custom". Finding the difference between these and other dates works, so the data seems to be stored correctly but not displaying as I want.
If I change the code to
Range("E1") = new_array(7, 1)
Range("E1").NumberFormat = "dd/mm/yyyy"
the dates still do not display correctly. Dates which can be written either way around (i.e. day is equal to or less than 12) display correctly, but are in fact the wrong date. i.e. 2014-12-11T04:59:00Z displays as 12/11/2014 which is what I want, but Excel thinks the date is the 12th November instead of 11th December. Dates such as 29/09/2014 which cannot be written both ways round display in UK format, but are not recognised properly by Excel which thinks the long date should be "29/09/2014" instead of "29 September 2014".
When I remove the formatting line completely, the results are the same.
I'm sorry for the rather long-winded explanataion, but there's clearly something I'm not understanding about how Excel and VBA handle, store and format dates. If anyone could enlighten me what's going wrong, I'd really appreciate it!
(Note, in all the code snippets above, where I quote e.g. Range("A1") this is shorthand. There is in fact a lot more code involved in looping and selecting values, but I know this works, so I am not concerned. The extracts above just demonstrate what happens for the first value in each loop.)

try
Range("E1").NumberFormat = "mm/dd/yyyy"
Range("E1") = Format(new_array(7, 1), "mm/dd/yyyy")

Related

excel: change format dates in advanced filter

I'm using the Advanced Filter to search between dates in a database.
I placed my criteria side by side so I can seach for one or more information together.
Here is the example:
This is the code:
Sub FiltroAutomatico()
'
' FiltroAutomatico Macro
'
'
Sheets("BASE_TOTAL_ATUAL").Range("A1:J445").AdvancedFilter Action:= _
xlFilterCopy, CriteriaRange:=Range("CONSULTA!Criteria"),
CopyToRange:=Range _
("CONSULTA!Extract"), Unique:=False
Range("H25").Select
ActiveWindow.SmallScroll Down:=-15
Range("G3").Select
End Sub
Anyway, the problem is that when I search for something like >03/03/2017 and <25/03/2017 it didn't work as I expected.
I think the problem it's because Excel it's not recognizing my dates correctly (my Excel is in portuguese and the date here has the dd/mm/yyyy format). I tested using US dates instead and it worked perfectly.
Is there any way to change the format dates from an Advanced Filter to understand that the format of my criteria is dd/mm/yyyy instead of mm/dd/yyyy?
I cannot test this, but dates in VBA filters have always been US-centric. I would suggest that you have your users enter the actual starting and end date in your local format (but NOT in the actual criteria range). In the criteria range itself, use this formula:
=">" & StartDate
="<" & EndDate
Where StartDate and EndDate refer to the dates entered by your user.
You could even leave it in the same physical location as you show above, but have the criteria range elsewhere. Or you could have them enter it on a User Form.
The cell will display something like >49076 where the number is the number of days since (usually) 1/1/1900. But it should work.
If you have them enter the dates elsewhere, be sure to LOCK and PROTECT the criteria cells so the user cannot delete or change the formula.

Trim function causes date format change

Firstly, important to note that I'm in the UK so standard date format is dd/mm/yyyy
In a A1, I have a date: 02/05/2017 (dd/mm/yyyy)
I can confirm this in the immediate window:
?CLng(Range("A1").Value)
42857
Now, if I do the following:
Range("A1").Value = Range("A1").Value
you can probably guess, nothing happens - the date is still 02/05/2017 and the numeric value is still 42857
But if I use trim with it:
Range("A1").Value = Trim(Range("A1").Value)
The date is changed to 05/02/2017. This isn't just formatting - the numeric value has also changed to 42771.
What is it about the Trim() method that causes the date to be read in US format and then converted back to UK format with a new date value? Is this a bug?
From the discussion in comments:
The default or "token" format in VBA (not Excel itself, as Macro Man rightly pointed out) is US English - regardless of regional settings or cell formatting.
When you do VBA text functions on a date, the output of those functions are in text format. So the result of Trim(Range("A1").Value) is a string. This string happens to resemble a proper US date, so when you insert it into a cell, Excel recognizes it as a US date.
So two implicit conversions happen. The first happens when you read the cell contents and pass it to trim(): date->text conversion; the second happens when you write it back to an Excel cell: text->date conversion. The second conversion has no information about the format, so it assumes US English.
(You should be able to achieve the same result with any text function, not just trim().)
I found out that if you add "'" before the date, the date is not altered.
Range("A1").Value = "'"&Trim(Range("A1").Value)

VBA Date 31/12/1899

I'm reading in data from a spreadsheet into a dictionary but having problems with a date field.
The code that reads in the data is
sourceworkbook.setRangeSingleCell "Review date(1)", cell.Row
dictionaryObject.ReviewDate = sourceworkbook.range.Value
This sets the range to the cell I want based on the column header and then grabs the value before putting it into the dictionary. Reviewdate is defined as a string inside a class.
I then do nothing with this particular field and just dump it back out from the dictionary to a different spreadsheet as follows:
targetWorkbook.setRangeSingleCell "Review Date", foundRowNumber
targetWorkbook.range.Value = Dictionary.Item(Key).ReviewDate
However, whilst this works fine with some dates, some show as 31/12/1899, Looking at my current dump I have a date of 18/07/2016 that has worked fine, but a date of 28/06/2016 has not.
Any help is much appreciated,
Thanks,
Mark

How to use UserForm Values for multiple things

I have UserForm1 which is a multipage userform and I am trying to access the information that was gathered through the form in a sub located in Module1. This sub will need to access several different values and do different things with those values so this is going to be a multipart question.
I have the below code in which I attempt to use one of the values as the upper limit of a For Next Loop. However the current problem is that when the code reaches this line it jumps to the Userform_Initialize routine.
For X = 1 To UserForm1.LocalOffer.Value
Second part of this question comes from inside the For Next loop from above. Where I have the below code. Which would ideally allow me to cycle through a series of similarly named Textboxes from the userform. Not even sure if that will work as the code keeps breaking before getting to that part.
Range("B" & X).Value = UserForm1.Controls("LocalTier" & Tier).Value
Last Part of this question if I have a Textbox in the userform that contains a date in the format 1/18/2015 is there a way for me to grab just a portion of that date say for instance just the Day or just the last digit of the year?
I am using Excel 2013 but the file will be ran on Excel 2007
Edit:
Turns out that problem 1 was fixed by not closing the userform with the X button but instead adding a line to hide the userform when you hit the last button. As it turns out my code for the second question worked just fine once i got past that. Only question left is the last one which I have no ideas on.
As from the comments, I see you don't need anymore to know about points 1 and 2, I will hence limit my answer to the point 3.
Last Part of this question if I have a Textbox in the userform that contains a date in the format 1/18/2015 is there a way for me to grab just a portion of that date say for instance just the Day or just the last digit of the year?
You can use either string manipulation, or date conversion.
Let's assume the Textbox is called myDateTextbox
String manipulation
Among the string manipulators that VBA provides, I would cite Left() and Right().
For example:
last_digit_of_the_year = Right(myDateTextbox.Text, 1)
will return you the last character of the string. On the other hand:
first_digit = Left(myDateTextBox.Text,1)
will return you the first digit of the string.
You can use the Len(myDateTextBox.Text) built-in to return the current length of the string.
Date conversion
You can simply convert your string into date using the CDate() function. Please note this function will return an error if you pass an invalid string. If your textbox contains 24/01/1990, you can first convert the string into a date:
myDate = CDate(myDateTextBox.Text)
Hence, you can retrieve day, month or year like this:
myYear = Year(myDate)
myMonth = Month(myDate)
myDay = Day(myDate)
Please note that CDate recognizes date formats according to the locale setting of your system.. Hence, if the format in the TextBox is not the same than the one of your system, then consider manipulating the string before to adapt it to the proper format. For example, if your system has settings DD/MM/YYYY and your textbox shows a MM/DD/YYYY type, you can "adjust it" as follows:
wrongFormat = myDateTextBox.Text
splittedDate = Split(wrongFormat,"/")
goodFormat = splittedDate(1) & "/" & splittedDate(0) & "/" splittedDate(2)
If wrongFormat was 1/18/2014 but your system would like to read it as 18/1/2014, it's now fine because goodFormat will be equal to 18/1/2014 after the split and re-build.

Excel - Copy the displayed value not the actual value

I am a pilot, and use a logbook program called Logten Pro. I have the ability to take excel spreadsheets saved from my work flight management software, and import them into Logten Pro using the CSV format.
My problem however, is that the work flight management software, exports the date and time of take-off of a flight into one cell in the following excel format: DD/MM/YYYY H:MM:SS PM.
This is handled fine by Excel, and is formatted by default to DD/MM/YY even though the actual value is more specific, comprising of the full length date and time group.
This is a problem because Logten Pro will only auto-import the date if it is in DD/MM/YY format, and there is no way to pull out just the displayed DD/MM/YY date rather than the full date time group actual value, unless you manually go through and delete the extra text from the function box.
My question is: Is there a VBA macro that can automatically copy the actual displayed text, and paste it into another cell, changing the actual value as it does, to just the DD/MM/YY value? Additionally, can this be made to work down a whole column rather than individual cells at a time?
Note I have no VBA experience so the perfect answer would just be a complete VBA string I could copy and paste.
Thank You.
As pointed out in the comments, you'd better not use VBA but formulas instead.
This formula:
TEXT(A1,"dd-mm-yyy")
will return the formated date in a text way. You can drag and drop the formula in the whole range of your cells and Copy/Paste Special > Values so that you will only have the needed values to get imported in Logten Pro.
There are three options using formulas.
Rounddown
Excel stores the date time as a number and uses formatting to display it as a date.
The format is date.time, where the integer is the date and the fraction is the time.
As an example
01/01/2012 10:30:00 PM is stored as 40909.9375
All the values after the decimal place relate to the hours and minutes
So a formula could be used to round the number down to a whole number.
=ROUNDDOWN(A1,0)
Then format the value as a short date.
It will then display as 01/01/2012
INT
As above, but using a different formula to get rid of the fraction (time)
=INT(A1)
Text
Alternately the date only could be extracted as text using this formula
=TEXT(A1,"dd/mm/yyyy")
It will then display as 01/01/2012
I'm a bit late to the party on this one, but recently came across this as was searching for answers to a similar problem.
Here is the answer I finally came up with.
Option Explicit
Sub ValuesToDisplayValues()
Dim ThisRange As Range, ThisCell As Range
Set ThisRange = Selection
For Each ThisCell In ThisRange
ThisCell.Value = WorksheetFunction.Text(ThisCell.Value, ThisCell.NumberFormat)
Next ThisCell
End Sub
This answers the question as asked, apart from the new values are pasted over the existing ones, not into a new cell, as there is no simple way to know where you would want the new values to be pasted. It will work on the whole range of selected cells, so you can do a whole column if needed.