【问题标题】:I want to format my csv file, from an excel export我想从 excel 导出格式化我的 csv 文件
【发布时间】:2021-10-14 01:30:56
【问题描述】:

我对新导出的 csv 文件中的日期格式有疑问。 如果我从 excel 文件中导出一个范围,那么日期格式是 dd/mm/yyyy 但我需要 dd/mm/yyyy hh:nn。

如果我将原始 excel 文件中的格式更改为正确的格式,那么 csv 中的大多数值都会显示正确的格式,但日期值除外,例如2021 年 8 月 18 日 00:00。

所以如果时间是 00:00,那么只有 dd/mm/yyyy 格式出现在该行,并且这种格式与数据库不兼容。

(我在excel和编辑器中打开它,它出现了同样的问题)

有人可以帮我吗?

    Dim ws As Worksheet, fd As FileDialog, rngTest As Range, rngExport As Range, fltr As FileDialogFilter
    Dim start As Long
    start = 2
    
    
    'Nach jeweiliger Zeit wird Datenreihe (start ab) ausgewählt
    If Time < TimeValue("11:15") Then
        Do Until Daten.Range("ov" & start) = Date + 1
        start = start + 1
        Loop
    ElseIf Time < TimeValue("11:15") Then
        Do Until Daten.Range("ov" & start) = Date + 2
        start = start + 1
        Loop
    Else: start = 2
    End If
    
    
    
   start = start + 1

    'Worksheet auf dem die Daten stehen
    Set ws = Worksheets("Daten")
     
    
    'Zelle die auf Inhalt überprüft werden soll
    Set rngTest = ws.Range("ov2")
    'Bereich der exportiert wird
    Set rngExport = ws.Range("ov" & start & ":ow10000")
'    ws.Range("ov" & start & ":ov5000").NumberFormat = "dd/mm/yyyy hh:mm"
    If rngTest.Text <> "" Then
        Set fd = Application.FileDialog(msoFileDialogSaveAs)
        'Filename
        fd.InitialFileName = "LG" & " " & Diagramm.Range("a5").Value & " " & "RZ" & " " & Format(Date, "mmmm") & " " & Format(Date, "yyyy") & "_" & "MW" & "_" & "ab" & " " & Daten.Range("ov" & start - 1).Value
       ' Application.Dialogs(xlDialogSaveAs).Show filenameComplete
        With fd
            .Title = ""
            'Filterindex für CSV-Dateien ermitteln
            For i = 1 To .Filters.count
                If .Filters(i).Extensions = "*.csv" Then
                    .FilterIndex = i
                    Exit For
                End If
            Next
            'Wenn OK geklickt wurde starte Export
            If .Show = True Then
                ExportRangeAsCSV rngExport, ";", .SelectedItems(1)
                
            End If
        End With
    End If
End Sub

'Hier werden die Werte in eine CSV-Datei eingefügt und gespeichert
Sub ExportRangeAsCSV(ByVal rng As Range, delim As String, filepath As String)
    Dim arr As Variant, line As String, csvContent As String, fso As Object, csvFile As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set csvFile = fso.OpenTextFile(filepath, 2, True)
    
    arr = rng.Value 'Filter
    If IsArray(arr) Then
    
            ' um die Überschrift im CSV oben einzufügen
        Dim col As Range
        For Each col In rng.Columns
           If Len(line) > 0 Then line = line & delim
           line = line & """" & rng.Parent.Cells(1, col.column) & """"
        Next
        csvContent = line & vbNewLine
    
    
            'um die Werte ins CSV einzufügen
        For r = 1 To UBound(arr, 1)
            line = ""
            For c = 1 To UBound(arr, 2)
                If c < UBound(arr, 2) Then
                    line = line & """" & arr(r, c) & """" & delim
                Else
                    line = line & """" & arr(r, c) & """"
                End If
            Next
          
            csvContent = csvContent & line & vbNewLine
           
        Next
        
        csvFile.Write (csvContent)
        csvFile.Close
    Else
        MsgBox "Bereich besteht nur aus einer Zelle!", vbExclamation
    End If
    Set fso = Nothing
    Set csvFile = Nothing
End Sub

Range("ov").value 是日期, Range("ow").value 是金额(双精度)

