この記事では、指定されたフォルダに存在するCSVファイルを全て取り込みする方法について説明しています。
VBAを利用すれば、フォルダに存在するCSVファイルを全て取得でき、1つ1つCSVファイルを手で開く必要はありません。
しかも、全てのCSVデータを間違いなく取得し、簡単に一覧化することができます。
また、ヘッダー行があるCSVファイルでは、ヘッダー行を除いて取り込みできます。
他にも、値のくくりを除いて取り込みます。
例えば、ダブルコーテーションでくくられている場合、値のみ取り込みします。
それでは、指定したフォルダ配下の全てのCSVファイルを対象に、取り込みする機能を作成していきましょう。
困っている女性
困っている女性
困っている女性
解決する男性
解決する男性
困っている女性
◆似たような作業で、単純に1つのCSVファイルを取り込みする方法については、以下の記事を参照してください。
【EXCEL:VBA】CSVファイルを取り込みたい
◆他には、EXCELシートに入力したデータをCSV形式でファイル出力する方法については、以下の記事を参照してください。
【EXCEL:VBA】入力したデータをCSVファイル形式で出力したい
複数CSVファイルを一気に取り込みする機能を、1つ1つ順番に説明していきます。
もくじ
フォルダ指定欄、ヘッダー行の有無・文字くくり形式を指定する欄を準備する
まず、フォルダを指定する欄と細かい設定する欄を作成します。
「メイン」シートを作成する
- 「メイン」という名前のシートを作成します。
- 1行目に「フォルダパス」のタイトル行を作成します。
- 2行目に「フォルダパス」を入力する欄を作成します。
- 3行目に「ヘッダー行の有無」、「文字くくりの形式」のタイトル行を作成します。
- 4行目に「ヘッダー行の有無」、「文字くくりの形式」の設定例の行を作成します。
- 5行目に「ヘッダー行の有無」、「文字くくりの形式」を入力する欄を作成します。
取り込んだCSVデータを出力するシートを準備する
全てのCSVデータを出力するシートを作成します。
「データ」シートを作成する
「データ」という名前のシートを追加します。
あとは、特になにもしなくてよいです。
VBAでシート名を取得する機能を記入する
開発タブの「Visual Basic」をクリックして、「Microsoft Visual Basic for Applications」を起動します。
「Microsoft Visual Basic for Applications」にVBAプログラムを入力します。
標準モジュールを追加して、以下のソースを書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
Public Sub Main_Proc() Dim shtMain As Worksheet Dim shtData As Worksheet Dim fso As Object Dim f As Object Dim nowRow As Long Dim blnHeader As Boolean Dim buf As String Dim var As Variant Dim i As Integer '①メインシートを変数に格納する Set shtMain = ThisWorkbook.Sheets("メイン") '②データシートを変数に格納する Set shtData = ThisWorkbook.Sheets("データ") '③データシートをクリアする shtData.Cells.Clear '④FileSystemObjectを変数に格納する Set fso = CreateObject("Scripting.FileSystemObject") nowRow = 1 '⑤指定されているフォルダに存在するファイル数分処理を繰り返す For Each f In fso.GetFolder(shtMain.Range("A2")).Files '⑥拡張子がcsvのファイルのみ対象とする If LCase(fso.getextensionName(f.Name)) = "csv" Then blnHeader = True '⑦CSVファイルを開く Open shtMain.Range("A2") & "\" & f.Name For Input As #1 '⑧CSVファイルの最終行まで繰り返す Do Until EOF(1) '⑨1行分をbuf変数に取り込みする Line Input #1, buf '⑩ファイルの1行目かつヘッダー行がありの場合は、取り込みをスキップする If blnHeader = True And shtMain.Range("A5") = "あり" Then '取り込みをスキップする Else '⑪カンマ毎に区切って、値を配列に格納する var = Split(buf, ",") '⑫配列の最終列まで繰り返す For i = 0 To UBound(var) '⑬文字くくりの形式が"なし"ならそのままセルにセットする '"なし"以外なら、B5に入力した値を除去してセルにセットする If shtMain.Range("B5") = "なし" Then shtData.Cells(nowRow, i + 1) = var(i) Else shtData.Cells(nowRow, i + 1) = Replace(var(i), shtMain.Range("B5"), "") End If Next nowRow = nowRow + 1 End If blnHeader = False Loop '⑭現在開いているCSVファイルを閉じる Close #1 End If Next '⑮FileSystemObjectをクリアする Set fso = Nothing MsgBox "完了" End Sub |
最後にEXCELを「◯◯◯.xlsm」というような感じでマクロ有効ブック形式で保存します。
指定したフォルダに存在するCSVファイルを取り込みする機能の使い方
それでは、CSVファイルを取り込みする方法を説明します。
まず、A2セルにCSVファイルが存在するフォルダパスを入力します。
次に、取り込みするCSVファイルの設定をします。
「ヘッダー行の有無」には、「あり」・「なし」のどちらかを指定します。
ヘッダー行(1行目)がある場合は、「あり」を指定します。
ヘッダー行がない場合は、「なし」を指定します。
「文字くくりの形式」には、「なし」または実際のくくり文字を指定します。
例えば、ダブルコーテーション(”)でくくられている場合、「”」を指定します。
次に、「開発」タブの「マクロ」をクリックします。
先程作成した自作関数「Main_Proc」が一覧に表示されていますので、選択します。
次に、「実行」ボタンをクリックしてフォルダを作成します。
しばらく待つと、指定したフォルダ配下に存在する全CSVファイルが取り込まれ、データシートに出力されます。
ちなみに、実際のフォルダは以下のようになっています。
ちなみに、実際のCSVファイルの中身は以下のようになっています。
1行目にはヘッダー行があり、各データはダブルコーテーションでくくられています。
複数のCSVファイルを取り込みするVBAプログラム(Main_Proc)の説明
それでは、VBAプログラム(Main_Proc)を説明します。
①メインシートを変数に格納する
1 2 |
'①メインシートを変数に格納する Set shtMain = ThisWorkbook.Sheets("メイン") |
そうすることにより、入力するプログラムを短くすることができるからです。
何度も「ThisWorkbook.Sheets(“メイン”)」と入力するより、「shtMain」と入力するほうがコードが少なくてよいからです。
②データシートを変数に格納する
1 2 |
'②データシートを変数に格納する Set shtData = ThisWorkbook.Sheets("データ") |
取り込んだCSVデータを出力するときに、何度も使います。
③データシートをクリアする
1 2 |
'③データシートをクリアする shtData.Cells.Clear |
なぜなら、何度も繰り返し実行する場合、前に取り込んでいたCSVデータが残っていると、不都合が起きるからです。
手で毎回消すのも面倒なので、VBAプログラムで自動的に消しておきます。
④FileSystemObjectを変数に格納する
1 2 |
'④FileSystemObjectを変数に格納する Set fso = CreateObject("Scripting.FileSystemObject") |
「FileSystemObject」は、フォルダに存在するファイルを調べることに利用します。
⑤指定されているフォルダに存在するファイル数分処理を繰り返す
1 2 |
'⑤指定されているフォルダに存在するファイル数分処理を繰り返す For Each f In fso.GetFolder(shtMain.Range("A2")).Files |
⑥拡張子がcsvのファイルのみ対象とする
1 2 |
'⑥拡張子がcsvのファイルのみ対象とする If LCase(fso.getextensionName(f.Name)) = "csv" Then |
拡張子が「csv」のファイルのみを対象に、以降の処理を行います。
例えば、拡張子が「txt」や「xlsx」など、対象外となります。
⑦CSVファイルを開く
1 2 |
'⑦CSVファイルを開く Open shtMain.Range("A2") & "\" & f.Name For Input As #1 |
⑧CSVファイルの最終行まで繰り返す
1 2 |
'⑧CSVファイルの最終行まで繰り返す Do Until EOF(1) |
⑨1行分をbuf変数に取り込みする
1 2 |
'⑨1行分をbuf変数に取り込みする Line Input #1, buf |
⑩ファイルの1行目かつヘッダー行がありの場合は、取り込みをスキップする
1 2 |
'⑩ファイルの1行目かつヘッダー行がありの場合は、取り込みをスキップする If blnHeader = True And shtMain.Range("A5") = "あり" Then |
具体的には、ヘッダー行は取り込まないので、なにもしません。
⑪カンマ毎に区切って、値を配列に格納する
1 2 |
'⑪カンマ毎に区切って、値を配列に格納する var = Split(buf, ",") |
⑫配列の最終列まで繰り返す
1 2 |
'⑫配列の最終列まで繰り返す For i = 0 To UBound(var) |
⑬文字くくりの形式が”なし”ならそのままセルにセットする
1 2 3 4 5 6 7 |
'⑬文字くくりの形式が"なし"ならそのままセルにセットする '"なし"以外なら、B5に入力した値を除去してセルにセットする If shtMain.Range("B5") = "なし" Then shtData.Cells(nowRow, i + 1) = var(i) Else shtData.Cells(nowRow, i + 1) = Replace(var(i), shtMain.Range("B5"), "") End If |
「文字くくりの形式」で「なし」以外を指定されている場合、指定された値を取り除いて、セルに出力しています。
⑭現在開いているCSVファイルを閉じる
1 2 |
'⑭現在開いているCSVファイルを閉じる Close #1 |
⑮FileSystemObjectをクリアする
1 2 |
'⑮FileSystemObjectをクリアする Set fso = Nothing |
結果として、指定されたフォルダに存在するCSVファイル全てを、データシートに取り込みできるようになりました。
それでは、複数のCSVファイルを一気に取り込みするツールを作って、作業を効率化しましょう。
以上です。
最後まで読んでいただきありがとうございました。
この記事をシェアしていただけると喜びます。
お世話になっております。
大変参考にさせていただいております。
ヘッダー行がありの場合は1行飛ばして読み込む設定があるようですが、
2行飛ばして読み込む方法をご教示いただけないでしょうか。
ヘッダー行が2行ある場合、以下のコードを追加します。
Line Input #1, buf
具体的には、以下の場所にコードを追加します。
'⑩ファイルの1行目かつヘッダー行がありの場合は、取り込みをスキップする
If blnHeader = True And shtMain.Range("A5") = "あり" Then
'取り込みをスキップする
Line Input #1, buf '←追加した行
Else
ヘッダー行が3行ある場合、以下のコードを追加します。
'⑩ファイルの1行目かつヘッダー行がありの場合は、取り込みをスキップする
If blnHeader = True And shtMain.Range("A5") = "あり" Then
'取り込みをスキップする
Line Input #1, buf '←追加した行
Line Input #1, buf '←追加した行
Else
以上です。
>ヘッダー行が2行ある場合
ありがとうございました!できました。
(こんなに早く返信いただけるとは思っておらず、サイトの確認が遅れました)