【问题标题】:How to get rid of unwanted commas at end of string in CSV file如何去掉 CSV 文件中字符串末尾不需要的逗号
【发布时间】:2021-06-03 17:35:23
【问题描述】:

我编写了以下代码,目的是将两个范围保存到 CSV 文件中:

Sub Export_range_to_CSV()
    Dim myCSVFileName As String
    Dim myWB As Workbook
    Dim tempWB As Workbook
    Dim range1 As Range
    Dim range2 As Range
    Set range1 = Sheets("sheet1").Range("G2:G4")
    Set range2 = Sheets("sheet1").Range("G5:H53")

    Application.DisplayAlerts = False
    On Error GoTo err

    Set myWB = ThisWorkbook
    myCSVFileName = "filepath" & "\" & "name" & VBA.Format(VBA.Now, "yyyymmdd_hhmm") & ".csv"
    
    range1.Copy

    Set tempWB = Application.Workbooks.Add(1)
    With tempWB
        .Sheets(1).Range("A1").PasteSpecial xlPasteValues
        range2.Copy
        .Sheets(1).Range("A4").PasteSpecial xlPasteValues
        .SaveAs Filename:=myCSVFileName, FileFormat:=xlCSV, CreateBackup:=False
        .Close
    End With
err:
    Application.DisplayAlerts = True
End Sub

上面的代码完成了这项工作,但对于range1,它在保存为 CSV 时在字符串末尾有逗号。我需要删除这些才能使下游的工作正常工作。如何去掉range1末尾的逗号?

这是保存为 CSV 文件后的样子:

范围1

- # X=Y, <- need to remove these commas
- # Z=U,
- # M=Q,

范围2

- datetime,quantity
- 2021-03-05 23:00:00+00:00,17
- 2021-03-05 23:30:00+00:00,17
- 2021-03-06 00:00:00+00:00,17
- 2021-03-06 00:30:00+00:00,17

我认为问题出在 range1 只有一列,一旦 range2 发挥作用,它假定 range1 也应该是两列。