【问题讨论】:

  • 不是 VBA,但也许你可以试试这个 Notepad++ 插件,它可以重新格式化日期时间值github.com/BdR76/CSVLint

标签: excel vba csv format export


【解决方案1】:

Excel 在格式化数字方面确实很烂,因为内部系统将存储值和显示值分开保存。因此,您所看到的并不是保存时最终会出现在文件中的内容。为了强制 excel 将格式实际应用于存储的值,我使用引号将数字和日期转换为字符串。就像[A1].formula = "=""" &amp; [A1].Value &amp; """" 一样,它将包含数字 100.00 的单元格转换为 ="100.00" 一个 Excel 无法重新格式化的文字字符串。

对于您的日期格式情况,您可以使用[A1].formula = "=""" &amp; Format([A1].Value, "dd/mm/yyyy hh:nn") &amp; """"。这将强制 excel 以指定格式保存单元格值并确保输出 csv 为该格式。

这是我之前用来将二维值数组更改为上述公式数组的函数。

Private Function ForceString(ByRef InputArr As Variant) As Variant
    Dim OutputArr() As Variant
    OutputArr = InputArr
    Dim i As Long, j As Long
    For i = LBound(OutputArr) To UBound(OutputArr)
        For j = LBound(OutputArr, 2) To UBound(OutputArr, 2)
            If Len(OutputArr(i, j)) < 255 Then
                OutputArr(i, j) = "=""" & OutputArr(i, j) & """"
            Else
                Dim k As Long, Tmp As String
                Tmp = "="
                For k = 1 To Len(OutputArr(i, j)) Step 255
                    Tmp = Tmp & IIf(k <> 1, "&", "") & """" & Mid(OutputArr(i, j), 1, 255) & """"
                Next k
                OutputArr(i, j) = Tmp
            End If
        Next j
    Next i
    ForceString = OutputArr
End Function

中间的 If/Else 是由于 Excel 中限制公式中的文字字符串不允许超过 255 个字符。在这些情况下,只需将其拆分为多个字符串,但输出值仍然相同。

【讨论】:

  • 幸运的是,Excel 将数字和格式分开存储。如果将日期存储为字符串“08/10/2021”(因为它写在 CSV 文件中),那么世界上每个人都需要使用极其奇怪的美国日期格式。
  • @FunThomas 你说幸运,我说不幸。 :P
【解决方案2】:

由于您已经在手动编写 CSV 文件,我建议引入一个将单元格内容转换为字符串的函数。您可以将此例程用于多种用途,例如格式化数字(小数、位数...)、删除字符串中不需要的字符(例如换行符、分号、引号字符)...

只是给你一个想法:

Function FormatCellValue(v As Variant) As String
    If IsDate(v) Then
        FormatCellValue = Format(v, "dd.mm.yyyy hh:mm")
    ElseIf VarType(v) = vbDecimal Then
        FormatCellValue = Format(v, "#####.00")
    ElseIf VarType(v) = vbString Then
        v = Replace(v, vbCr, " ")
        v = Replace(v, vbLf, " ")
        v = Replace(v, ";", ",")
        v = Replace(v, """", "'")
        FormatCellValue = v
    Else
        FormatCellValue = v
    End If
End Function

在您现有的代码中,只需编写

line = line & """" & FormatCellValue(arr(r, c)) & """"

更新 如果你只想写带引号和日期(和数字)的字符串,你可以在 FormatCell 函数中添加引号:在Vartype = vbString-branch 中,写

 FormatCellValue = """" & v & """" 

并将调用更改为

 line = line & FormatCellValue(arr(r, c)) 

【讨论】:

  • 我认为我们可以通过将我的行 OutputArr(i, j) = "=""" &amp; OutputArr(i, j) &amp; """" 更改为 OutputArr(i, j) = "=""" &amp; FormatCellValue(OutputArr(i, j)) &amp; """" 将您和我的答案结合在一起。这将是一种将 csv 特定格式包含到我的数组字符串化函数中的天才方式。
  • @Toddleson:老实说,我不明白先将要导出的内容写入公式的想法。进入 VBA 后,无需返回 Excel。
  • 我平时的工作流程是把VBA放在workbook打开,让用户调整,然后手动保存。我想你是对的,如果你在关闭状态下运行 VBA,那么我的建议毫无意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 2012-03-18
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
相关资源
最近更新 更多