Como posso mesclar centenas de arquivos de planilha do Excel?

7

Eu tenho centenas de arquivos Excel que são todos do mesmo formato (ou seja, 4 planilhas por arquivo do Excel). Eu preciso combinar todos os arquivos em um arquivo de canto e de dança que deve ter o mesmo formato que os originais (ou seja, manter as quatro planilhas separadas, todas com nomes idênticos).

Enquanto cada arquivo é estruturado da mesma forma, o número de colunas (e os nomes dos títulos) entre as planilhas 1 e 2 (por exemplo) é diferente. Por isso, não pode ser combinado em um arquivo com tudo em uma só folha!

Existem duas complicações:

  1. Eu preciso criar uma coluna EXTRA no arquivo mesclado (em cada folha) para identificar o arquivo de origem ("nome do arquivo").

  2. Os arquivos contêm muitas entradas de dados zero (por exemplo, 55 linhas de dados úteis seguidas por centenas de linhas de zeros) que preciso remover do arquivo mesclado.

Eu nunca usei VBA, mas todo mundo tem que começar em algum lugar, suponho.

    
por Jonathan de Mille 01.07.2011 / 11:40

6 respostas

13

Esse é um pedido poderoso que você tem, mas eu tive uma noite para gravar, então aqui está um código que acho que funcionará. (Não saber os formatos das suas planilhas não ajuda, mas podemos trabalhar com isso.)

Abra uma nova pasta de trabalho (essa será sua pasta de trabalho principal), vá para o ambiente VBA (Alt + F11) e crie um novo módulo (Módulo Insert >). Cole o seguinte código do VBA na nova janela do módulo:

Option Explicit
Const NUMBER_OF_SHEETS = 4

Public Sub GiantMerge()
    Dim externWorkbookFilepath As Variant
    Dim externWorkbook As Workbook
    Dim i As Long
    Dim mainLastEnd(1 To NUMBER_OF_SHEETS) As Range
    Dim mainCurEnd As Range

    Application.ScreenUpdating = False

    ' Initialise

    ' Correct number of sheets
    Application.DisplayAlerts = False
    If ThisWorkbook.Sheets.Count < NUMBER_OF_SHEETS Then
        ThisWorkbook.Sheets.Add Count:=NUMBER_OF_SHEETS - ThisWorkbook.Sheets.Count
    ElseIf ThisWorkbook.Sheets.Count > NUMBER_OF_SHEETS Then
        For i = ThisWorkbook.Sheets.Count To NUMBER_OF_SHEETS + 1 Step -1
            ThisWorkbook.Sheets(i).Delete
        Next i
    End If
    Application.DisplayAlerts = True

    For i = 1 To NUMBER_OF_SHEETS
        Set mainLastEnd(i) = GetTrueEnd(ThisWorkbook.Sheets(i))
    Next i


    ' Load the data
    For Each externWorkbookFilepath In GetWorkbooks()
        Set externWorkbook = Application.Workbooks.Open(externWorkbookFilepath, , True)

        For i = 1 To NUMBER_OF_SHEETS

            If mainLastEnd(i).Row > 1 Then
                ' There is data in the sheet

                ' Copy new data (skip headings)
                externWorkbook.Sheets(i).Range("A2:" & GetTrueEnd(externWorkbook.Sheets(i)).Address).Copy ThisWorkbook.Sheets(i).Cells(mainLastEnd(i).Row + 1, 1)

                ' Find the end column and row
                Set mainCurEnd = GetTrueEnd(ThisWorkbook.Sheets(i))
            Else
                ' No nata in sheet yet (prob very first run)

                ' Get correct sheet name from first file we check
                ThisWorkbook.Sheets(i).Name = externWorkbook.Sheets(i).Name

                ' Copy new data (with headings)
                externWorkbook.Sheets(i).Range("A1:" & GetTrueEnd(externWorkbook.Sheets(i)).Address).Copy ThisWorkbook.Sheets(i).Cells(mainLastEnd(i).Row, 1)

                ' Find the end column and row
                Set mainCurEnd = GetTrueEnd(ThisWorkbook.Sheets(i)).Offset(, 1)

                ' Add file name heading
                ThisWorkbook.Sheets(i).Cells(1, mainCurEnd.Column).Value = "File Name"
            End If

            ' Add file name into extra column
            ThisWorkbook.Sheets(i).Range(ThisWorkbook.Sheets(i).Cells(mainLastEnd(i).Row + 1, mainCurEnd.Column), mainCurEnd).Value = externWorkbook.Name

            Set mainLastEnd(i) = mainCurEnd
        Next i

        externWorkbook.Close
    Next externWorkbookFilepath

    Application.ScreenUpdating = True