【问题讨论】:

    标签: excel vba export-to-csv


    【解决方案1】:

    最后一列是通过检查两个范围的最后一列来计算的。以较高者为准。让我解释一下。

    假设数据直到 J 列

    Set range1 = Sheets("sheet1").Range("G2:G4")
    Set range2 = Sheets("sheet1").Range("G5:J53")
    

    那么在这个场景中,将添加 3 个逗号。同样,如果range2 中的最后一列是 K,range1 中的最后一列是 H,那么将在第一个范围内添加 3 个逗号。

    反转范围时也是如此

    Set range1 = Sheets("sheet1").Range("G5:J53")
    Set range2 = Sheets("sheet1").Range("G2:G4")
    

    现在第二个范围将有额外的逗号

    解决方案

    读取数组中的数据,然后删除最后一个逗号。所以一旦你的 Csv 文件被写入,将文件传递给这个过程,它会处理剩下的事情

    以下代码一次性读取数组中的 csv,然后检查每一行是否在右侧有 ,。如果有,则将其删除。最后,它通过将数组一次性放入文本文件来删除旧的 csv 并写入新文件。我已经对代码进行了注释,因此您理解它应该没有问题。但如果你这样做了,那就问吧。

    '~~> Example usage
    Sub Sample()
        CleanCsv "C:\Users\Siddharth Rout\Desktop\aaa.txt"
    End Sub
    
    '~~> Cleans csv
    Sub CleanCsv(fl As String)
        Dim MyData As String, strData() As String
        Dim i As Long
        
        '~~> Read the file in one go into an array
        Open fl For Binary As #1
        MyData = Space$(LOF(1))
        Get #1, , MyData
        Close #1
        strData() = Split(MyData, vbCrLf)
        
        '~~> Check for "," and remove
        For i = LBound(strData) To UBound(strData)
            If Right(strData(i), 1) = "," Then
                Do While Right(strData(i), 1) = ","
                    strData(i) = Left(strData(i), Len(strData(i)) - 1)
                Loop
            End If
        Next i
        
        '~~> Kill old file
        Kill fl
        
        '~~> Output the array in one go into a text file
        Dim ff As Long
        ff = FreeFile
        Open fl For Binary As #ff
        
        Put #ff, , Join(strData, vbCrLf)
        
        Close #ff
    End Sub
    

    【讨论】:

      【解决方案2】:

      删除尾随逗号

      • 您运行exportRangesToCSV,而removeTrailingCommaInTextFile 在接近尾声时被调用,removeTrailingCommaremoveTrailingCommaInTextFile 调用。
      • 我对其进行了测试,它可以工作,但请记住,我对操作文本文件(第二个过程)知之甚少,这或多或少是我编写的第一个正则表达式(第三个过程)。我花了“年龄”来写它们(不是抱怨)。第一个程序是我“在家”。
      • 请注意第二个过程中的经典错误处理例程示例(您的做法是不可接受的:您缺少Resume 部分)。您可以轻松地将其应用于第一个过程。
      • 不要忘记调整常量部分中的值。

      守则

      Option Explicit
      
      Sub exportRangesToCSV()
          
          Const sName As String = "Sheet1"
          Const sAddr As String = "G2:G4,G5:H53"
          
          Const dFolderPath As String = "C:\Test"
          Const dLeftBaseName As String = "Name"
          Const dTimeFormat As String = "yyyymmdd_hhmm"
          Const dFileExtension As String = ".csv"
          Const dAddr As String = "A1"
          
          Dim wb As Workbook: Set wb = ThisWorkbook
          Dim rg As Range: Set rg = wb.Worksheets(sName).Range(sAddr)
          
          Dim dFilePath As String
          dFilePath = dFolderPath & "\" & dLeftBaseName _
              & VBA.Format(VBA.Now, dTimeFormat) & dFileExtension
          
          Application.ScreenUpdating = False
          With Workbooks.Add()
              Dim dCell As Range: Set dCell = .Worksheets(1).Range(dAddr)
              Dim srg As Range
              For Each srg In rg.Areas
                  dCell.Resize(srg.Rows.Count, srg.Columns.Count).Value = srg.Value
                  Set dCell = dCell.Offset(srg.Rows.Count)
              Next srg
              Application.DisplayAlerts = False
              .SaveAs dFilePath, xlCSV
              Application.DisplayAlerts = True
              .Close False
          End With
          Application.ScreenUpdating = True
          
          removeTrailingCommaInTextFile dFilePath, True
          
          'wb.FollowHyperlink dFolderPath
      
      End Sub
      
      Sub removeTrailingCommaInTextFile( _
              ByVal FilePath As String, _
              Optional ByVal removeAllOccurrences As Boolean = False)
          Const ProcName As String = "removeTrailingCommaInTextFile"
          On Error GoTo clearError
      
          Dim TextFile As Long: TextFile = FreeFile
          Dim TempString As String
          Open FilePath For Input As TextFile
          TempString = Input(LOF(TextFile), TextFile)
          Close TextFile
          Open FilePath For Output As TextFile
          Print #TextFile, removeTrailingComma(TempString, removeAllOccurrences)
          Close TextFile
      
      ProcExit:
          Exit Sub
      clearError:
          Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
                    & "    " & "Run-time error '" & err.Number & "':" & vbLf _
                    & "        " & err.Description
          Resume ProcExit
      End Sub
      
      Function removeTrailingComma( _
          ByVal SearchString As String, _
          Optional ByVal removeAllOccurrences As Boolean = False) _
      As String
          With CreateObject("VBScript.RegExp")
              .Global = True
              .MultiLine = True
              If removeAllOccurrences Then
                  .Pattern = ",+$"
              Else
                  .Pattern = ",$"
              End If
              removeTrailingComma = .Replace(SearchString, "")
          End With
      End Function
      

      编辑

      • 此解决方案将直接写入文本文件而不导出。如果单元格太多,它可能会变慢。

      数组

      Sub exportRangesToCSVArrays()
          
          Const sName As String = "Sheet1"
          Const sAddr As String = "G2:G4,G5:H53"
          
          Const dFolderPath As String = "C:\Test"
          Const dLeftBaseName As String = "Name"
          Const dTimeFormat As String = "yyyymmdd_hhmm"
          Const dFileExtension As String = ".csv"
          Const dAddr As String = "A1"
          Const Delimiter As String = ","
          
          Dim wb As Workbook: Set wb = ThisWorkbook
          Dim rg As Range: Set rg = wb.Worksheets(sName).Range(sAddr)
          
          Dim aCount As Long: aCount = rg.Areas.Count
          Dim Data As Variant: ReDim Data(1 To aCount)
          Dim rData() As Long: ReDim rData(1 To aCount)
          Dim cData() As Long: ReDim cData(1 To aCount)
          Dim OneCell As Variant: ReDim OneCell(1 To 1, 1 To 1)
          Dim srg As Range
          Dim srCount As Long, scCount As Long
          Dim drCount As Long, dcCount As Long
          Dim n As Long
          
          For Each srg In rg.Areas
              n = n + 1
              srCount = srg.Rows.Count: scCount = srg.Columns.Count
              rData(n) = srCount: cData(n) = scCount
              If srCount > 1 Or scCount > 1 Then
                  Data(n) = srg.Value
              Else
                  Data(n) = OneCell: Data(1, 1) = srg.Value
              End If
              drCount = drCount + srCount
              If scCount > dcCount Then
                  dcCount = scCount
              End If
          Next srg
          
          Dim Result() As String: ReDim Result(1 To drCount)
          Dim r As Long, i As Long, j As Long
          For n = 1 To aCount
              For i = 1 To rData(n)
                  r = r + 1
                  For j = 1 To cData(n)
                      Result(r) = Result(r) & CStr(Data(n)(i, j)) & Delimiter
                  Next j
                  Result(r) = removeTrailingComma(Result(r), True)
              Next i
          Next n
          
          Dim dFilePath As String
          dFilePath = dFolderPath & "\" & dLeftBaseName _
              & VBA.Format(VBA.Now, dTimeFormat) & dFileExtension
          
          Dim TextFile As Long: TextFile = FreeFile
          Dim TempString As String
          Open dFilePath For Output As TextFile
          Print #TextFile, Join(Result, vbLf)
          Close TextFile
      
          'wb.FollowHyperlink dFolderPath
      
      End Sub
      

      【讨论】:

      • 我尝试了“代码”部分下的代码,它对我有用。只是为可能有类似问题的人说明它,以便他们知道哪个特定部分解决了我的问题。干杯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      相关资源
      最近更新 更多