【问题标题】:Date type data gets changed from “dd/mm” to “mm/dd” type while importing tab delimited text file to excel Through VBA通过 VBA 将制表符分隔的文本文件导入 Excel 时,日期类型数据从“dd/mm”更改为“mm/dd”类型
【发布时间】:2019-03-16 04:49:42
【问题描述】:

在浏览 SO 特色帖子 VBA, Date formatting issue 时,我认为不能简单地通过说格式问题来解决这个问题。在我的工作场所,我们在过去 12/13 年左右都面临着类似的问题。但是,我们使用了一些粗略的解决方法。但基本问题仍然完好无损。

由于我们正在处理的真实数据本质上是技术性的,无法泄露,并且包含超过 6000 行和 50 列。导入数据后的实际数据处理也包括页面 VBA 编码。我只用小的人为样本数据重现了这个问题。

手动导入制表符分隔的文本文件时,单列中的日期(也包括同一列中的数字空白和文本)以日期格式(“dd/MM/yyyy”)正常导入。手动操作时也录制了宏

但是当通过 VBA 执行相同的任务时。

  1. day 值大于 12 的日期显示为文本类型。

  2. 日期值小于 13 的日期显示为日期类型,但 01/04/2017(即 2017 年 4 月 1 日)更改为 04/0!/2017(即 2017 年 1 月 4 日)等等。

    Fname = "C:\Users\user\Desktop\SO Sample.TXT"
    
    Workbooks.OpenText Filename:=Fname, Origin:=xlMSDOS, _
        StartRow:=1, DataType:=xlDelimited, TextQualifier:=xlNone, _
        ConsecutiveDelimiter:=False, Tab:=True, Semicolon:=False, Comma:=False, _
        Space:=True, Other:=True, OtherChar:="*", FieldInfo:=Array(Array(1, 1), _
        Array(2, 1), Array(3, 1))
    

我的第一个问题是手动操作和 VBA 编码有什么区别

  1. 为了满意,用录制的宏替换编码并尝试
  2. VBA 宏已针对多个选项进行了测试,文件来源:=xlMSDOS、Xl Windows、437 等。
  3. 该特定部门的所有机器的区域设置仅采用相同的日期格式“dd/MM/yyyy”。
  4. 由于这是一个古老的过程,宏/VBA 代码仅在 Office 2007 和旧版本中试用。
  5. 通常所有格式都保持通用。

现在我们仍在为示例数据修改旧的解决方法

Sub Macro1()
Fname = "C:\Users\user\Desktop\SO Sample.TXT"

    Workbooks.OpenText Filename:=Fname, Origin:=xlMSDOS, _
        StartRow:=1, DataType:=xlDelimited, TextQualifier:=xlNone, _
        ConsecutiveDelimiter:=False, Tab:=True, Semicolon:=False, Comma:=False, _
        Space:=True, Other:=True, OtherChar:="*", FieldInfo:=Array(Array(1, 1), _
        Array(2, 1), Array(3, 1))

    SrcName = ActiveWorkbook.Name
    Range("A1:C40").Select
    Selection.Copy
    Windows(ThisWorkbook.Name).Activate
    Sheet1.Range("A5").Select
    ActiveSheet.Paste
    Windows(SrcName).Activate
    Range("A1:A1").Select
    Selection.Copy                     ' To release vast clipboard date
    ActiveWorkbook.Close False
    ThisWorkbook.Activate


 For X = 5 To 40
 Xdate = Cells(X, 2).Text
 Cells(X, 5).Value = Xdate
 Ydate = Cells(X, 5).Value
    If IsDate(Xdate) And IsDate(Ydate) Then
    Zdate = CDate(Ydate)
    'If DateDiff("d", Ydate, #1/1/1900#) > 0 Then Zdate = ""     'to filter out numeric data interpreted as date/time
    Else
    Zdate = ""
    End If
 Cells(X, 6).Value = Zdate
 Next

'Next are the sections of processing the data beased on the non empty date values found in column 6.
End Sub

这里当 Cells(X, 2).Text 被放入 Cells(X, 5) 时

  1. 出现的日期值大于 12 的日期在第 5 列中仍然是文本类型。

  2. 日期值小于 13 的日期显示为日期类型,但 01/04/2017(即 2017 年 4 月 1 日)已更改为 04/0!/2017(即 2017 年 1 月 4 日)在 Col 2 中再次更改为 Col 5 中的 01/04/2017(即 2017 年 4 月 1 日)

现在我的第二个问题是,当我们将 Cells(X, 2).Text 放入 Cells(X, 5) 时会发生什么?

这完全是出于学术兴趣,我换了部门,人们对旧工作很满意,没有人愿意修补古老的代码。但我的直觉是,解决方案必须是一个非常简单的单行调整,让我们说出“哦,我们怎么能错过这个愚蠢的事情多年”。

Edit2:进一步的小实验是关于 Cells.text 如何使用各种日期和区域设置(“DMY”和“MDY”)。在 Excel 文件中输入了几个示例日期,并执行了一个简单的循环以将 B 列单元格文本放入 D 列。
我得出的结论是 无论区域设置如何,VBA Cells.Text 都将日期解释为以美国格式 (mdy) 显示的日期。当将相同的内容放在另一个单元格上时(如果区域设置为“DMY”并且月份和日期可能可以互换,即日期

【问题讨论】:

  • VBA 采用美国区域设置。如果您的设置使用 dd/mm 格式,请将 Local:=True 添加到 Opentext 命令。
  • @Rory 谢谢。检查。 - 像魔术一样工作。现在我会去露台大喊“哦,我们怎么能错过这个愚蠢的事情多年”。你能给我关于我问题的第二部分的线索吗?。
  • @Rory 请把它作为答案,这样至少我可以接受它,它让我从十年前的调查中解放出来。

标签: excel vba date datetime


【解决方案1】:

VBA 采用美国区域设置。如果您的设置使用dd/mm 格式,请将Local:=True 添加到Opentext 命令中。

关于第二部分,在单元格中输入XDate 时忘记使用CDate

【讨论】:

  • 我故意不使用 Cdate(Xdate),因为它仅将 04/0!/2017 (即 2017 年 1 月 4 日)从第 2 列复制到第 5 列。(即使刚才我检查了它用“if Isdate ... Then”包装它,因为 col2 包含其他数据类型并抛出变量类型错误)。但是 不知何故 Cells(X,5).value= cells(X,2).Text 可以解决问题并将 Col 2 中的 04/0!/2017(即 2017 年 1 月 4 日)转换为 01/04/2017 (即 2017 年 4 月 1 日)在 Col 5。 我仍然无法理解其背后的逻辑。它在一些试验和错误中有效,并且仍然有效多年。
  • 我根据您的想法编辑了帖子,并添加了更多发现。请看一下。
猜你喜欢
  • 1970-01-01
  • 2022-11-19
  • 2018-01-07
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 2016-03-13
相关资源
最近更新 更多