End Sub

' Returns a collection of file paths, or an empty collection if the user selects cancel
Private Function GetWorkbooks() As Collection
    Dim fileNames As Variant
    Dim xlFile As Variant

    Set GetWorkbooks = New Collection

    fileNames = Application.GetOpenFilename(Title:="Please choose the files to merge", _
                                               FileFilter:="Excel Files, *.xls;*.xlsx", _
                                               MultiSelect:=True)
    If TypeName(fileNames) = "Variant()" Then
        For Each xlFile In fileNames
            GetWorkbooks.Add xlFile
        Next xlFile
    End If
End Function

' Finds the true end of the table (excluding unused columns/rows and rows filled with 0's)
Private Function GetTrueEnd(ws As Worksheet) As Range
    Dim lastRow As Long
    Dim lastCol As Long
    Dim r As Long
    Dim c As Long

    On Error Resume Next
    lastCol = ws.UsedRange.Find("*", , , xlPart, xlByColumns, xlPrevious).Column
    lastRow = ws.UsedRange.Find("*", , , xlPart, xlByRows, xlPrevious).Row
    On Error GoTo 0

    If lastCol <> 0 And lastRow <> 0 Then

        ' look back through the last rows of the table, looking for a non-zero value
        For r = lastRow To 1 Step -1
            For c = 1 To lastCol
                If ws.Cells(r, c).Text <> "" Then
                    If ws.Cells(r, c).Text <> 0 Then
                        Set GetTrueEnd = ws.Cells(r, lastCol)
                        Exit Function
                    End If
                End If
            Next c
        Next r
    End If

    Set GetTrueEnd = ws.Cells(1, 1)
End Function

Salve e estamos prontos para começar a usá-lo.

Execute a macro GiantMerge . Você tem que selecionar os arquivos do Excel que você deseja mesclar (você pode selecionar vários arquivos com a caixa de diálogo, no modo usual do Windows (Ctrl para selecionar vários arquivos individuais, Shift para selecionar um intervalo de arquivos)). Você não precisa executar a macro em todos os arquivos que deseja mesclar, você pode fazer isso em apenas alguns de cada vez. Na primeira vez que você executá-lo, ele configurará sua planilha mestre para ter o número correto de planilhas, nomeará as planilhas com base na primeira pasta de trabalho selecionada para mesclar e incluirá os cabeçalhos.

