This should suffice for what you need. I don't care for the .Range("C:C")
here, but this should be fine as long as column C only ever has this data in it. The problem with using .Range("C:C")
is that it will always modify and load the entire column which can reduce performance. If I have a chance, ill edit the code to use a more elegant solution, I just wanted to get a working answer up first to get you started.
In any event, here's the code:
Sub FixDateFormatting()
Dim ArrayDates() As Variant
' Load all the dates into an array for modification
ArrayDates = ThisWorkbook.Sheets(1).Range("C:C").Value
' Edit the format of the destination to be text based. This will prevent Excel from assuming format
' Note: This must be done after the values are put into the array, otherwise you could load values in the
' wrong format.
ThisWorkbook.Sheets(1).Range("C:C").NumberFormat = "@"
Dim i As Long
' Loop through the array and properly format all of the data
For i = LBound(ArrayDates, 1) To UBound(ArrayDates, 1)
ArrayDates(i, 1) = Format(CStr(Replace(ArrayDates(i, 1), ".", "/")), "dd/mm/yyyy hh:mm:ss")
Next
' Output the modified data
ThisWorkbook.Sheets(1).Range("C:C").Value = ArrayDates
End Sub
Replace ThisWorkbook.Sheets(1)
with an appropriate reference to the sheet you are modifying. You don't have to if the target sheet is the first sheet within the workbook running the code.
This should be much better than a loop. The only downside to this approach is that in order to retrieve the values from these cells and perform operations on them (using the dd-mm-yyyy format) is that you have to retrieve and manipulate these values in another array. If you try using excel formulas on these values you will not get the expected results. This is unavoidable (at least to my knowledge) when you are using a non-standard date format.
Let me know if you have any questions.
Take care,
Brandon
EDIT:
Here's a slightly more elegant solution that should have a slight performance increase. I made it (hopefully) easier to set the correct target worksheet. I also have resized the range to only include the necessary number of rows. See below:
Sub FixDateFormatting()
Dim TargetSheet As Worksheet
' Set the correct target sheet here:
Set TargetSheet = ThisWorkbook.Sheets(1)
Dim LastColRow As Long
' Store the absolute last row within a long variable for later use
LastColRow = TargetSheet.Range("C1048576").End(xlUp).Row
Dim TargetRange As Range
' Assumes your data starts in cell 2 (has a header row). Change the 2 as needed.
Set TargetRange = TargetSheet.Range("C2:C" & LastColRow)
Dim ArrayDates() As Variant
' Load all the dates into an array for modification
ArrayDates = TargetRange.Value
' Edit the format of the destination to be text based. This will prevent Excel from assuming format
' Note: This must be done after the values are put into the array, otherwise you could load values in the
' wrong format.
TargetRange.NumberFormat = "@"
Dim i As Long
' Loop through the array and properly format all of the data
For i = LBound(ArrayDates, 1) To UBound(ArrayDates, 1)
ArrayDates(i, 1) = Format(CStr(Replace(ArrayDates(i, 1), ".", "/")), "dd/mm/yyyy hh:mm:ss")
Next
' Output the modified data
TargetRange.Value = ArrayDates
End Sub
EDIT (Again):
This last solution is far more elegant and preserves the "DATE" format. You can then edit the cell as needed. This uses a UDF (user defined function). You can just type the function with the date to be fixed as the target. It will output a date that you can then modify to the formatting you need:
Public Function FixDateFormat(InputDate As String) As Date
' This will ensure that the string being input is appropriate for this function
' Modify the pattern as needed.
If InputDate Like "##.##.#### ##:##:##" Then
Dim DateTime As Variant
DateTime = Split(InputDate, " ")
Dim DateInfo As Variant
DateInfo = Split(DateTime(0), ".")
Dim HolderString As String
HolderString = Format(DateInfo(1), "00") & "/" & Format(DateInfo(0), "00") & "/" & Format(DateInfo(2), "0000") & " " & DateTime(1)
Debug.Print HolderString
Dim OutputDate As Date
OutputDate = CDate(HolderString)
FixDateFormat = OutputDate
Else
' Comment out this line to return a "#VALUE" error instead
FixDateFormat = vbNullDate
Exit Function
End If
End Function