【本日のミッション】
フォルダ内に散らばった複数のExcelファイルを、手作業でコピペせずに「一瞬で1つのブックにまとめる」仕組みを作ること。
目次
ミッションの概要
毎日繰り返し行う作業を自動化すると、劇的に作業効率が上がります。
特に「毎日届く売上報告」や「複数部署の月次ファイル」を1つに集めたい場合、VBAを使えばワンクリックで完了できますね。
別々のファイルのデータが・・・
1つのブックにまとまりました♪
解決方法とプロシージャ
- Dir関数でフォルダ内のファイルを順に取得する
- Workbooks.Openで開く
- Sheets.Copyで集約ブックに転記する
- 最後に保存して終了
Sub MergeFiles()
'【変数】
Dim f_pt As String 'フォルダパス
Dim fn As String 'ファイル名
Dim wb As Workbook 'コピー元ブック
Application.ScreenUpdating = False
’■変数セット
f_pt = "C:\Data\" '処理対象のフォルダパスを指定
fn = Dir(f_pt & "*.xlsx") '最初のExcelファイル名を取得
’■ファイルを順に処理
Do While fn <> "" 'ファイルがなくなるまで繰り返す
Set wb = Workbooks.Open(f_pt & fn) 'ファイルを開く
wb.Sheets(1).Copy Before:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) '1枚目のシートをコピー
wb.Close SaveChanges:=False '保存せず閉じる
fn = Dir '次のファイル名を取得
Loop
Application.ScreenUpdating = True
End Sub
今回は、フォルダ内にある複数のExcelファイルを一瞬で結合してしまうマクロをご紹介します。「何十個も開いてコピペ…」という地獄作業を、VBAが一瞬でやってくれるんです。
コード解説
変数宣言
Dim f_pt As String 'フォルダパス Dim fn As String 'ファイル名 Dim wb As Workbook 'コピー元ブック
- f_pt は処理対象フォルダのパスを入れる箱。
- fn は Dir 関数で取得したファイル名を入れる箱。
- wb は開いたExcelファイル(Workbook)を操作するための箱です。
画面更新の停止
VBAを実行すると、通常は シートの画面が1行ずつ切り替わる動き が表示されます。
ファイルを結合する処理など、大量のコピーやシート切り替えが発生すると、その度に画面が更新されて「ガタガタ」と動きが遅くなってしまいます。
このコードを入れると、を入れると、処理中の画面更新を止めることができます。
これにより実行スピードが格段に速くなり、ユーザーも無駄な画面のチラつきを見ずに済みます。
最後に必ず
Application.ScreenUpdating = True
で元に戻しておくのが安全です。
Dir関数とは
Dir関数は、第1引数に指定したファイル・フォルダが存在する場合、パスを除いたファイル名・フォルダ名を返します。存在しない場合は長さ0の文字列 ”” (空欄)を返します。
Dir(ファイル・フォルダのパス,ファイル・フォルダの属性)
Dir (“C:\VBA\第1階層\File1_1.xlsx”) の場合
- ファイルが存在する場合(ファイル名を返す)→ File1_1.xlsx
- ファイルが存在しない場合(空欄を返す) → ””
第1引数にはワイルドカードを使用することができるので、取得したいファイル名・フォルダ名の幅を広げることができます。
Dir(”C:\VBA\第1階層\*.*“)
第2引数に下記定数(値)を指定することで、特定の属性のオブジェクトのみを取得の対象とすることができます。
| 定数 | 値 | 属性 |
| vbNormal (既定) | 0 | 標準ファイル |
| vbReadOnly | 1 | 読み取り専用ファイル |
| vbHidden | 2 | 隠しファイル |
| vbSystem | 4 | システム ファイル |
| vbVolume | 8 | ボリューム ラベル。この値を指定すると、すべての属性は無効になります。 |
| vbDirectory | 16 | フォルダ |
| vbAlias | 64 | エイリアスファイル |
※4、8はMacでは使えません。また、64はMacintoshのみ使えます。
今回は、規定値となっている標準ファイルを取得するため、第2引数は省略しています。
Dir関数は一度引数を指定すると、次に別の引数を指定するまで、同じ引数に対する処理を行います。
fn=Dir(”C:\VBA\第1階層\*.*”) fn=Dir() fn=Dir()
1行目の処理では、変数fnに「C:\VBA\第1階層\*.*」に一致するファイルが存在すれば、そのファイル名を返します。
2行目以降の「fn=Dir()」では引数を指定していませんが、「C:\VBA\第1階層\*.*」に一致する別のファイル名を返します。
その処理を繰り返し、「C:\VBA\第1階層\*.*」に一致するファイルが無くなった時、長さ0の文字列 ”” 空欄 を返します。
何度も「fn=Dir()」を書くのは面倒だし、どのタイミングでファイルが無くなるかわからないので、Do While ~ Loopを使って繰り返し処理を行います。
fn=Dir(”C:\VBA\第1階層\*.*”) Do While fn <> "" 'fnが空欄になるまでDo While内の処理を続ける ~fnで行いたい処理を記述~ fn = Dir() '変数fnに次のファイル名を格納(ファイルが無い場合は空欄になる) Loop
参考:Dir関数が取得するファイルの順番
参考:Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
Do While ~ Loop で全ファイルを処理
fn <> ""→ まだファイルがある間だけ繰り返すWorkbooks.Open→ ファイルを開くwb.Sheets(1).Copy→ 開いたブックの1枚目のシートをコピーThisWorkbook.Sheets.Count→ 今のブックの最後のシートの直前にコピーするwb.Close SaveChanges:=False→ 元ファイルは保存せず閉じるfn = Dir→ 次のファイル名を取得する
これを繰り返すことで、フォルダ内のファイルを片っ端から結合していきます♪
まとめ
Dir関数でファイルを1つずつ取得Do While ~ Loopでファイルがなくなるまで繰り返し処理Workbooks.Open&Copyでシートをまとめる
初めて動かしたとき、ほんとに感動しました。
「あんな面倒な作業が、数秒で終わるなんて!」って。
VBAをちょっと使えるだけで、Excel作業の世界がガラッと変わりますよ♪
【参考】
指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
指定したフォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
再帰処理とは?フォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)
ファイルのフルパスからファイル名のみを取得 InStrRev関数(Excel VBA)
指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
FileSystemObjectとは?CreateObject 関数 FolderExists・GetFolderの使い方
FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止
再帰処理とは?指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
ファイルのフルパスからファイル名のみを取得 Split関数(Excel VBA)
Callステートメントとは 引数 括弧()の使い方(Excel VBA)
指定したフォルダ内から「特定の文字を含まないファイル名」を取得(Excel VBA)
ワイルドカードとは。使い方いろいろ。(Excel)
Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
指定したフォルダのファイル名を取得し、そのファイル名を一括で変換(Excel VBA)
Excel起動時に「コンパイルエラー」。64ビット システムで Declareステートメントに、PtrSafe属性を設定(Excel VBA )
「ファイルを開く」ダイアログボックス から ファイル名を取得(Excel VBA)
「ファイルを開く」ダイアログボックス から 複数 ファイル名を取得(Excel VBA)
指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
再帰処理とは?指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
エクセル Dir関数 を使ってファイルの存在(有無)を確認する(Excel VBA)
エクセル FileSystemObject を使ってファイルの存在(有無)をチェックする(Excel VBA)
Excel Dir関数 存在しないファイル・フォルダが「存在している」と判定される理由(Excel VBA)
64ビットExcel起動時にコンパイルエラー。Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)(Excel VBA )
Excel VBA セキュリティリスク このファイルのソースが信頼できないため、Microsoftによりマクロの実行がブロックされました。 を解決
Excel 64bit VBAファイルを立ち上げたらマクロが動かないエラー VBEプロシージャコードが表示されないを解決
Excel VBAでフォルダ内の全ファイルを1つにまとめる方法
Microsoft公式:Dir関数リファレンス
Microsoft公式:Workbook オブジェクト