2017-04-24 2 views
1

Ich habe eine CSV, die Unix Epoch Times hat. Es gibt zwar Beispiele für das Konvertieren von Epochenzeiten in Datumsformate mit Formeln, aber ich konnte kein VBA-Beispiel finden, das eine ganze Spalte (Größe kann variieren) von Epochenzeiten in eine yyyy-mm-dd Form umwandelt. Was ich versuche, in dem Makro zu tun ist,Konvertieren Sie eine ganze Spalte in Unix Epoch Time in Excel Datum (JJJJ-MM-TT) Formular 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. eine Liste aller Blätter in der Arbeitsmappe erhalten (ausgenommen dem aktiven Blatt)
  2. In jedem Blatt, Lesen Sie die Spaltennamen, die Epoch Times hat (kann ich auf einen Spaltennamen in VBA verweisen?)
  3. eine neue Spalte es erstellen neben mit YYYY-MM-DD Form (Wie kann ich einen neuen Spaltennamen auf der linken Seite der Epoche Zeit) schaffen
  4. Für jedes Element in Epoch Zeit, erstellen Sie die YYYY-MM-DD Formular entspricht in einer eigenen Spalte
+0

Verwendung links \ mid Funktionen Beispiele siehe http://stackoverflow.com/a/34741424/4539709 – 0m3r

+0

ich am Beispiel sah Sie geteilt, aber es hat nicht die Epoche Zeit yyyy-mm-dd Umwandlung Es hat die Konvertierung von JJJJMMTT nach JJJJ/MM/TT. Danke für das Beispiel obwohl –

+0

Ich glaube nicht, dass Sie nur mit einem Zahlenformat konvertieren können - Epochenzeit ist jetzt ungefähr 1493016379 und Excel-Rohversion ist 42849,69869. Sie müssen eine Art von Berechnung pro Zelle durchführen und den Epochenzeitwert überschreiben. Hast du das erwartet? –

Antwort

1

Sie können ein paar Methoden ausprobieren - die erste Methode benötigt eine neue Spalte und fügt die Formel ein, um die Epochzeit in ein Excel-Datum umzuwandeln, und wendet dann ein Format an, um 'JJJJ-MM-TT' zu erhalten. Dieser Weg ist ziemlich einfach - ursprünglich konvertierte ich das neue Datum mit TEXT Funktion, aber wenn Sie NumberFormat stattdessen anwenden möchten, dann ist das die Art, wie ich es unten un-kommentiert verließ.

Die zweite Methode liest die Spalte der Epochenzeiten von einer Range zu einer Variant und führt dann die Berechnung auf dem varianten Array vor dem Schreiben der konvertierten Daten zurück in das Blatt. Mit der zweiten Methode können Sie entweder eine neue Datenspalte oder verwenden, um die ursprünglichen Epochendaten zu überschreiben.

Sie müssten Sie den Code unten zu Ihren persönlichen Umständen mit ListObjects usw. anzupassen, aber das Prinzip wäre das gleiche:

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 

Beispiel Ein- und Ausgang:

enter image description here

+0

Robin, Perfekt .. Ich habe jetzt zwei Möglichkeiten zur Auswahl ... Super. –

1

Sie benötigen nur geringfügige Änderungen in Ihrem Code. Siehe die Erläuterungen in den Code-Kommentaren.

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 

Für weitere Informationen siehe The VBA Guide To ListObject Excel Tables.


Alternative: Wenn Sie leer Zeitstempel wollen auch ein leeres Datum sein, dann diese Formel stattdessen verwenden.

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

Super hilfreich Peh! Vielen Dank für die Details, die auch anderen helfen können. –