【问题标题】:Convert an Entire Column in Unix Epoch Time into Excel Date (YYYY-MM-DD) form VBA将 Unix 纪元时间中的整列转换为 Excel 日期 (YYYY-MM-DD) 形式的 VBA
【发布时间】:2017-09-20 17:01:31
【问题描述】:

我有一个具有 Unix 纪元时间的 CSV。虽然有使用公式将纪元时间转换为日期格式的示例,但我找不到任何将纪元时间的整列(大小可能不同)转换为yyyy-mm-dd 形式的 VBA 示例。我想在宏中做的是

Sub FormatTimeStamp()  
    Dim tbl As ListObject
    Dim sht As Worksheet

    For Each sht In ThisWorkbook.Worksheets
        For Each tbl In sht.ListObjects
            For Each dateCol In tbl.ListColumns
                If InStr(dateCol.Name, "timestamp") > 0 Then
                    dateCol.DataBodyRange.NumberFormat = "yyyy-mm-dd"
                End If
            Next dateCol
        Next tbl
    Next sht 
End Sub
  1. 获取工作簿中所有工作表的列表(活动工作表除外)
  2. 在每个工作表中,读取具有 Epoch Times 的列名(我可以参考 VBA 中的列名吗?)
  3. 使用YYYY-MM-DD 表单在其旁边创建一个新列(如何在纪元时间的左侧创建一个新列名)
  4. 对于 Epoch 时间中的每个项目,在其自己的列中创建等效的 YYYY-MM-DD 表单

【问题讨论】:

  • 使用left\mid函数见例子stackoverflow.com/a/34741424/4539709
  • 我查看了您分享的示例,但它没有从 yyyy-mm-dd 转换的纪元时间,而是从 yyyymmdd 到 yyyy/mm/dd 的转换。谢谢你的例子
  • 我不相信你可以只用数字格式进行转换——现在的纪元时间大约是 1493016379,而 Excel 原始版本是 42849.69869。您必须对每个单元格进行某种计算并覆盖纪元时间值。这是您的预期吗?
  • 是的,罗宾,我有几个工作表,其中有一个名为“时间戳”的列。此列时间戳中有纪元时间。我需要将纪元时间转换为 yyyy-mm-dd 并覆盖纪元时间,或者为纪元时间旁边的 yyyy-mm-dd 创建一个新列。我尝试使用数字格式设置它,但运行宏时没有任何反应
  • 在B1 公式=(A1/86400)+25569 上尝试这个公式公式,假设A1 有纪元时间,然后将单元格格式设置为NumberFormat = "yyyy-mm-dd"

标签: excel vba date datetime epoch


【解决方案1】:

您可以尝试几种方法 - 第一种方法需要一个新列并插入公式以将纪元时间转换为 Excel 日期,然后应用格式来获​​取“yyyy-mm-dd”。这种方式非常简单 - 最初我使用 TEXT 函数转换新日期,但如果您想应用 NumberFormat 代替,那么这就是我将其留在下方未注释的方式。

第二种方法从Range 到Variant 读取纪元时间列,然后在将转换后的数据写回工作表之前对变量数组进行计算。使用第二种方法,您可以使用它来获得新的数据列或覆盖原始纪元时间数据。

您必须使用ListObjects 等根据您的情况调整以下代码,但原理是相同的:

Option Explicit

Sub Method1()

    Dim rngEpochTimeData As Range

    ' get times
    Set rngEpochTimeData = ThisWorkbook.Worksheets("Sheet1").Range("A2:A11")

    ' set range offset by 1 column with converting formula with RC notation
    ' set as text
    'rngEpochTimeData.Offset(0, 1).FormulaR1C1 = "=TEXT((RC[-1]/86400)+DATE(1970,1,1),""yyyy-mm-dd"")"

    ' set as date and also set number format
    With rngEpochTimeData.Offset(0, 1)
        .FormulaR1C1 = "=(RC[-1]/86400)+DATE(1970,1,1)"
        .NumberFormat = "yyyy-mm-dd"
    End With

End Sub

Sub Method2()

    Dim rngEpochTimeData As Range
    Dim varTimeData As Variant
    Dim lngCounter As Long
    Dim lngEpochTime As Long

    ' get times
    Set rngEpochTimeData = ThisWorkbook.Worksheets("Sheet1").Range("A2:A11")

    ' set range data to array
    varTimeData = rngEpochTimeData.Value

    ' iterate array and do conversion
    For lngCounter = LBound(varTimeData, 1) To UBound(varTimeData, 1)
        lngEpochTime = varTimeData(lngCounter, 1)
        varTimeData(lngCounter, 1) = CDate((lngEpochTime / 86400) + 25569)
    Next lngCounter

    ' write to range
    With rngEpochTimeData.Offset(0, 2)
        .Value = varTimeData
        .NumberFormat = "yyyy-mm-dd"
    End With

End Sub

输入输出示例:

【讨论】:

  • 罗宾,完美..我现在有两个选择可供选择..太棒了。
【解决方案2】:

您只需要对代码进行微小的更改。请参阅代码 cmets 中的解释。

Option Explicit 'see http://stackoverflow.com/documentation/excel-vba/1107/vba-best-practices

Sub FormatTimeStamp()
    Dim tbl As ListObject
    Dim sht As Worksheet
    Dim newCol As Long

    For Each sht In ThisWorkbook.Worksheets
        For Each tbl In sht.ListObjects
            newCol = tbl.ListColumns("timestamp").Range.Column - tbl.ListColumns(1).Range.Column + 1
              'calculate the position of timestamp column whithin the table
              'note: .Column returns the column number relative to the sheet but we need
              '      the column number relative to the table! Therefore we subtract the
              '      column number of the first column of the table and add 1 to
              '      obtain the position of the column relative to the table.

            tbl.ListColumns.Add Position:=newCol
              'add a new column before the timestamp column

            tbl.HeaderRowRange(newCol).Value = "date from timestamp"
              'add a header name for the new column (optional)

            tbl.DataBodyRange(1, newCol).Formula = "=([timestamp]/86400)+DATE(1970,1,1)"
              'calculate the date from the timestamp with a formula
              'note: we only need to fill the first row of a column
              '      the formula gets copied down automatically by Excel
              '      this works only within tables.
              '      In a normal sheet range we would need to loop throug all rows,
              '      to fill in the formula in each cell of the entire column.

            tbl.ListColumns(newCol).DataBodyRange.NumberFormat = "yyyy-mm-dd"
              'change the cell format of the data range to international date format
        Next tbl
    Next sht
End Sub

欲了解更多信息,请参阅The VBA Guide To ListObject Excel Tables。


替代方案: 如果您希望空时间戳也成为空日期,请改用此公式。

=IF([timestamp]<>"",([timestamp]/86400)+DATE(1970,1,1),"")

【讨论】:

  • 超级有用的 Peh!非常感谢您提供的细节也可以帮助其他人。
猜你喜欢
  • 2016-06-09
  • 2014-06-22
  • 2016-11-06
  • 2019-01-16
  • 2023-03-15
  • 2013-10-19
  • 2018-08-24
  • 2022-11-12
  • 2023-02-22
相关资源
最近更新 更多