I have the following text in cell A1
09-03-22
that's mm-dd-yyyy
the type is general but I want to Convert it into Date with the format dd.mm.yyyy
Can be in Excel or with vba....
Because if I change the type to date it always returns as 09.03.2022 or 09 March 2022 ... Excel thinks my month is my day and the other way around. But what I want is 03.09.2022
With VBA, this is one way to do it in the ActiveCell:
Sub TxtDateToDate()
Dim strDate As String
With ActiveCell
strDate = .Value
strDate = Split(strDate, ".")(1) & "/" & _
Split(strDate, ".")(0) & "/" & _
Split(strDate, ".")(2)
.Formula = .Value + 0 'shake cell format
.Formula = DateValue(strDate)
.NumberFormat = "MM.DD.YYYY"
End With
End Sub
If I correctly understood your case, it looks that there is a column having inconsistent Date/String data. The existing Date swaps the day with month and the string date starts with month followed by day.
If this is the case, please try the next code. It assumes that the column to be processed is A:A, and returns in column B:B. You can easily change the two columns:
Sub ConvertText_DateToDate()
Dim sh As Worksheet, lastR As Long, arr, arrD, arrStrD, i As Long
Set sh = ActiveSheet
lastR = sh.Range("A" & sh.rows.count).End(xlUp).row
arr = sh.Range("A2:A" & lastR).Value2
ReDim arrD(1 To UBound(arr), 1 To 1)
For i = 1 To UBound(arr)
If IsNumeric(arr(i, 1)) Then
arrD(i, 1) = DateSerial(Year(arr(i, 1)), Day(arr(i, 1)), Month(arr(i, 1)))
Else
arrStrD = Split(arr(i, 1), "/")
arrD(i, 1) = DateSerial(CLng(arrStrD(2)), CLng(arrStrD(0)), CLng(arrStrD(1)))
End If
Next i
'format and drop the processed array content, at once:
With sh.Range("B2").Resize(UBound(arrD), 1)
.NumberFormat = "dd-mm-yyyy"
.Value2 = arrD
End With
End Sub
But, if the Date part did not swap day with month, you have to use
arrD(i, 1) = arr(i, 1)
Instead of:
arrD(i, 1) = DateSerial(Year(arr(i, 1)), Day(arr(i, 1)), Month(arr(i, 1)))
Related
There is column A and B with different date format :
20200714
44043
2020/09/01
2021/1/4
is there any VBA to standardize the date format as the same format?
2020/7/14
2020/7/31
2020/9/1
2021/1/4
Sub text()
Dim lastRow, l As Long
lastRow = Range("a65536").End(xlUp).Row
For l = 2 To lastRow
Range("A" & l).Select
Selection.NumberFormatLocal = "yyyy/m/d"
Next
End Sub
after run code, some cell show as ####, some looks good as yyyy/m/d.
Please, try the next function:
Function DateConv(strVal) As Date
If IsDate(strVal) Then
DateConv = strVal
ElseIf IsNumeric(strVal) And Len(strVal) = 5 Then
DateConv = CDate(CLng(strVal))
ElseIf IsNumeric(strVal) And Len(strVal) = 8 Then
DateConv = DateSerial(CLng(left(strVal, 4)), CLng(Mid(strVal, 5, 2)), CLng(Right(strVal, 2)))
ElseIf Len(strVal) = 8 Then
Dim arrD: arrD = Split(strVal, "/")
DateConv = DateSerial(CLng(arrD(0)), CLng(arrD(1)), CLng(arrD(2)))
End If
End Function
It can be used to convert a column (A:A as example) in the next way:
Sub makeDate()
Dim sh As Worksheet, lastR As Long, arr, arrD, i As Long
Set sh = ActiveSheet
lastR = Range("A" & sh.rows.count).End(xlUp).row
arr = sh.Range("A2:A" & lastR).value
ReDim arrD(1 To UBound(arr), 1 To 1)
For i = 1 To UBound(arr)
arrD(i, 1) = DateConv(arr(i, 1))
Next i
With sh.Range("A2").Resize(UBound(arrD), 1)
.NumberFormat = "yyyy/mm/dd"
.value = arrD
End With
End Sub
Of course, the range to be converted must exist in column "A:A"...
There may be problems only if the format date (brought from somewhere...) does not have a similar format. I mean "yyyy/dd/mm" instead of "yyyy/mm/yy".
I'm new using VBA and I'm trying to code into VBA but it didn't work so far, my timestamp data is not common and I got 10000+ rows to do the same formula (sometime excel just crash so i would like to try VBA)
timestamp that I tried split
Edit : add code
Sub Split_text_3()
Dim p As String
For x = 1 To 6 '---How do it until last cell?
Cells(x, 2).Value = Mid(Cells(x, 1).Value, 9, 2) 'combind in same cell
Cells(x, 3).Value = Mid(Cells(x, 1).Value, 5, 3) 'combind in same cell
Cells(x, 4).Value = Mid(Cells(x, 1).Value, 21, 4) 'combind in same cell
Cells(x, 5).Value = Mid(Cells(x, 1).Value, 12, 8)
Next x End Sub
and the data look like this (I tried to separate it first and then might try to combine them later)
image
Please, try the next function:
Function extractDateTime(strTime As String) As Variant
Dim arrD, d As Date, t As Date
arrD = Split(strTime, " ")
d = CDate(arrD(2) & "/" & arrD(1) & "/" & arrD(4))
t = CDate(arrD(3))
extractDateTime = Array(d, t)
End Function
It can be tested in the next way:
Sub testExtractDate()
Dim x As String, arrDate
x = "WED SEP 08 08:13:52 2021"
arrDate = extractDateTime(x)
Debug.Print arrDate(0), arrDate(1)
End Sub
If it returns as you need (I think, yes...), you can use the next function to process the range. It assumes that the column keeping the strings are A:A, and returns in C:D:
Sub useFunction()
Dim sh As Worksheet, lastR As Long, Arr, arrDate, arrFin, i As Long
Set sh = ActiveSheet
lastR = sh.Range("A" & sh.rows.count).End(xlUp).row
Arr = sh.Range("A2:A" & lastR).Value
If IsArray(Arr) Then
ReDim arrFin(1 To UBound(Arr), 1 To 2)
For i = 1 To UBound(Arr)
If Arr(i, 1) <> "" Then
arrDate = extractDateTime(CStr(Arr(i, 1)))
arrFin(i, 1) = arrDate(0): arrFin(i, 2) = arrDate(1)
End If
Next i
sh.Range("C2").Resize(UBound(arrFin), 2).Value = arrFin
Else
sh.Range("C2:D2").Value = extractDateTime(CStr(sh.Range("A2").Value))
End If
End Sub
I think I have another solution (not bulletproof) but it is simplier, quicker and code less solution (no offense FraneDuru!):
Sub DateStamp()
Dim arr, arr_temp, arr_new() As Variant
Dim i As long
'Take cells from selected all the way down to 1st blank cell
'and assign values to an array
arr = ThisWorkbook.ActiveSheet.Range(Selection, Selection.End(xlDown)).Value
ReDim Preserve arr_new(1 To UBound(arr), 1 To 2)
For i = 1 To UBound(arr)
'Make another array by spliting input string by whitespace delimiter (default)
arr_temp = Split(arr(i, 1))
'Construct values in desired "format"
arr_new(i, 1) = "'" & arr_temp(2) & "/" & arr_temp(1) & "/" & arr_temp(4)
arr_new(i, 2) = arr_temp(3)
Next i
'Paste result into Excel
Selection.Offset(0, 1).Resize(UBound(arr), 2) = arr_new
End Sub
All you have to do is to select the cell toy want to start with and run the macro! :)
Bellow also a picture with watches, so you can catch-up what is going on:
I have tried multiple codes such as this
Sub DateFixer()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
For Each r In Selection
v = r.Text
r.Clear
r.NumberFormat = "dd/mm/yyyy hh:mm:ss"
r.Value = DateSerial(Mid(v, 7, 4), Mid(v, 4, 2), Left(v, 2)) + TimeSerial(Mid(v, 12, 2), Mid(v, 15, 2), Right(v, 2))
Next r
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
and this
Application.ActiveWorkbook.Worksheets("data").Range("A1:A3").NumberFormat = "dd/mm/yyyy hh:mm:ss am/pm
"
and this
Sub changeformat()
Dim lastrow As Long
lastrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
'MsgBox lastrow
For i = 2 To lastrow
Cells(i, 2).NumberFormat = ("dd/mm/yyyy hh:mm:ss am/pm")
Next i
End Sub
But it still did not change my DateTime to 9/12/20 09:28:00 am. May i know what did i do wrongly?
You can do it splitting each part and forcing them into dates. Then sum up and then change format:
Sub changeformat()
Dim lastrow As Long
Dim i As Long
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastrow
Cells(i, 1).Value = CDate(Replace(Split(Cells(i, 1), " ")(0), ".", "/")) + CDate(Split(Cells(i, 1), " ")(1))
Cells(i, 1).NumberFormat = ("dd/mm/yyyy hh:mm:ss am/pm")
Next i
End Sub
After executing code I get:
Notice the value 9.12.20 09:27:60 can't be converted because 09:27:60 is not a valid time. Seconds always go from 00 to 59, not from 1 to 60. So actually 09:27:60 should be 09:28:00
I'm afraid you'll need to code an exception for this cases.
As shown by the fact that, when in General format, the cell is still displaying a date/time string, the date/time stamps are Text strings and not "real" Excel dates (which are stored as days and fractions of a day).
First we have to convert the string to a "real" date. Then one can use the .NumberFormat property to display it in a cell however we want.
Fortunately, the format seems fixed so we can split on the dot/space and colon to get the different date/time parts.
The code below assumes
all the dates are text strings
the number format codes for dates are mdy and for time hms
As written, the results will be written in the adjacent column. To change it in place, see the comments in the code.
Option Explicit
Sub dateFixer()
Dim vSrc As Variant, vRes As Variant
Dim rSrc As Range, rRes As Range
Dim V, W, X, I As Long
With ActiveSheet
Set rSrc = .Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp))
'set rRes = rSrc to overwrite original
Set rRes = rSrc.Offset(rowoffset:=0, columnoffset:=1)
End With
'read into vba array for speedy processing
vSrc = rSrc
'Dim output array
ReDim vRes(1 To UBound(vSrc, 1), 1 To UBound(vSrc, 2))
'process the string dates
For I = 1 To UBound(vSrc, 1)
V = Split(vSrc(I, 1), ".") '0=day, 1 = month
W = Split(V(2), " ") ' 0=year
X = Split(W(1), ":") ' 0,1,2 = hr:min:sec
vRes(I, 1) = DateSerial(W(0), V(1), V(0)) + TimeSerial(X(0), X(1), X(2))
Next I
'Write the results back to the worksheet
Application.ScreenUpdating = False
With rRes
.EntireColumn.Clear
.Value = vRes
.NumberFormat = "dd/mm/yy hh:mm:ss"
End With
End Sub
This the data I have.
I just want its month name and year.
For example 201804: Apr 2018
Try this UDF
Sub Test()
Debug.Print FormatDate("201804")
End Sub
Function FormatDate(sInput As String)
sInput = "1/" & Right(sInput, 2) & "/" & Left(sInput, 4)
FormatDate = Format(CDate(sInput), "mmm yyyy")
End Function
Try
Sub test()
Dim vDB
Dim i As Long
Dim s As String, y As String, m As String
vDB = Range("a1", Range("a" & Rows.Count).End(xlUp))
For i = 2 To UBound(vDB, 1)
s = vDB(i, 1)
y = Left(s, 4)
m = Right(s, 2)
vDB(i, 1) = Format(DateSerial(y, m, 1), "mmm yyyy")
Next i
With Range("b1").Resize(UBound(vDB, 1), 1)
.NumberFormatLocal = "#"
.Value = vDB
End With
End Sub
Here is the worksheet formula, converting the date in A1. Copy the formula down as required.
=DATE(LEFT(A1,4),RIGHT(A1,2),1)
The result is a proper date set for the first day of the month, in this case April 1, 2018. The format in which this result is displayed depends entirely upon your system settings. However, you can over-ride the system by setting a custom date format in Format > Cells > Numbers > Custom*. Set Type as mmm yyyy to display Apr 2018 in the cell.
I'm trying to populate a date from a data source in which the date is formatted as datetime. The destination file can only accept the mm/dd/yy format to upload to our system, but everything that I try is either only cosmetically formatting the date (i.e. datetime still shows in the formula bar) or converts the data to m/d/yyyy which also won't work.
Below is what I've tried, with no success:
Via VBA (only cosmetically changes the format):
[T:T].Select
With Selection
.NumberFormat = "mm/dd/yy"
.Value = .Value
End With
Using VBA to create a temporary helper column U with the below formula (gets me to m/d/yyyy:
=MONTH(T2)&"/"&DAY(T2)&"/"&YEAR(T2)
I know that I can create a bunch of conditional statements to make the above work, but was curious if there was a less convoluted way to solve what seems like a very simple problem.
Edit: To be clear, the result will likely have to be stored as a string.
Per Scott Craner's advice, the following loop worked perfectly!
For i = 2 To LastRow
Range("T" & i).NumberFormat = "#" 'Format as text to prevent excel from taking over
Range("T" & i) = Format(Range("T" & i), "mm/dd/yy")
Next i
Try
Sub test()
Dim rngDB As Range
Dim vDB
Dim i As Long, r As Long
Set rngDB = Range("t1", Range("t" & Rows.Count).End(xlUp))
vDB = rngDB
r = UBound(vDB, 1)
For i = 1 To r
vDB(i, 1) = Format(vDB(i, 1), "mm/dd/yy")
vDB(i, 1) = Replace(vDB(i, 1), "-", "/")
Next i
rngDB.NumberFormatLocal = "#"
rngDB = vDB
End Sub
Try forcing the NumberFormat to text. Here is an example.
Option Explicit
Sub SetDateTime()
Dim lngRow As Long
For lngRow = 1 To 10
Cells(lngRow, 20).Value = Now
Next lngRow
End Sub
Sub ReformatDate()
Dim lngRow As Long
Dim datX As Date
Dim strX As String
For lngRow = 1 To 10
strX = Cells(lngRow, 20).Value
If IsDate(strX) Then
datX = CDate(strX)
Cells(lngRow, 20).NumberFormat = "#"
Cells(lngRow, 20).Value = Format(datX, "mm/dd/yy")
End If
Next lngRow
End Sub