与区域设置无关的文本到日期转换功能

时间:2018-02-08 11:14:21

标签: excel vba excel-vba

我正在尝试将看起来像“MMM DD YYYY”的字符串(例如“2015年1月17日”)转换为Excel序列日期。
问题是:我正在运行国际版本的Windows,DATEVALUE和CDate()都不识别这种格式(它们依赖于系统区域设置)。而且,当我写这个函数时,我不知道它将在哪个语言环境中使用 这篇文章:Excel VBA - Convert Text to Date?提供了一个很好的解决方案(以编程方式调用TextToColumns),但它对我没用 - 我需要一个函数(或UDF)来处理公式中的字符串。那些“日期”是另一个计算的结果(实际上是regexps),因此我不能在这些单元格上使用TextToColumns - 它会搞砸它们。

是的,我可以编写一个带有静态查找表的UDF,它将数字输入DateSerial(),但也许有更好的方法?

澄清这不是关于d / m / y的固定顺序。主要罪魁祸首是一个月的文本名称 - 它是英文的,因此国际版的Excel将无法识别它。例如,2月是芬兰语语言环境中的“helmikuuta”和波兰语中的“luty”:)

ON ANSWERS 哇这么多有用的答案!到目前为止,我使用SO的经验相当消极 - 我问了一个问题,没有人说任何建设性的东西,最后我开发了一个解决方案,并自己回答了这个问题。然而,这一次,我感到惊喜,我对人性的信念得到了恢复:)现在将审查答案并对它们发表评论......

4 个答案:

答案 0 :(得分:4)

这是一个简单的UDF,

Function repairDate(str As String)
    Dim arr As Variant, mnths As Variant

    mnths = Array("Jan", "Feb", "Mar", _
                  "Apr", "May", "Jun", _
                  "Jul", "Aug", "Sep", _
                  "Oct", "Nov", "Dec")
    arr = Split(str, Chr(32))
    repairDate = DateSerial(arr(2), _
                    Application.Match(arr(0), mnths, 0), _
                    arr(1))
End Function

这将返回序列日期。建议您使用以*开头的日期格式之一,因为它们是跨语言支持。

enter image description here

答案 1 :(得分:3)

假设您的原始文本日期是A1,此公式应该为您提供所需的输出:

=DATE(RIGHT(A1,4),MONTH(DATEVALUE(LEFT(A1,3)&" 1")),MID(A1,5,2))

这是它的工作原理:

1)我们以这种方式从字符串中提取日期部分:

右(A1,4)给你一年

MID(A1,5,2)给你一天

左(A1,3)给你月份

2)我们将月份转换为MONTH数字,而月份部分只转换为DATEVALUE

3)最后我们将这些值传递给DATE函数。

仅对月份使用日期值应与您的国际设置一起使用。

答案 2 :(得分:3)

如果您需要UDF,也许这可以提供帮助

Public Function CONVERT_DATE(ByRef rng As Range) As Date

Dim MyDate As Variant
MyDate = Split(rng.Value, " ")


'month is always mydate(0). So we use select case
Select Case UCase(MyDate(0))
    Case "JAN"
        MyDate(0) = 1
    Case "FEB"
        MyDate(0) = 2
    Case "MAR"
        MyDate(0) = 3
    Case "APR"
        MyDate(0) = 4
    Case "MAY"
        MyDate(0) = 5
    Case "JUN"
        MyDate(0) = 6
    Case "JUL"
        MyDate(0) = 7
    Case "AUG"
        MyDate(0) = 8
    Case "SEP"
        MyDate(0) = 9
    Case "OCT"
        MyDate(0) = 10
    Case "NOV"
        MyDate(0) = 11
    Case "DEC"
        MyDate(0) = 12
End Select

'mydate(1) is day
'mydate(2) is year

CONVERT_DATE = CDate(Format(Join(MyDate, "/"), "dd/mm/yyyy"))

End Function

仅当您的数据始终为

时才会有效
  

“2015年1月17日”

答案 3 :(得分:1)

鉴于您的日期位于从第5行开始的A列中:

Sub CorrectDateArray ()
    Dim MySheet As Worksheet, DateRange As Range
    Dim lRow As Long, vArr(), i As Integer
    '    Designate your worksheet, where MySheet is your actual name
    Set MySheet = Thisworkbook.Worksheets("MySheet")
    '    Last row
    lRow = MySheet.Range("A" & MySheet.Rows.Count).End(xlUp).Row
    '    Designate DateRange
    Set DateRange = MySheet.Range("A5:A" & lRow)
    '    Put values of array formula into array
    vArr = Evaluate("=LEFT(REPLACE(" & DateRange.Address & ",1," & _
                        "FIND(" "," & DateRange.Address & ",1),"")," & _
                            "FIND(" ";REPLACE(" & DateRange.Address & ",1," & _
                                "FIND(" ",N2,1),""),1)) & " & _
                    "LEFT(" & DateRange.Address & ";FIND(" "," & DateRange.Address & ",1)) & " & _
                    "RIGHT(" & DateRange.Address & ",4)")
    '    Finaly, a correct array of dates
    For i = Lbound(vArr) To Ubound(vArr)
        vArr(i) = CDate(vArr(i))
    Next
End Sub