Сохраните каждый лист в книге в отдельные файлы CSV.

Как сохранить каждый лист в книге Excel для разделения CSV файлов с помощью макроса?

У меня есть Excel с несколькими листами, и я искал макрос, который сохранит каждый лист на отдельном CSV (comma separated file). Excel не позволит вам сохранить все листы в разные CSV файлы.


person Alex Duggleby    schedule 12.09.2008    source источник


Ответы (8)


Вот тот, который предоставит вам визуальный выбор файла, чтобы выбрать папку, в которую вы хотите сохранить файлы, а также позволяет вам выбрать разделитель CSV (я использую каналы '|', потому что мои поля содержат запятые, и я не хочу иметь дело в кавычках):

' ---------------------- Directory Choosing Helper Functions -----------------------
' Excel and VBA do not provide any convenient directory chooser or file chooser
' dialogs, but these functions will provide a reference to a system DLL
' with the necessary capabilities
Private Type BROWSEINFO    ' used by the function GetFolderName
    hOwner As Long
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As Long
    lParam As Long
    iImage As Long
End Type

Private Declare Function SHGetPathFromIDList Lib "shell32.dll" _
                                             Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" _
                                           Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long

Function GetFolderName(Msg As String) As String
    ' returns the name of the folder selected by the user
    Dim bInfo As BROWSEINFO, path As String, r As Long
    Dim X As Long, pos As Integer
    bInfo.pidlRoot = 0&    ' Root folder = Desktop
    If IsMissing(Msg) Then
        bInfo.lpszTitle = "Select a folder."
        ' the dialog title
    Else
        bInfo.lpszTitle = Msg    ' the dialog title
    End If
    bInfo.ulFlags = &H1    ' Type of directory to return
    X = SHBrowseForFolder(bInfo)    ' display the dialog
    ' Parse the result
    path = Space$(512)
    r = SHGetPathFromIDList(ByVal X, ByVal path)
    If r Then
        pos = InStr(path, Chr$(0))
        GetFolderName = Left(path, pos - 1)
    Else
        GetFolderName = ""
    End If
End Function
'---------------------- END Directory Chooser Helper Functions ----------------------

Public Sub DoTheExport()
    Dim FName As Variant
    Dim Sep As String
    Dim wsSheet As Worksheet
    Dim nFileNum As Integer
    Dim csvPath As String


    Sep = InputBox("Enter a single delimiter character (e.g., comma or semi-colon)", _
                   "Export To Text File")
    'csvPath = InputBox("Enter the full path to export CSV files to: ")

    csvPath = GetFolderName("Choose the folder to export CSV files to:")
    If csvPath = "" Then
        MsgBox ("You didn't choose an export directory. Nothing will be exported.")
        Exit Sub
    End If

    For Each wsSheet In Worksheets
        wsSheet.Activate
        nFileNum = FreeFile
        Open csvPath & "\" & _
             wsSheet.Name & ".csv" For Output As #nFileNum
        ExportToTextFile CStr(nFileNum), Sep, False
        Close nFileNum
    Next wsSheet

End Sub



Public Sub ExportToTextFile(nFileNum As Integer, _
                            Sep As String, SelectionOnly As Boolean)

    Dim WholeLine As String
    Dim RowNdx As Long
    Dim ColNdx As Integer
    Dim StartRow As Long
    Dim EndRow As Long
    Dim StartCol As Integer
    Dim EndCol As Integer
    Dim CellValue As String

    Application.ScreenUpdating = False
    On Error GoTo EndMacro:

    If SelectionOnly = True Then
        With Selection
            StartRow = .Cells(1).Row
            StartCol = .Cells(1).Column
            EndRow = .Cells(.Cells.Count).Row
            EndCol = .Cells(.Cells.Count).Column
        End With
    Else
        With ActiveSheet.UsedRange
            StartRow = .Cells(1).Row
            StartCol = .Cells(1).Column
            EndRow = .Cells(.Cells.Count).Row
            EndCol = .Cells(.Cells.Count).Column
        End With
    End If

    For RowNdx = StartRow To EndRow
        WholeLine = ""
        For ColNdx = StartCol To EndCol
            If Cells(RowNdx, ColNdx).Value = "" Then
                CellValue = ""
            Else
                CellValue = Cells(RowNdx, ColNdx).Value
            End If
            WholeLine = WholeLine & CellValue & Sep
        Next ColNdx
        WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
        Print #nFileNum, WholeLine
    Next RowNdx

EndMacro:
    On Error GoTo 0
    Application.ScreenUpdating = True

End Sub
person HigherAbstraction    schedule 12.09.2008
comment
Поскольку в вопросе не использовался нестандартный разделитель, я не понимаю, почему вы написали ячейку по программе ячейки. Если вы идете по этому маршруту, работайте с вариантными массивами, а не с диапазонами, пересчитайте UsedRange перед обращением к нему (удалите потенциальное лишнее пространство), объедините длинные строки с комбинированными короткими строками WholeLine = WholeLine & (CellValue & Sep), используйте строковые функции, а не варианты (Left$ не Left) и т. Д. - person brettdj; 24.03.2012

