我的列中包含正确格式的日期:
我想首先改变"。"到" /"哪个工作正常,以下代码,但它会自动修改日期格式,并将日期识别为月份,如果它在12岁以下。
'2) Replace "." by "/"
'Range("C:C").NumberFormat = "@" ' I tried with AND without this line...no difference
'Range("C:C").NumberFormat = "dd.mm.yyyy hh:mm:ss" ' if I add this then only "." starting from 13th of January are reaplced by "/"
'Range("C:C").NumberFormat = "dd/mm/yyyy hh:mm:ss" ' no differences at all neither
Columns("C:C").Select
Selection.Replace What:=".", Replacement:="/", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
太烦人了...任何想法如何解决这个问题?
答案 0 :(得分:2)
如果您不介意循环浏览数据,可以执行以下操作:
Sub Test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("SheetName")
For Each Cell In ws.Range("C2:C" & ws.Cells(ws.Rows.Count, "C").End(xlUp).Row)
Cell.Value = CDate(Replace(Cell.Value, ".", "/"))
Next Cell
End Sub
或者,如果您需要,可以使用辅助列并使用以下公式:
=TEXT(DATE(MID(C2,SEARCH(".",C2,SEARCH(".",C2,1)+1)+1,4),MID(C2,SEARCH(".",C2,1)+1,2),MID(C2,1,2))+TIMEVALUE(RIGHT(C2,8)),"dd/mm/yyyy hh:mm:ss")
答案 1 :(得分:2)
此代码在C2:C25
中使用Sheet1
,将其转换为内存数组,遍历该数组并将所有值转换为实际日期,然后转储转换后的代码D2:D25
上Sheet1
的值会在D列中应用所需的NumberFormat
,然后调整列的大小以适应。
结果是日期被正确地视为日期,自定义格式:
Public Sub ConvertToDate()
Dim target As Variant
target = ToArray(Sheet1.Range("C2:C25")) 'todo: adjust to desired range
Dim i As Long
For i = LBound(target) To UBound(target)
target(i) = ToDate(target(i))
Next
'here you'd probably dump the result in C2:
Sheet1.Range("D:D").NumberFormat = "dd.MM.yyyy hh:mm:ss"
Sheet1.Range("D2").Resize(UBound(target), 1).value = Application.WorksheetFunction.Transpose(target)
Sheet1.Range("D:D").EntireColumn.AutoFit
End Sub
Private Function ToDate(ByVal value As String) As Date
' make sure our assumptions are correct before going any further:
Debug.Assert value Like "##.##.#### ##:##:##"
Dim datetimeParts As Variant
datetimeParts = Strings.Split(value, " ")
Dim dateParts As Variant
dateParts = Strings.Split(datetimeParts(0), ".")
Dim datePart As Date
datePart = DateTime.DateSerial(dateParts(2), dateParts(1), dateParts(0))
Dim result As Date
result = CDate((CStr(datePart) & " " & datetimeParts(1)))
ToDate = result
End Function
ToArray
辅助函数就是这个函数(改编自this post):
Private Function ToArray(ByVal target As Range) As Variant
Select Case True
Case target.Rows.Count = 1
'horizontal 1D range
ToArray = Application.WorksheetFunction.Transpose(Application.WorksheetFunction.Transpose(target.value))
Case target.Columns.Count = 1
'vertical 1D range
ToArray = Application.WorksheetFunction.Transpose(target.value)
Case Else
'2D array: let Excel to the conversion itself
ToArray = target.value
End Select
End Function
您应该能够轻松调整此代码以使用您的工作表和数据。
答案 2 :(得分:1)
这应该足以满足您的需求。我不在乎.Range("C:C")
这里,但只要C列中只有这些数据,这就没问题了。使用。Range("C:C")
的问题在于它总是会修改并加载整个列,从而降低性能。如果我有机会,编辑代码以使用更优雅的解决方案,我只是想先得到一个有效的答案,让你开始。
无论如何,这里是代码:
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
将ThisWorkbook.Sheets(1)
替换为您正在修改的工作表的适当参考。如果目标工作表是运行代码的工作簿中的第一个工作表,则不必如此。
这应该比循环好得多。这种方法的唯一缺点是,为了从这些单元格中检索值并对它们执行操作(使用dd-mm-yyyy格式),您必须在另一个数组中检索和操作这些值。如果您尝试在这些值上使用excel公式,则无法获得预期结果。当您使用非标准日期格式时,这是不可避免的(至少据我所知)。
如果您有任何问题,请与我们联系。
小心,
布兰登
编辑:
这是一个稍微优雅的解决方案,应该会略微提升性能。我(希望)更容易设置正确的目标工作表。我还调整了范围,只包含必要的行数。见下文:
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
编辑(再次):
这最后一个解决方案更优雅,并保留了" DATE"格式。然后,您可以根据需要编辑单元格。这使用UDF(用户定义的函数)。您只需键入要将日期固定为目标的函数即可。它将输出一个日期,然后您可以将其修改为所需的格式:
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
答案 3 :(得分:0)
无需手动修改区域设置,您必须使用循环。
LastRow = Cells(Rows.Count, "C").End(xlUp).Row
Set r = Range(Cells(1, "C"), Cells(LastRow, "C"))
t = r.Value
For i = 1 To UBound(t)
t(i, 1) = Replace(t(i, 1), ".", "/")
Next
r.NumberFormat = ""
r.FormulaLocal = t
答案 4 :(得分:-1)
有多种方法可以解决这个问题,最明显的方法是调整NumberFormat
属性。尝试录制一些具有各种格式的宏,以了解它如何适合您。在您的情况下,代码可能是这样的:
Sheet1.Columns("C:C").NumberFormat = "mm/dd/yyyy"
答案 5 :(得分:-1)
这样的事情
Sub Makro3()
Columns("C:C").Select
Selection.NumberFormat = "dd\/mm\/yyyy hh:mm:ss"
End Sub
添加了hh:mm:ss