すべて同じ形式のExcelファイルが数百あります(Excelファイルごとに4つのワークシート)。すべてのファイルを1つに統合して、元のファイルと同じ形式のすべての歌と踊りのファイルにする必要があります(つまり、すべて同じ名前の4つの個別のワークシートを維持します)。
各ファイルの構造は同じですが、たとえばシート1と2の間の列(および見出し名)の数は異なります。したがって、1つのファイルにすべてを1つのシートにまとめることはできません。
2つの複雑な問題があります。
ソースファイル(「ファイル名」)を識別するために、マージされたファイル(各シート上)にEXTRA列を作成する必要があります。
ファイルには、マージされたファイルから削除する必要がある多くのゼロデータエントリ(たとえば、55行の有用なデータとそれに続く数百行のゼロ)が含まれています。
私はVBAを使用したことがありませんが、誰もが私が思うところから始めなければなりません。
それはあなたが持っている強力な要求ですが、私は燃やす夜があったので、ここに私が動作すると思ういくつかのコードがあります。 (あなたのシートのフォーマットを知らなくても役に立ちませんが、これから作業することができます。)
新しいワークブック(これがマスターワークブックになります)を開き、VBA環境(Alt + F11)に移動して、新しいモジュールを作成します(挿入>モジュール)。次のVBAコードを新しいモジュールウィンドウに貼り付けます。
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
保存すると、使用を開始する準備が整います。
マクロGiantMerge
を実行します。マージするExcelファイルを選択する必要があります(通常のウィンドウの方法で、ダイアログボックスで複数のファイルを選択できます(Ctrlキーを押して複数の個別ファイルを選択し、Shiftキーを押してファイルの範囲を選択します)。マージするすべてのファイルでマクロを実行する必要はありません。一度に数個だけ実行できます。初めて実行すると、マスターブックが正しい数のシートを持つように構成され、マージするために選択した最初のブックに基づいてシートに名前が付けられ、見出しに追加されます。
私は以下の仮定をしました(完全なリストではありません):
お役に立てれば。
また、Ron de BruinがRDBMergeと呼ばれるExcelワークシートをマージするための素晴らしいWindowsプラグインを作成したことにも言及する価値があります。手順はここにあります: http://www.rondebruin.nl/merge.htm 。 Excel 2007でxlsxファイルをマージすることで、問題なく動作しました。
ソースファイルの名前を含むマージされたファイルに追加の列を作成します。ただし、ゼロデータエントリ(元の質問の2番目の部分)の処理方法はわかりません。
これらのExcelファイルをマージするだけのツールが必要な場合は、 JMC Excel を確認してください。
単純なpythonスクリプトを使用するメソッド(VBよりもはるかに短い!))。
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
これはまともなサイズのプロジェクトですが、非常に実行可能です。ここに、構築できるVBAの良いスタートがあります。これにより、1つのフォルダーにファイルを(単独で)持っている場合に、マージする必要があるすべてのファイルを確認できます。マージするマスタブックは、このディレクトリに存在してはなりません。
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
これで、あなた(または他の誰か)が最後にForループのコードを提供できます。お役に立てれば。