【问题标题】:Insert Header row into multiple CSV files using VBA使用 VBA 将标题行插入多个 CSV 文件
【发布时间】:2020-07-02 11:35:05
【问题描述】:

我有一个宏,可以将一个巨大的 CSV 文件分成多个块,例如50,000 行,但只有第一个拆分文件包含标题。我需要修改代码以将标题包含在每个单独的文件中,或者在脚本末尾添加一段逻辑,它将遍历文件夹中的所有文件并添加标题记录(文件除外1).

这是当前脚本:

Sub SplitCSVFile()
'Splits a text or csv file into smaller files with a user defined number (max) of lines or rows. The new files get the original file name + a number (1, 2, 3 etc.).

Dim sFile As String  'Name of the original file
Dim sText As String  'The file text
Dim lStep As Long    'Max number of lines in the new files
Dim vX, vY           'Variant arrays. vX = input, vY = output
Dim iFile As Integer 'File number from Windows
Dim lCount As Long   'Counter
Dim lIncr As Long    'Number for file name
Dim lMax As Long     'Upper limit for loop
Dim lNb As Long      'Counter
Dim lSoFar As Long   'How far did we get?

On Error GoTo ErrorHandle

'Select a file
sFile = Application.GetOpenFilename()

'If the user cancelled
If sFile = "False" Then Exit Sub

'Ask the user for max number of lines per file.
lStep = Application.InputBox("Max number of lines/rows?", Type:=1)

'Arrays have zero as LBound, so we subtract 1
lStep = lStep - 1

'Read the file text to sText
sText = _
CreateObject("Scripting.FileSystemObject").OpenTextFile(sFile).ReadAll

'Put the text into the array vX. Carriage return–linefeed combination will add a new row to the array.
 vX = Split(sText, vbCrLf)

'Free memory
sText = ""

'Start a loop that will run until all rows in the array have been read and saved into new files. The variable lSoFar keeps track of how far we are in vX.
Do While lSoFar < UBound(vX)
   'If the number of rows minus lSoFar is bigger than max number of rows, the array vY is dimensioned to max number of rows.
   If UBound(vX) - lSoFar >= lStep Then
      ReDim vY(lStep)
      'lMax is set = last rownumber to be copied to vY.
      lMax = lStep + lSoFar
   Else
      'Else we dimension vY to the number of rows left.
      ReDim vY(UBound(vX) - lSoFar)
      'Last row to copy is last row in vX
      lMax = UBound(vX)
   End If

   lNb = 0
   'Now we copy the rows from vX to vY
   For lCount = lSoFar To lMax
      vY(lNb) = vX(lCount)
      lNb = lNb + 1
   Next

   'lSoFar keeps track of how far we got in vX
   lSoFar = lCount

   'Get a free file number
   iFile = FreeFile

   'Increment the number for the new file name
   lIncr = lIncr + 1

   'Save vY as a CSV file
   'Open sFile & "-" & lIncr & ".csv" For Output As #iFile
    Open Replace(sFile, ".csv", "") & "_" & lIncr & ".csv" For Output As #iFile
      'The Join function makes a text string from the array elements.
      Print #iFile, Join$(vY, vbCrLf)
   Close #iFile
Loop

Erase vX
Erase vY

Exit Sub
ErrorHandle:
MsgBox Err.Description & " Procedure SplitTextFile"
End Sub

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    只要换行

    Print #iFile, Join$(vY, vbCrLf)
    

    Print #iFile, IIf(lIncr = 0, "", vX(0) & vbCrLf) & Join$(vY, vbCrLf)
    

    【讨论】:

    • 完美!谢谢。我刚刚添加了一个 if 语句来不为第一个文件执行此操作,因为它已经有了标题。
    • @user2725402 你不需要任何额外的检查,条件已经在表达式IIf(lIncr = 0, "", vX(0) &amp; vbCrLf)中。
    【解决方案2】:

    在 Print 语句中使用 lIncr = 0 值将为您拆分的第一个 csv 生成一个辅助标头。

    由于在调用 Print 语句时 lIncr 值已经 = 1,并且标题是为初始 csv 打印的第一行,因此 IIF 检查失败并包含辅助标题 vX(0)。

    IIF 检查用于填充所需的每个附加 csv 的标头。

    正确的打印语句是……

    打印#iFile, IIf(lIncr = 1, "", vX(0) & vbCrLf) & Join$(vY, vbCrLf)

    【讨论】:

    • 如果 lIncr = 0,第一次拆分将打印 2 个标题。
    • 这是来自the accepted answer 的代码的精确副本,该代码是在将近三年前发布的。请在贡献自己的答案之前查看现有答案。如果您有不同的方法甚至更好的解释,即使已被接受,也可以提交另一个答案。但在这种情况下,您提供的是 same 指导和 less 解释。
    • @Jeremy...阅读评论并查看代码。产生正确结果的代码略有不同。
    • 啊哈,我的错。谢谢你说出来。虽然,当我们在这里时,这是一个很好的例子,说明为什么解释你的代码如此重要。请编辑您的帖子并从您的评论中添加解释,这样未来的读者就会很清楚。不要将解释作为评论留下。
    猜你喜欢
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2020-07-03
    • 2019-02-12
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多