【VBAでCSV読込み】VBAでCSVを正確・高速に読み込む方法【コピペでOK】
今回は、Excel VBAを使ってCSVファイルを「正確に」かつ「高速に」読み込む方法をシェアします。
まず、Excel VBA は Javaに代表されるプログラム言語と違い、CSVを読み込むためのライブラリがありません。
なので、自力で読み込む必要があります。
しかし、CSVを読み込む処理を自力で実装することはオススメしません。
それは以下2点の理由からです。
- CSVには色々なタイプがあること(例えば、タブ区切りのCSVやカンマ区切りのCSV)
- エスケープ文字や改行コードの混入などに備え、CSVの仕様を全て理解する必要があること
そこで、今回はExcel自体の機能を使用してCSVを読み込む方法を採用します。
今回は、Excel自体の機能を使用して最も高速に読み込む方法をシェアします。
ソースコード
まずはソースコードを以下にシェアします。
1 2 3 4 5 6 |
Option Explicit ' CSVデータ1件分の情報を格納するクラス Public Code As String Public Name As String |
上記は、CSVデータ1行分のデータを格納するクラスです。
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 83 84 85 86 87 88 89 90 91 |
Option Explicit ' テスト実行用プロシージャ Public Sub Main() ' 変数宣言 Dim fso As Scripting.FileSystemObject Dim csvFile As Scripting.File Dim filePath As String Dim csvDatas As Collection ' 変数宣言(処理時間計測用) Dim startTime As Single ' ファイルシステムオブジェクトを取得 Set fso = New Scripting.FileSystemObject ' 開きたいCSVファイルパスを取得 filePath = InputBox(Prompt:="読み込むCSVファイルパスを入力してください") ' CSVファイルパスが入力されていない場合は処理終了 If filePath = "" Then MsgBox "CSVファイルが入力されていません。" & vbLf & "CSVファイルパスを入力してください。", vbExclamation + vbOKOnly, "エラー" Exit Sub End If ' ファイルが存在しなかった場合は処理終了 If Not fso.FileExists(filePath) Then MsgBox "CSVファイルが存在しません。" & vbLf & "存在するCSVファイルパスを指定してください。", vbExclamation + vbOKOnly, "エラー" Exit Sub End If ' 開きたいCSVファイルを取得 Set csvFile = fso.GetFile(filePath) ' 処理開始日時を取得 startTime = Timer() ' CSVデータを取得 Set csvDatas = ReadCsv(csvFile, True) ' 処理時間を出力 Debug.Print "処理時間 : " & Format((Timer() - startTime), "0.00") & " 秒" End Sub ' CSVファイルを読み込む ' 第二引数はCSVファイルにヘッダーがある場合Trueを、そうでない場合はFalseを設定する Public Function ReadCsv(ByRef csvFile As Scripting.File, ByRef hasHeader As Boolean) As Collection ' 変数宣言 Dim csvBook As Workbook Dim mCsvDatas As Collection Dim mCsvData As CsvData Dim cells As Variant Dim i As Long ' CSVファイルを開く Set csvBook = Workbooks.Open(Filename:=csvFile.Path, ReadOnly:=True) ' CSVデータを二次元配列に格納 With csvBook.Worksheets(1) cells = .Range(.cells(1, 1), .UsedRange.cells(.UsedRange.cells.Count)) End With ' CSVファイルは保存せず閉じる csvBook.Close SaveChanges:=False ' 結果返却オブジェクトを初期化 Set mCsvDatas = New Collection ' 全CSVデータを走査(ヘッダー行が存在する場合は2行目から読み込み) For i = LBound(cells, 1) + IIf(hasHeader, 1, 0) To UBound(cells, 1) ' CSVデータ1件分を格納するオブジェクトを初期化 Set mCsvData = New CsvData ' CSVデータをオブジェクトに設定 mCsvData.Code = cells(i, 1) mCsvData.Name = cells(i, 2) ' CSVデータをオブジェクトに追加 mCsvDatas.Add mCsvData Next ' 結果返却 Set ReadCsv = mCsvDatas End Function |
上記は、実際にCSVを読み込んで結果をCollectionオブジェクトに設定して返却する処理です。
上記で登場する Scripting.FileSystemObject を使用するためには、
「参照設定」という作業が必要になります。
この作業方法については、ここ で方法をシェアしています。(非常に簡単です)
上記の方法で1万行のCSVファイルを読み込んだ際のベンチマークを以下に記載します。
回目 | 処理時間 |
1回目 | 0.57秒 |
2回目 | 0.55秒 |
3回目 | 0.55秒 |
平均: | 0.55秒 |
平均で0.55秒で読み込むことができました。
CSVの形式やエスケープ文字など、実装が大変な部分を回避しつつ、
高速に読み込むことができたと思います。
まとめ
今回は、Excel VBAで高速にCSVファイルを読み込む方法をシェアしました。
Excel VBAについて他にもこんな処理はどうやるの?などの質問がある場合は、
フォームからご連絡頂けたら幸いです。
記事にして共有させて頂きます。