我想格式化我的 csv 文件,从 excel 导出
I want to format my csv file, from an excel export
我对新导出的 csv 文件中的日期格式有疑问。
如果我从 excel 文件导出一个范围,那么日期格式是 dd/mm/yyyy 但我需要 dd/mm/yyyy hh:nn.
如果我将原始 excel 文件中的格式更改为正确的格式,则 csv 中的大多数值都会显示正确的格式,但日期值除外,例如18.08.2021 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 是金额(双倍)
Excel 格式化数字真的很糟糕,因为内部系统将存储值和显示值分开保存。所以你看到的不是你保存时文件中的内容。为了强制 excel 将格式实际应用于存储值,我使用引号将数字和日期转换为字符串。就像 [A1].formula = "=""" & [A1].Value & """"
一样,它会将包含数字 100.00 的单元格转换为 ="100.00"
无法重新格式化的文字字符串 excel。
对于你的日期格式情况,你可以[A1].formula = "=""" & Format([A1].Value, "dd/mm/yyyy hh:nn") & """"
。这将强制 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个字符。在那些情况下,它只需要拆分成多个字符串,但输出值仍然相同。
由于您已经在手动编写 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
-分支中,写
FormatCellValue = """" & v & """"
并将调用更改为
line = line & FormatCellValue(arr(r, c))
我对新导出的 csv 文件中的日期格式有疑问。 如果我从 excel 文件导出一个范围,那么日期格式是 dd/mm/yyyy 但我需要 dd/mm/yyyy hh:nn.
如果我将原始 excel 文件中的格式更改为正确的格式,则 csv 中的大多数值都会显示正确的格式,但日期值除外,例如18.08.2021 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 是金额(双倍)
Excel 格式化数字真的很糟糕,因为内部系统将存储值和显示值分开保存。所以你看到的不是你保存时文件中的内容。为了强制 excel 将格式实际应用于存储值,我使用引号将数字和日期转换为字符串。就像 [A1].formula = "=""" & [A1].Value & """"
一样,它会将包含数字 100.00 的单元格转换为 ="100.00"
无法重新格式化的文字字符串 excel。
对于你的日期格式情况,你可以[A1].formula = "=""" & Format([A1].Value, "dd/mm/yyyy hh:nn") & """"
。这将强制 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个字符。在那些情况下,它只需要拆分成多个字符串,但输出值仍然相同。
由于您已经在手动编写 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
-分支中,写
FormatCellValue = """" & v & """"
并将调用更改为
line = line & FormatCellValue(arr(r, c))