Eu fiz as seguintes suposições (não uma lista completa):

  • Existem 4 folhas (Isso pode ser facilmente alterado alterando a constante na parte superior do código).
  • As folhas estão na mesma ordem em todas as pastas de trabalho extras
  • As colunas em cada folha estão na mesma ordem em todas as pastas de trabalho (embora nem todas as folhas em um caderno de trabalho tenham as mesmas colunas. Por exemplo, WorkBook1, Sheet1 tem colunas A, B, C, Sheet2 possui colunas A, B; WorkBook2, Sheet1 tem colunas A, B, C, Sheet2 tem colunas A, B. Etc. Se uma pasta de trabalho tiver o seguinte: Sheet1 tem colunas A, C, B, Sheet2 tem colunas B, A, em seguida, as colunas não serão alinhadas corretamente )
  • Não há colunas extras ou ausentes nas pastas de trabalho extras
  • Existe uma linha de título em cada folha em cada pasta de trabalho (e está na primeira linha em cada folha apenas)
  • Todas as colunas devem ser incluídas (mesmo que contenham apenas 0's)
  • Todas as linhas no final de uma tabela contendo apenas 0s não são copiadas para o mestre
  • É apenas o nome do arquivo (e não o caminho do arquivo) que você precisa na coluna extra
  • Eu não sei quão bem isso funcionará se você não tiver dados em algumas das planilhas (ou eles estão apenas preenchidos com zeros)

Espero que isso ajude.

    
por 03.07.2011 / 00:32
1

Também vale a pena mencionar que Ron de Bruin criou um fabuloso plugin do Windows para mesclar planilhas do Excel, chamado RDBMerge. As instruções podem ser encontradas aqui: link . Ele funcionou perfeitamente para mim, mesclando arquivos xlsx no Excel 2007.

Cria uma coluna extra no arquivo mesclado que contém o nome do arquivo de origem. Não sei como lida com entradas de dados zero (segunda parte da pergunta original).

    
por 18.03.2013 / 12:17
1

Se você precisar de uma ferramenta apenas para mesclar esses arquivos do Excel, verifique JMC Excel .

    
por 27.05.2013 / 12:22
0

Este é um projeto de tamanho decente, mas muito factível. Aqui está um bom começo no VBA que você pode construir. Isso permitirá que você passe por todos os arquivos que precisa mesclar se os tiver (sozinho) em uma pasta. A pasta de trabalho principal na qual você está se fundindo NÃO deve estar nesse diretório.

Option Explicit
Sub giantmerge()
    Dim f As Object, fso As Object
    Dim folder As String
    Dim wb As Workbook, ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
    Dim sn1 As String, sn2 As String, sn3 As String, sn4 As String
    Set wb = ThisWorkbook
    'Change sheet names to match those in your workbooks.
    sn1 = "Sheet1"
    sn2 = "Sheet2"
    sn3 = "Sheet3"
    sn4 = "Sheet4"
    Set ws1 = wb.Sheets(sn1)
    Set ws2 = wb.Sheets(sn2)
    Set ws3 = wb.Sheets(sn3)
    Set ws4 = wb.Sheets(sn4)

    Set fso = CreateObject("Scripting.FileSystemObject")
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Show
        If .SelectedItems.Count = 0 Then
            MsgBox "Cancel Selected"
            End
        End If
        folder = .SelectedItems(1)
    End With
    For Each f In fso.GetFolder(folder).Files
        Workbooks.Open Filename:=f.Path
        'Get data and store in temporary arrays.
        Workbooks(f.Name).Close
        'Input data in this workbook (master).
    Next
End Sub

Agora, você (ou outra pessoa) pode fornecer o código para o loop For no final. Espero que isso ajude.

    
por 01.07.2011 / 17:12
0
Sub simpleXlsMerger()
    Dim bookList As Workbook
    Dim mergeObj As Object, dirObj As Object, filesObj As Object, everyObj As Object
    Application.ScreenUpdating = False
    Set mergeObj = CreateObject("Scripting.FileSystemObject")

    ' change folder path of excel files here
    Set dirObj = mergeObj.Getfolder("D:\change\to\excel\files\path\here")
    Set filesObj = dirObj.Files
    For Each everyObj In filesObj
        Set bookList = Workbooks.Open(everyObj)

        ' change "A2" with cell reference of start point for every files here
        ' for example "B3:IV" to merge all files start from columns B and rows 3 
        ' If you're files using more than IV column, change it to the latest column
        ' Also change "A" column on "A65536" to the same column as start point
        Range("A2:IV" & Range("A65536").End(xlUp).Row).Copy
        ThisWorkbook.Worksheets(1).Activate

        ' Do not change the following column. It's not the same column as above
        Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial
        Application.CutCopyMode = False
        bookList.Close
    Next
End Sub
    
por 17.06.2016 / 14:39
0

Método usando um script python simples (muito menor que VB!).

link

    
por 26.10.2016 / 00:47