【问题标题】:Excel VBA: importing CSV with dates as dd/mm/yyyyExcel VBA:导入日期为 dd/mm/yyyy 的 CSV
【发布时间】:2010-04-14 01:42:52
【问题描述】:

我知道这是一个相当普遍的问题,但我还没有找到可靠的解决方案。

我在 csv 文件中有数据,第一列的格式为 dd/mm/yyyy。当我使用 Workbooks.OpenText 打开它时,它默认为 mm/dd/yyyy,直到它发现它认为月份超过 12,然后恢复为 dd/mm/yyyy。

这是我的测试代码,它试图将其强制为 xlDMYFormat,我也尝试过文本格式。我了解此问题仅适用于 *.csv 文件,不适用于 *.txt,但这不是可接受的解决方案。

Option Base 1
Sub TestImport()

Filename = "test.csv"

Dim ColumnArray(1 To 1, 1 To 2)

ColumnsDesired = Array(1)
DataTypeArray = Array(xlDMYFormat)

' populate the array for fieldinfo
For x = LBound(ColumnsDesired) To UBound(ColumnsDesired)
    ColumnArray(x, 1) = ColumnsDesired(x)
    ColumnArray(x, 2) = DataTypeArray(x)
Next x

Workbooks.OpenText Filename:=Filename, DataType:=xlDelimited, Comma:=True, FieldInfo:=ColumnArray

End Sub

test.csv 包含:

Date
11/03/2010
12/03/2010
13/03/2010
14/03/2010
15/03/2010
16/03/2010
17/03/2010

