【问题标题】:Can CDate be used on a Range without a for loop?可以在没有 for 循环的范围内使用 CDate 吗?
【发布时间】:2021-07-22 16:45:00
【问题描述】:

我有一个按以下方式格式化的列:

Range("A:A").NumberFormat = "dd.mm.yyyy" 

现在,我正在为此寻找一个高效的版本:

    For k = 1 To Range("A1").End(xlDown).Row
    ' from first to last row
    Cells(k, 1).Value = CDate(Cells(k, 1).Value)
    Next k

这需要很长时间;(有人知道有效的解决方案吗?谢谢!!!

我为什么需要这个? 运行时:

      With ws.Sort
        .SortFields.Add Key:=Range("A1"), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SetRange Range("A1", Range("A1").End(xlDown))
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

我得到了奇怪的排序:

01.01.2021
01.02.2021
01.03.2021
02.01.2021

【问题讨论】:

  • 将数据加载到数组中,对其进行处理,然后将其写回范围。
  • 或者使用 Data - Text to Columns 就可以了。
  • 我真的不明白你的循环,你为什么不复制/粘贴然后格式化列?我在这里缺少什么?
  • 我编辑了我的问题。我正在为排序目的进行所有这些 CDate 转换。我有德国日期,但不同的计算机默认日期。因此,我需要确保始终保留 dd.mm.yyyy 格式。 CDate 正在解决该问题以执行排序,无论是哪个系统。
  • 如果您排序的列不包含日期,则字符串的排序会正确返回。您确定该列包含日期类型值吗?

标签: excel vba date


【解决方案1】:

可以在没有 for 循环的范围内使用 CDate 吗?

是的,可以在没有循环的情况下转换您的范围,但 Excel 中没有 CDATE 公式,因此您必须将公式 Date()RIGHT()MID()LEFT()

例如

=DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))

现在回答你的问题

试试这个

Option Explicit

Sub Sample()
    Dim rng As Range
    Dim sAddr As String
    Dim ws As Worksheet
    Dim lRow As Long
    
    '~~> Change Sheet as applicable
    Set ws = Sheet1
    
    With ws
        lRow = .Range("A" & .Rows.Count).End(xlUp).Row
        
        Set rng = .Range("A1:A" & lRow)
        sAddr = rng.Address

        rng = Evaluate("index(DATE(RIGHT(" & sAddr & _
                       ",4),MID(" & sAddr & ",4,2),LEFT(" & _
                       sAddr & ",2)),)")
        
        '~~> Change to whatever format you want
        rng.NumberFormat = "dd/mm/yyyy"
    End With
End Sub

解释见Convert an entire range to uppercase without looping through all the cells

行动中

话虽如此,我更喜欢上面提到的@Rory。使用Data - Text to Columns

【讨论】:

  • 谢谢悉达多。如果我做对了,您的代码正在交换 dd 和 mm,对吗?实际上,格式已经很好了,我想保留 dd.mm.yyyy 。但是当我对格式化列使用排序时,它会对 dd 执行奇怪的排序,因为它只被识别为数字。然而,当我使用 for 循环时,一切都被识别得很好。
  • your code is swapping dd and mm, right? 不,它没有。 Actually, the format is already fine, I want to keep dd.mm.yyyydd.mm.yyyy 不是正确的“日期”格式。
  • 好的,所以正确的意思是:mm.dd.yyyy?我还能以某种方式处理 datedd.mm.yyyy 吗? (用于排序)
  • Ok, so correct would mean: mm.dd.yyyy ? 不,我指的是“.”。这就是为什么我使用rng.NumberFormat = "dd/mm/yyyy" 上面的日期可以按升序或降序排序。
  • 非常感谢,终于成功了。我使用此函数将另一个文件转换为基础值.NumberFormat = "@"。再次感谢你!!!!!真的很高兴得到您的帮助!!!!
猜你喜欢
  • 2021-06-19
  • 2012-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 2013-07-15
相关资源
最近更新 更多