@AlexDuggleby: вам не нужно копировать рабочие листы, вы можете сохранить их напрямую. например.:

Public Sub SaveWorksheetsAsCsv()
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String

    SaveToDirectory = "C:\"

    For Each WS In ThisWorkbook.Worksheets
        WS.SaveAs SaveToDirectory & WS.Name, xlCSV
    Next

End Sub

Единственная потенциальная проблема заключается в том, что ваша книга остается сохраненной как последний файл csv. Если вам нужно сохранить исходную книгу, вам нужно будет сохранить ее как.

person Graham    schedule 12.09.2008
comment
+1 Чтобы использовать в Excel, можно: Alt + F11, Вставить ›Модуль, Вставить код, Нажмите кнопку воспроизведения. - person bishop; 24.10.2014
comment
Другая проблема, не работает, если она сохранена в вашей личной книге. В остальном отлично! - person Dylan Cross; 03.03.2016
comment
@bishop как запустить этот код? Я вставил его в редактор VBA в Excel 2016 на MAC, но не смог запустить. Я получаю эту ошибку Ошибка времени выполнения "1004": ошибка, определяемая приложением или объектом - person Dinesh; 28.04.2016
comment
Если вы измените SaveToDirectory, убедитесь, что вы сохранили обратную косую черту в конце. - person jobo3208; 23.09.2016
comment
Спасибо за это! Имейте в виду: я заметил, что если есть файл. в имени листа расширение .CSV не добавляется к имени файла. - person Craig Eddy; 07.03.2019
comment
Без сомнения, это лучший ответ в этой теме. Сэкономил мне много времени! - person Piotr L; 08.12.2020

И вот мое решение должно работать с Excel> 2000, но протестировано только в 2007 году:

Private Sub SaveAllSheetsAsCSV()
On Error GoTo Heaven

' each sheet reference
Dim Sheet As Worksheet
' path to output to
Dim OutputPath As String
' name of each csv
Dim OutputFile As String

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False

' ask the user where to save
OutputPath = InputBox("Enter a directory to save to", "Save to directory", Path)

If OutputPath <> "" Then

    ' save for each sheet
    For Each Sheet In Sheets

        OutputFile = OutputPath & "\" & Sheet.Name & ".csv"

        ' make a copy to create a new book with this sheet
        ' otherwise you will always only get the first sheet
        Sheet.Copy
        ' this copy will now become active
        ActiveWorkbook.SaveAs FileName:=OutputFile, FileFormat:=xlCSV, CreateBackup:=False
        ActiveWorkbook.Close
    Next

End If

Finally:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True

Exit Sub

Heaven:
MsgBox "Couldn't save all sheets to CSV." & vbCrLf & _
        "Source: " & Err.Source & " " & vbCrLf & _
        "Number: " & Err.Number & " " & vbCrLf & _
        "Description: " & Err.Description & " " & vbCrLf

GoTo Finally
End Sub

(ОТ: Интересно, заменит ли SO некоторые из моих второстепенных блогов)

person Alex Duggleby    schedule 12.09.2008
comment
Спасибо! Работает в Office 2010. Мне потребовалось некоторое время, чтобы понять, что мне пришлось оставить конечный / в пути к файлу, иначе выдает ошибки - person TimoSolo; 31.10.2011

Основываясь на ответе Грэма, дополнительный код сохраняет книгу обратно в исходное место в исходном формате.

Public Sub SaveWorksheetsAsCsv()

Dim WS As Excel.Worksheet
Dim SaveToDirectory As String

Dim CurrentWorkbook As String
Dim CurrentFormat As Long

 CurrentWorkbook = ThisWorkbook.FullName
 CurrentFormat = ThisWorkbook.FileFormat
' Store current details for the workbook

      SaveToDirectory = "C:\"

      For Each WS In ThisWorkbook.Worksheets
          WS.SaveAs SaveToDirectory & WS.Name, xlCSV
      Next

 Application.DisplayAlerts = False
  ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
 Application.DisplayAlerts = True
' Temporarily turn alerts off to prevent the user being prompted
'  about overwriting the original file.

End Sub
person Robert Mearns    schedule 15.09.2008
comment
извините, но зачем вам сохранять исходную книгу? Можно просто закрыть без изменений, правда? Затем вы уже создали все файлы .csv. - person user3032689; 18.06.2016
comment
Вы правы, вам не обязательно. Это зависит от вашего рабочего процесса. Сохранение предназначено для восстановления текущего имени и формата книги. Затем он остается открытым для взаимодействия с пользователем. Если этого не было сделано, тогда, когда пользователь попытается сохранить его, именем будет имя последнего обработанного листа в формате .csv. Если вам больше не нужна книга, тогда ThisWorkbook.Close SaveChanges: = False будет работать так же хорошо. - person Robert Mearns; 20.06.2016
comment
Понятно, это то, что вы задумали :) - person user3032689; 20.06.2016

