Yüzlerce Excel elektronik tablosu dosyasını nasıl birleştirebilirim?


7

Aynı biçime sahip yüzlerce Excel dosyasına sahibim (örneğin, Excel dosyası başına 4 çalışma sayfası). Tüm dosyaları orijinaller ile aynı formata sahip olması gereken tüm şarkı söyleyen ve dans eden 1 dosyada birleştirmem gerekiyor (yani hepsi aynı adda olan dört ayrı çalışma sayfasını saklayın).

Her dosya aynı şekilde yapılandırılmış olsa da, sayfa 1 ve 2 arasındaki (örneğin) sütun sayısı (ve başlık adları) farklıdır. Bu yüzden tek bir sayfada her şeyle tek bir dosyada birleştirilemez!

İki komplikasyon var:

  1. Kaynak dosyayı ("dosya adı") tanımlamak için birleştirilmiş dosyada (EACH sayfasında) bir EKSTRA sütunu oluşturmam gerekiyor.

  2. Dosyalar, birleştirilmiş dosyadan kaldırmam gereken çok sayıda sıfır veri girişi (ör. 55 satır yararlı veri ve ardından yüzlerce sıfır sırası) içerir.

VBA'yı hiç kullanmadım, ama herkes sanırım bir yerden başlamalı.


1
VBA’ya başlamanın iyi bir yolu, makrolarınızı kaydederek (hit kayıt, ispatlamalarınızı yapın ve sonra durmanız) ve bunlarla ilişkili kodu görüntüleyerek başlamaktır (sadece bir ipucu, sorununuzu çözmek için bunu yapmanız önerilmemektedir)
jonsca

Ya da sadece en MVP dilenmek answers.microsoft.com . Muhtemelen yapmanın en iyi yolu, başladığınız şeyin örnek şablonlarını göndermek ve sonunda nasıl görünmesini istediğinizi belirlemek, sütunların tam olarak nasıl biçimlendirilmesini istediğinizi işaretlediğinizden emin olmaktır. Ne kadar hazırlıklı iş olursa o kadar iyidir. Bu şekilde, kötü yazılmış özellikler nedeniyle birkaç satır yazmıyorsunuz.
surfasb

Yanıtlar:


13

Bu, sahip olduğunuz kudretli bir istek, ancak yakmak için bir akşam geçirdim, işte işe yarayacağını düşündüğüm bazı kodlar. (Sayfalarınızın biçimini bilmemeniz yardımcı olmuyor ancak bu konuda çalışabiliriz.)

Yeni bir çalışma kitabı açın (bu ana çalışma kitabınız olacaktır), VBA ortamına (Alt + F11) gidin ve yeni bir modül oluşturun (Ekle> Modül). Aşağıdaki VBA kodunu yeni modül penceresine yapıştırın:

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

Sakla, kullanmaya başlamaya hazırız.

Makroyu çalıştır GiantMerge. Birleştirmek istediğiniz excel dosyalarını seçmek zorundasınız (diyalog kutusuyla birden fazla dosyayı, normal pencereler yolunda seçebilirsiniz (birden fazla bireysel dosya seçmek için Ctrl, bir dosya aralığı seçmek için Shift)). Makroyu birleştirmek istediğiniz tüm dosyalar üzerinde çalıştırmak zorunda değilsiniz, aynı anda birkaç defa yapabilirsiniz. İlk çalıştırdığınızda, ana çalışma kitabınızı doğru sayıda sayfaya sahip olacak şekilde yapılandırır, birleştirmek için seçtiğiniz ilk çalışma kitabına göre sayfaları adlandırır ve başlıklara ekler.

Aşağıdaki varsayımları yaptım (tam bir liste değil):

  • 4 sayfa vardır (Bu kodun üstündeki sabiti değiştirerek kolayca değiştirilebilir.)
  • Tüm ekstra çalışma kitaplarında sayfalar aynı sıradadır
  • Her sayfadaki sütunlar tüm çalışma kitaplarında aynı sıradadır (çalışma kitabındaki tüm sayfaların aynı sütunlara sahip olmamasına rağmen. Örneğin, Çalışma Kitabı1, Sayfa1'de A, B, C, Sayfa2'de sütunlar A, B; Çalışma Kitabı2, Sayfa1'de bulunur. A, B, C, Sayfa2'de A, B sütunları vardır. Etc. Bir çalışma kitabında aşağıdakiler varsa: Sayfa1'de A, C, B, Sayfa2'de B, A sütunları vardır, sonra sütunlar doğru şekilde hizalanmaz)
  • Ek çalışma kitaplarında fazladan veya eksik sütun yok
  • Her çalışma kitabındaki her sayfada bir başlık satırı vardır (ve yalnızca her sayfada ilk satırdadır)
  • Tüm sütunlar dahil edilmelidir (yalnızca 0 içermeli olsalar bile)
  • Yalnızca 0 içeren bir tablonun sonundaki tüm satırlar master’a kopyalanmaz
  • Ek sütunda ihtiyacınız olan sadece dosya adıdır (dosya yolu değil)
  • Bazı sayfalarda herhangi bir veri yoksa (veya sadece sıfırlarla dolu) ne kadar işe yarayacağını bilmiyorum.

