这应该足以满足您的需要。我不关心这里的.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