Небольшая модификация на ответ от Алекса включает и выключает автоматический расчет.

Удивительно, но неизмененный код нормально работал с ВПР, но не работал с СМЕЩЕНИЕМ. Также отключение автоматического расчета значительно ускоряет сохранение.

Public Sub SaveAllSheetsAsCSV()
On Error GoTo Heaven

' each sheet reference
Dim Sheet As Worksheet
' path to output to
Dim OutputPath As String
' name of each csv
Dim OutputFile As String

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False

' Save the file in current director
OutputPath = ThisWorkbook.Path


If OutputPath <> "" Then
Application.Calculation = xlCalculationManual

' save for each sheet
For Each Sheet In Sheets

    OutputFile = OutputPath & Application.PathSeparator & Sheet.Name & ".csv"

    ' make a copy to create a new book with this sheet
    ' otherwise you will always only get the first sheet

    Sheet.Copy
    ' this copy will now become active
     ActiveWorkbook.SaveAs Filename:=OutputFile, FileFormat:=xlCSV,     CreateBackup:=False
    ActiveWorkbook.Close
Next

Application.Calculation = xlCalculationAutomatic

End If

Finally:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True

Exit Sub

Heaven:
MsgBox "Couldn't save all sheets to CSV." & vbCrLf & _
        "Source: " & Err.Source & " " & vbCrLf & _
        "Number: " & Err.Number & " " & vbCrLf & _
        "Description: " & Err.Description & " " & vbCrLf

GoTo Finally
End Sub
person Community    schedule 10.05.2009
comment
ActiveWorkbook.SaveAs Filename: = OutputFile, FileFormat: = xlCSV, CreateBackup: = False, Local: = True сохранит даты в локальном формате. - person adam; 10.07.2013

Используйте Visual Basic для просмотра листов и сохранения .csv файлов.

  1. Откройте .xlsx файл в Excel.

  2. Нажмите option + F11

  3. InsertModule

  4. Вставьте это в код модуля:

    Public Sub SaveWorksheetsAsCsv()
    
     Dim WS As Excel.Worksheet
     Dim SaveToDirectory As String
    
     SaveToDirectory = "./"
    
     For Each WS In ThisWorkbook.Worksheets
        WS.SaveAs SaveToDirectory & WS.Name & ".csv", xlCSV
     Next
    
    End Sub
    
  5. Запускаем модуль.

    (т.е. нажмите кнопку воспроизведения вверху, а затем нажмите "Выполнить" в диалоговом окне, если оно появится.)

  6. Найдите свои .csv файлы в ~/Library/Containers/com.microsoft.Excel/Data.

    open ~/Library/Containers/com.microsoft.Excel/Data
    
  7. Закройте .xlsx файл.

  8. Промойте и повторите для остальных .xlsx файлов.

person Joshua Pinter    schedule 19.02.2021

Для таких пользователей Mac, как я, есть несколько подводных камней:

Вы не можете сохранять в любой каталог, который хотите. Лишь немногие из них могут получить ваши сохраненные файлы. Дополнительная информация здесь

Вот рабочий скрипт, который вы можете скопировать и вставить в свой Excel для Mac:

Public Sub SaveWorksheetsAsCsv()

 Dim WS As Excel.Worksheet
 Dim SaveToDirectory As String

 SaveToDirectory = "~/Library/Containers/com.microsoft.Excel/Data/"

 For Each WS In ThisWorkbook.Worksheet
    WS.SaveAs SaveToDirectory & WS.Name & ".csv", xlCSV
 Next

End Sub

person Żabojad    schedule 19.05.2020
comment
+1 для использования на Mac. Две вещи: 1. В строке цикла for отсутствует s - должно быть ...ThisWorkbook.Worksheet*s* 2. Я получаю '[sheetname].csv' cannot be accessed ошибку. Однако, как ни странно, если я установил путь к SaveToDirectory = './', все листы успешно экспортировались в папку ~/Library/Containers/com.microsoft.Excel/Data/. - person Ken; 25.08.2020

Загляните в Ответ фон Пуки, все ему / ей.

 Sub asdf()
Dim ws As Worksheet, newWb As Workbook

Application.ScreenUpdating = False
For Each ws In Sheets(Array("EID Upload", "Wages with Locals Upload", "Wages without Local Upload"))
   ws.Copy
   Set newWb = ActiveWorkbook
   With newWb
      .SaveAs ws.Name, xlCSV
      .Close (False)
   End With
Next ws
Application.ScreenUpdating = True

End Sub
person Luigi Mackenzie C. Brito    schedule 09.01.2015