Bu yardımcı olur umarım.


1
Mutlak Genius !! Dosya adlarını doğru yere ekledi ve fazla veriyi dört çalışma sayfasından 2'sinden çıkardı. Şansı verilen her şeyi yapmış olacağından eminim ama son engelde düştü: [Eğer ws.Cells (r, c) <> 0 Öyleyse] Düşünebilmemin tek sebebi, çalıştığı levhaların içerdiğidir. ham veriler (sabit sayılar), tarihler ve formül yok. Diğer kağıtlara bağlı formüller içermeyen ikisi. Bunun uygun olup olmadığını bilmiyorum ama çalışma sayfalarındaki bilgiler arasındaki tek gerçek fark bu. Düzeltmek için ne yapabilirim? Çok teşekkürler
Jonathan de Mille

@Jonathan de Mille, değiştirmeyi deneyin If ws.Cells(r, c) <> 0 Theniçin If ws.Cells(r, c).Value <> 0 Then. Yukarıdaki cevapta kodumu güncelledim. Ama şimdi işteyken bunu test edemiyorum. İşe yaramazsa, eve geldiğimde bu gece başka bir göz atacağım.
Chris Kent

Kesinti sırasında aldığınız tam hata mesajını bana bildirirseniz yardımcı olabilir.
Chris Kent

@ Phydaux. Merhaba, Yalnızca 1 dosya seçersem, hatasız çalışır. İki dosya seçersem, yukarıdaki noktaya düşer. Bunun nedeni, sayfaların ham veriye sahip olduğu yerlerde sıfır veri noktasını doğru bir şekilde tanımlaması, ancak ham verilere bağlı formülleri içeren sayfalarda bulunmamasıdır. Olduğu gibi, çalışma kitabından yalnızca bir 'belirli' çalışma sayfası seçilebiliyorsa (örneğin XXX-Raw diyorsa), sıfırın atılabileceği nokta o çalışma kitabındaki 4 sayfa için de aynı olurdu. Ps: .value değişikliğini denedim ama sonuç aynıydı. Bu yardımcı olur umarım. Çok teşekkürler.
Jonathan de Mille,

@ Phydaux. Bu arada hata mesajı çalışma zamanı hatası '13' Uyumlu değil yazın. Çok teşekkürler.
Jonathan de Mille,

1

Ron de Bruin'in RDBMerge adlı Excel çalışma sayfalarını birleştirmek için harika bir Windows eklentisi oluşturduğunu da belirtmek gerekir. Talimatlar burada bulunabilir: http://www.rondebruin.nl/merge.htm . Excel 2007'de xlsx dosyalarını birleştirmek benim için kusursuz çalıştı.

Kaynak dosya adını içeren birleştirilmiş dosyada fazladan bir sütun oluşturur. Yine de sıfır veri girişini (orijinal sorunun ikinci kısmı) nasıl kullandığından emin değilim.



0

Bu iyi bir büyüklük projesi ama çok yapılabilir. İşte, inşa edebileceğiniz VBA'da iyi bir başlangıç. Bu, (tek başına) bir klasörde varsa birleştirmeniz gereken tüm dosyaları gözden geçirmenize olanak sağlar. Birleştirdiğiniz ana çalışma kitabı bu dizinde olmamalıdır.

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

Artık siz (veya başka biri) sonunda For döngüsü için kod sağlayabilirsiniz. Bu yardımcı olur umarım.


Çok teşekkürler, hepsi şu anda bana gobbledygook demek, ama ben bir gideceğim.
Jonathan de Mille,

Acemiyetim şimdi gösteriliyor, bunu denediğimde, satırda bir çalışma zamanı hatası aldım -> Set ws1 = wb. Kaçırdığım bir şey mi var?
Jonathan de Mille,

Sayfa adlarını çalışma kitabınızdaki sayfalarla eşleşecek şekilde değiştirdiniz mi? Satırı değiştirmeniz gerekir: sn1 = "Sayfa1" ila: sn1 = "<sayfa adınız>" vb. Diğer sayfa nesneleri için.
Excellll

Merhaba, çalışma sayfası adlarını vb. Değiştirdim, ancak dizini aralık hatası dışında kaldıramadım.
Jonathan de Mille,

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

SuperUser'a hoş geldiniz. Bu kod, yayınlanan diğer VBA cevaplarının ne yapmadığını ne yapar? Kodunuzu, yalnızca bir kod bloğunu göndermek yerine bir açıklama ve açıklama ile tanıtmak için her zaman en iyisidir.
Andi Mohr

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.