Excel:宏将工作表导出为CSV文件而不离开当前的Excel工作表

时间:2016-05-04 21:01:08

标签: excel vba excel-vba csv export-to-csv

这里有很多问题需要创建一个宏来将工作表保存为CSV文件。所有答案都使用SaveAs,例如来自SuperUser的this one。他们基本上说要创建一个像这样的VBA函数:

Sub SaveAsCSV()
    ActiveWorkbook.SaveAs FileFormat:=clCSV, CreateBackup:=False
End Sub

这是一个很好的答案,但我想做一个导出而不是另存为。当SaveAs被执行时,它会引起我两个烦恼:

  • 我当前的工作文件变为CSV文件。我想继续使用我原来的.xlsm文件,但要将当前工作表的内容导出为同名的CSV文件。
  • 出现一个对话框,要求我确认我要重写CSV文件。

是否可以将当前工作表导出为文件,但是可以继续使用原始文件?

7 个答案:

答案 0 :(得分:22)

@NathanClement有点快。然而,这是完整的代码(稍微复杂一点):

Option Explicit

Public Sub ExportWorksheetAndSaveAsCSV()

Dim wbkExport As Workbook
Dim shtToExport As Worksheet

Set shtToExport = ThisWorkbook.Worksheets("Sheet1")     'Sheet to export as CSV
Set wbkExport = Application.Workbooks.Add
shtToExport.Copy Before:=wbkExport.Worksheets(wbkExport.Worksheets.Count)
Application.DisplayAlerts = False                       'Possibly overwrite without asking
wbkExport.SaveAs Filename:="C:\tmp\test.csv", FileFormat:=xlCSV
Application.DisplayAlerts = True
wbkExport.Close SaveChanges:=False

End Sub

答案 1 :(得分:10)

几乎我想要@Ralph。您的代码存在一些问题:

  1. 只导出名为“Sheet1”的硬编码表;
  2. 它总是导出到同一个临时文件,覆盖它;
  3. 它忽略了语言环境分离字符。
  4. 为了解决这些问题并满足我的所有要求,我改编了code from here。我已经清理了一点,使其更具可读性。

    Option Explicit
    Sub ExportAsCSV()
    
        Dim MyFileName As String
        Dim CurrentWB As Workbook, TempWB As Workbook
    
        Set CurrentWB = ActiveWorkbook
        ActiveWorkbook.ActiveSheet.UsedRange.Copy
    
        Set TempWB = Application.Workbooks.Add(1)
        With TempWB.Sheets(1).Range("A1")
          .PasteSpecial xlPasteValues
          .PasteSpecial xlPasteFormats
        End With        
    
        Dim Change below to "- 4"  to become compatible with .xls files
        MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, Len(CurrentWB.Name) - 5) & ".csv"
    
        Application.DisplayAlerts = False
        TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
        TempWB.Close SaveChanges:=False
        Application.DisplayAlerts = True
    End Sub
    

    上面的代码还有一些小问题你应该注意:

    1. .CloseDisplayAlerts=True应该在finally子句中,但我不知道如何在VBA中执行此操作
    2. 如果当前文件名有4个字母,就像.xlsm一样。无法在.xls excel文件中使用。对于3个字符的文件扩展名,您必须在设置MyFileName时将- 5更改为- 4
    3. 作为附带效果,您的剪贴板将替换为当前的工作表内容。
    4. 修改:将Local:=True保存到我的区域设置CSV分隔符。

答案 2 :(得分:1)

在上面的此答案上有一点改进,可以在同一例程中同时处理.xlsx和.xls文件,以防万一。

我还添加了一行以选择使用活动工作表名称而不是工作簿进行保存,这对我来说通常是最实用的:

Sub ExportAsCSV()

    Dim MyFileName As String
    Dim CurrentWB As Workbook, TempWB As Workbook

    Set CurrentWB = ActiveWorkbook
    ActiveWorkbook.ActiveSheet.UsedRange.Copy

    Set TempWB = Application.Workbooks.Add(1)
    With TempWB.Sheets(1).Range("A1")
        .PasteSpecial xlPasteValues
        .PasteSpecial xlPasteFormats
    End With

    MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, InStrRev(CurrentWB.Name, ".") - 1) & ".csv"
    'Optionally, comment previous line and uncomment next one to save as the current sheet name
    'MyFileName = CurrentWB.Path & "\" & CurrentWB.ActiveSheet.Name & ".csv"


    Application.DisplayAlerts = False
    TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
    TempWB.Close SaveChanges:=False
    Application.DisplayAlerts = True
End Sub

答案 3 :(得分:0)

根据我对@neves帖子的评论,我通过添加xlPasteFormats以及值部分略微改进了这一点,因此日期与日期相同 - 我主要将其保存为银行对帐单的CSV,因此需要日期。

