关于excel:”格式”或”日期”无法识别日期字符串

date string isn't recognized by “Format” or “Cdate”

我一直在尝试将这个字符串转换为日期格式变量,但是每次尝试似乎都行不通,

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
Option Explicit

Sub date()
    Dim m1 As Range
    Dim m As String
    Dim ddate As Date
    Set m1 = Worksheets("dates").Range("A9")
    'm1 text="somehting 31-Jan-2019"
    m = Right(m1, 11)
    m = Replace(m,"-","/") '"31/Jan/2019
    ddate = CDate(m)

End Sub

最后的'ddate'出现错误'类型不匹配'


CDate函数足够聪明,可以找出以短划线分隔的日期格式,因此无需将其替换为斜杠。如果提取日期文本,然后将其转换为日期变量,则可以使用日期变量执行任何操作。如果要以其他格式显示它,则必须先实际设置单元格/范围的格式,然后再在其中粘贴值。由于没有提供更多样本,因此我采取了自由做法,并添加了修整功能以确保正确提取日期文本:

1
2
3
4
5
6
7
8
9
10
11
12
13
Option Explicit

Sub ExtractDate()
    Dim s As String
    Dim d As Date

    s = Worksheets("dates").Range("A9").Value
    s = RTrim(s) 'remove the trailing space
    s = Right(s, 11)
    s = LTrim(s) 'remove the leading space
    d = CDate(s)

End Sub

执行此操作的更好方法是使用数组:

1
2
3
4
5
6
7
8
9
10
11
12
Sub ExtractDate()
    Dim s As String
    Dim arr As Variant
    Dim d As Date

    s = Worksheets("dates").Range("A9").Value
    s = RTrim(s) 'remove the trailing space
    arr = Split(s,"") 'split by space, so the date segment will be the last element
    s = arr(UBound(arr))
    d = CDate(s)

End Sub

这也是可以从工作表中调用的函数:

1
2
3
4
5
6
7
Function ExtractDate(cell As Range) As Date
    Dim arr As Variant

    arr = Split(RTrim(cell.Value),"") 'split by space, so the date segment will be the last element
    ExtractDate = CDate(arr(UBound(arr))) 'format cell as date to see in date format

End Function

enter image description here


一些建议:

  • 正如BigBen所说,您不能将Date用作过程名称
  • 另外,正如Tim所说,您必须了解您的区域设置(也许您的系统使用英语,但是您的月份缩写使用另一种语言)
  • 始终在模块顶部使用Option Explicit(这可以防止发生错误,例如使用未声明的变量并将其拼写错误。
  • 尝试将变量命名为以后可以理解的名称
  • 话虽如此,我使用两种方法解决了这个问题。

    阅读每种选择中的注释以了解正在发生的事情。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Sub ConvertDateAlternative1()

        Dim evalCell As Range
        Dim cellValue As String

        Dim resultYear As Long
        Dim resultMonth As Long
        Dim resultDay As Long

        Dim resultDate As Date

        ' Qualify the full location by adding the workbook. In this case Thisworkbook
        Set evalCell = ThisWorkbook.Worksheets("dates").Range("A9")
        'm1 text="somehting 31-Jan-2019"

        ' Alternative 1: if you know the exact location of each part of the date

        cellValue = evalCell.Value
        resultYear = Right(cellValue, 4)
        resultMonth = Month(Mid(cellValue, 14, 3) &" 1, 2000") ' -> Build a date from which VBA understands that Jan is month number 1 (this is sensitive to your regional settings)
        resultDay = Mid(cellValue, 11, 2)
        resultDate = DateSerial(resultYear, resultMonth, resultDay)

        Debug.Print"Date alternative 1: is" & Format(resultDate,"dd/mmm/yyyy")

    End Sub
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    Sub ConvertDateAlternative2()

        Dim evalCell As Range
        Dim cellValue As String
        Dim dateParts() As String ' -> In this case we need an array

        Dim resultYear As Long
        Dim resultMonth As Long
        Dim resultDay As Long

        Dim resultDate As Date

        ' Qualify the full location by adding the workbook. In this case Thisworkbook
        Set evalCell = ThisWorkbook.Worksheets("dates").Range("A9")
        'm1 text="somehting 31-Jan-2019"

        ' Alternative 2: By splitting the last segment of the string (this requires that the date comes after a space in the string)

        ' In a single step combined a split of the string by spaces Split(evalCell.Value,"") which returns an array
        ' And getting the last item in that array, which would be the date segment
        cellValue = Split(evalCell.Value,"")(UBound(Split(evalCell.Value,"")))

        ' Now, split the string that looks like a date by"-"
        dateParts = Split(cellValue,"-")

        ' In this order, day is the first item in the array, then comes the month and then the year
        resultDay = dateParts(0)
        resultMonth = Month(dateParts(1) &" 1, 2000") '-> To this one we apply the same trick as in alternative 1
        resultYear = dateParts(2)

        resultDate = DateSerial(resultYear, resultMonth, resultDay)

        Debug.Print"Date alternative 2: is" & Format(resultDate,"dd/mmm/yyyy")

    End Sub

    让我知道它是否有效