【问题讨论】:

    标签: excel vba csv


    【解决方案1】:

    我对 .OpenText 方法也有同样的问题。我的区域设置是英语 - 澳大利亚而不是新西兰。 我发现了另一个建议使用 .open 的线程, (http://www.pcreview.co.uk/forums/date-format-error-csv-file-t3960006.html) 所以我试过了 Application.Workbooks.Open 文件名:=strInPath,格式:=xlDelimited,本地:=True 并且成功了。

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。这是一个将 dd/mm/yyyy 转换为 mm/dd/yyyy 的函数。一次只喂它一个日期。希望对您有所帮助。

      Function convertDate(x As String) As Date
      'convert a dd/mm/yyyy into mm/dd/yyyy'
      Dim Xmonth
      Dim XDay
      Dim XYear
      Dim SlashLocation
      Dim XTemp As String
      
      
      XTemp = x
      SlashLocation = InStr(XTemp, "/")
      XDay = Left(XTemp, SlashLocation - 1)
      
      XTemp = Mid(XTemp, SlashLocation + 1)
      SlashLocation = InStr(XTemp, "/")
      Xmonth = Left(XTemp, SlashLocation - 1)
      
      XTemp = Mid(XTemp, SlashLocation + 1)
      XYear = XTemp
      
      convertDate = Xmonth + "/" + XDay + "/" + XYear
      
      End Function
      

      【讨论】:

        【解决方案3】:

        在“Workbooks.OpenText”行的末尾,添加 Local:=True

        Workbooks.OpenText filename:=filename, DataType:=xlDelimited, Comma:=True, FieldInfo:=ColumnArray, Local:=True
        

        当我将地区更改为英语(新西兰)时,这在我的电脑上有效。

        编辑:现在我看到其他人给出了相同的答案。 :-)

        【讨论】:

          【解决方案4】:

          意识到这有点晚了,但如果你结合本地和数组限定符它应该可以正常工作:

          Workbooks.OpenText Filename:=FileName, _
              FieldInfo:=Array(Array(1, 4), Array(2, 1)), Local:=True
          

          【讨论】:

            【解决方案5】:

            我正在尝试读取 txt 文件并使用澳大利亚日期格式 dd/mm/yyyy,但我知道您是否使用 Workbooks.Open 函数打开文本文件,您可以将日期设置为本地.. 通过添加 @987654323 @

            Workbooks.Open Filename:=VarOpenWorkbook, Local:=True
            

            这对我有用...

            【讨论】:

              【解决方案6】:

              这似乎可以解决问题,但仍然是一个 hack。我将添加一个检查,以确保该范围内的日期没有超过一天,以确保正确导入为 dd/mm/yyyy 的数据不会被反转。

              问题仍有待解决,而不是修补问题的方法。

              感谢迄今为止的帖子。

              Function convertDate(x As String) As Date
              ' treat dates as mm/dd/yyyy unless mm > 12, then use dd/mm/yyyy
              ' returns a date value
              
              Dim aDate() As String
              
              aDate = Split(x, "/")
              
              If UBound(aDate) <> 2 Then
                  Exit Function
              End If
              
              If aDate(0) > 12 Then
                  d = aDate(0)
                  m = aDate(1)
              Else
                  d = aDate(1)
                  m = aDate(0)
              End If
              
              y = aDate(2)
              
              d = Lpad(d, "0", 2)
              m = Lpad(m, "0", 2)
              
              If Len(y) = 4 Then
                  Exit Function ' full year expected
              End If
              
              uDate = y & "-" & m & "-" & d & " 00:00:00"
              convertDate = CDate(uDate)
              
              End Function
              
              Function Lpad(myString, padString, padLength)
                Dim l As Long
                l = Len(myString)
                If l > padLength Then
                  padLength = l
                End If
              
                Lpad = Right$(String(padLength, padString) & myString, padLength)
              End Function
              

              【讨论】:

                【解决方案7】:

                我使用的解决方案是;

                1. 将文件名从 .csv 更改为 .txt,然后再次尝试导入(但这听起来不合适
                2. 在您的 PC 上更改区域设置。如果您是英国人、澳大利亚人、新西兰人等,并且通常使用 dd/mm/yyyy,那么可能 Windows 安装不正确,因为美国日期格式等。
                3. 要么将其全部作为文本导入然后转换,要么编写一些代码来解析文件。无论哪种方式,您都需要确保获得正确的日期。这是通用日期格式和 CDATE() 可以帮助您的地方。

                下面的函数读取一个字符串并将其更改为 dd/mm/yyyy 日期。不过,您必须将单元格格式化为日期。请注意,如果您已经将值作为日期导入,这将无济于事。

                您可以在代码中使用它,也可以将其作为函数 (UDF) 使用(如果您将它通过到模块中)。

                Function TextToDate(txt As String) As Date
                
                  Dim uDate As String
                  Dim d, m, y As String
                  Dim aDate() As String
                
                  aDate = Split(txt, "/")
                  If UBound(aDate) <> 2 Then
                    Exit Function
                  End If
                
                  d = Lpad(aDate(0), "0", 2)
                  m = Lpad(aDate(1), "0", 2)
                  y = aDate(2)
                
                  If Len(y) = 2 Then ''# I'm just being lazy here.. you'll need to decide a rule for this.
                    y = "20" & y
                  End If
                
                  ''#  Universal Date format is : "yyyy-mm-dd hh:mm:ss" this ensure no confusion on dd/mm/yy vs mm/dd/yy
                  ''#  VBA should be able to always correctly deal with this
                
                   uDate = y & "-" & m & "-" & d & " 00:00:00"
                   TextToDate = CDate(uDate)
                End Function
                
                
                Function Lpad(myString As String, padString As String, padLength As Long) As String
                  Dim l As Long
                  l = Len(myString)
                  If l > padLength Then
                    padLength = l
                  End If
                
                  Lpad = Right$(String(padLength, padString) & myString, padLength)
                End Function
                

                【讨论】:

                • 区域设置设置为英语 (NZ),日期格式正确预期为 dd/mm/yyyy。感谢您的代码,但我在使用 OpenText 和获取作为文本导入的值(如 Q 中所列)时遇到了问题。此外,可以使用普通的 date(y,m,d) 函数,而不是创建一个字符串并进行转换。使用 OpenText 的 FieldInfo 参数有没有运气?
                • 不,对不起,我记得我用一个古怪的 .csv 撞到了墙上,它有不同的日期格式、尾随负数等......最后我只是用类似的东西编写了自己的解析器以上日期。它比 Workbooks.OpenText 慢,但只需要几个小时就可以编写并且运行速度足够快,可以每月导入。 YMMV
                【解决方案8】:

                这是代码...我的第一列是 DD/MM/YYYY 日期,第二列是文本... Array(1,4) 是关键...

                Workbooks.OpenText Filename:= _
                    "ttt.txt", Origin:=437, StartRow _
                    :=1, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _
                    ConsecutiveDelimiter:=False, Tab:=False, Semicolon:=False, Comma:=True _
                    , Space:=False, Other:=False, FieldInfo:=Array(Array(1, 4), Array(2, 1)), _
                    TrailingMinusNumbers:=True
                

                该值被识别为正确的日期...您需要将 DD/MM/YY 格式应用于此之后的第一列。

                【讨论】:

                  【解决方案9】:

                  我刚刚发现的是,您必须将本地日期分配给变量类型Date。我不明白它为什么有帮助,但确实有。

                  dim xDate As Date
                  
                  xDate = PresDate.Value    ' it is my form object let say it has 03/09/2013
                  
                  curRange.Value = xDate    ' curRange is my cur cell
                  

                  在将dd/mm/yyyy 转移到xDate 时,它仍然是dd/mm/yyyy,并且在将其放入excel 后不会改变它。为什么?我不知道。但经过多次尝试,它有所帮助。希望对很多人有帮助=)

                  【讨论】:

                    【解决方案10】:

                    试试这个:

                    Workbooks.OpenText Filename:=Filename, DataType:=xlDelimited, Comma:=True
                    

                    即使您喜欢不同的格式,Excel 也应该正确地将这些日期值解释为日期。执行 OpenText 方法后,确定哪一列包含日期值并更改格式以使其适合您:

                    CsvSheet.Columns(1).NumberFormat = "dd/mm/yyyy"
                    

                    【讨论】:

                    • > Excel 应该正确地将这些日期值解释为日期 是的,它应该,但不是。这就是重点。
                    • 嗯。你确定? excel 将它们解释为什么类型的值?你检查过,还是只是在做假设?
                    • 顺便说一句,您也可以轻松地将这些值复制到日期数组中,然后在按照您想要的方式格式化单元格后将它们粘贴回工作表中,无论数据类型如何Excel 最初将这些值解释为存在。三行代码,四顶。
                    • 是的,我确定。在问题中,我提供了示例代码和示例输入。我没有提供输出表,但解释了问题。这是您的代码的输出,使用英语 (NZ) 区域设置: Date 03/11/10 03/12/10 13/03/2010 14/03/2010 等问题不在于 excel formats 日期,但它如何解释它们并将它们从字符串转换为导入时的日期对象。
                    • 好吧,我在自己的 VBA 测试中使用了您的示例代码和示例输入,Excel 正确地将这些值视为日期。我想我一定做对了。祝你好运! :-)
                    猜你喜欢
                    • 2018-06-08
                    • 2016-11-06
                    • 2016-01-11
                    • 2015-12-26
                    • 1970-01-01
                    • 2023-02-22
                    • 2017-05-28
                    • 2022-11-17
                    • 1970-01-01
                    相关资源
                    最近更新 更多