Sub ExportAsCSV()

    Dim MyFileName As String
    Dim CurrentWB As Workbook, TempWB As Workbook

    Set CurrentWB = ActiveWorkbook
    ActiveWorkbook.ActiveSheet.UsedRange.Copy

    Set TempWB = Application.Workbooks.Add(1)
    With TempWB.Sheets(1).Range("A1")
        .PasteSpecial xlPasteValues
        .PasteSpecial xlPasteFormats
    End With

    'Dim Change below to "- 4"  to become compatible with .xls files
    MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, Len(CurrentWB.Name) - 5) & ".csv"

    Application.DisplayAlerts = False
    TempWB.SaveAs Filename:=MyFileName, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
    TempWB.Close SaveChanges:=False
    Application.DisplayAlerts = True
End Sub

答案 4 :(得分:0)

对于那些需要对输出进行更多自定义(分隔符或小数点符号)或具有大型数据集(超过65k行)的情况,我编写了以下内容:

Option Explicit

Sub rng2csv(rng As Range, fileName As String, Optional sep As String = ";", Optional decimalSign As String)
'export range data to a CSV file, allowing to chose the separator and decimal symbol
'can export using rng number formatting!
'by Patrick Honorez --- www.idevlop.com
    Dim f As Integer, i As Long, c As Long, r
    Dim ar, rowAr, sOut As String
    Dim replaceDecimal As Boolean, oldDec As String

    Dim a As Application:   Set a = Application

    ar = rng
    f = FreeFile()
    Open fileName For Output As #f

    oldDec = Format(0, ".")     'current client's decimal symbol
    replaceDecimal = (decimalSign <> "") And (decimalSign <> oldDec)

    For Each r In rng.Rows
        rowAr = a.Transpose(a.Transpose(r.Value))
        If replaceDecimal Then
            For c = 1 To UBound(rowAr)
                'use isnumber() to avoid cells with numbers formatted as strings
                If a.IsNumber(rowAr(c)) Then
                    'uncomment the next 3 lines to export numbers using source number formatting
'                    If r.cells(1, c).NumberFormat <> "General" Then
'                        rowAr(c) = Format$(rowAr(c), r.cells(1, c).NumberFormat)
'                    End If
                    rowAr(c) = Replace(rowAr(c), oldDec, decimalSign, 1, 1)
                End If
            Next c
        End If
        sOut = Join(rowAr, sep)
        Print #f, sOut
    Next r
    Close #f

End Sub

Sub export()
    Debug.Print Now, "Start export"
    rng2csv shOutput.Range("a1").CurrentRegion, RemoveExt(ThisWorkbook.FullName) & ".csv", ";", "."
    Debug.Print Now, "Export done"
End Sub

答案 5 :(得分:0)

  1. 您可以使用不带参数的 Worksheet.Copy 将工作表复制到新工作簿。 Worksheet.Move 会将工作表复制到新工作簿,并将其从原始工作簿中删除(您可能会说“导出”它)。
  2. 获取对新创建的工作簿的引用并另存为 CSV。
  3. 将 DisplayAlerts 设置为 false 以抑制警告消息。 (完成后不要忘记将其重新打开)。
  4. 您需要在保存工作簿和关闭工作簿时关闭 DisplayAlerts。
    wsToExport.Move

    With Workbooks
        Set wbCsv = .Item(.Count)
    End With

    Application.DisplayAlerts = False
    wbCsv.SaveAs xlCSV
    wbCsv.Close False
    Application.DisplayAlerts = True

答案 6 :(得分:-2)

正如我评论的那样,该网站上有一些地方将工作表的内容写入CSV。 This onethis one仅指出两个。

以下是我的版本

  • 它明确地在单元格中查找“,”
  • 它还使用UsedRange - 因为您想获取工作表中的所有内容
  • 使用数组进行循环,因为这比循环遍历工作表单元格更快
  • 我没有使用FSO例程,但这是一个选项

代码......

Sub makeCSV(theSheet As Worksheet)
Dim iFile As Long, myPath As String
Dim myArr() As Variant, outStr As String
Dim iLoop As Long, jLoop As Long

myPath = Application.ActiveWorkbook.Path
iFile = FreeFile
Open myPath & "\myCSV.csv" For Output Lock Write As #iFile

myArr = theSheet.UsedRange
For iLoop = LBound(myArr, 1) To UBound(myArr, 1)
    outStr = ""
    For jLoop = LBound(myArr, 2) To UBound(myArr, 2) - 1
        If InStr(1, myArr(iLoop, jLoop), ",") Then
            outStr = outStr & """" & myArr(iLoop, jLoop) & """" & ","
        Else
            outStr = outStr & myArr(iLoop, jLoop) & ","
        End If
    Next jLoop
    If InStr(1, myArr(iLoop, jLoop), ",") Then
        outStr = outStr & """" & myArr(iLoop, UBound(myArr, 2)) & """"
    Else
        outStr = outStr & myArr(iLoop, UBound(myArr, 2))
    End If
    Print #iFile, outStr
Next iLoop

Close iFile
Erase myArr

End Sub