毎日のCSV編集に10分以上ロスしてない!?VBAで一覧表を自動作成する方法とは

 

毎日CSVファイルを開いて、必要なデータだけを手作業でコピペして編集していませんか。

 

VBAを使えば、「CSVファイルを開く→必要なデータだけを取得する→一覧表に自動転記する」という一連の作業をボタン1クリックで処理することが可能です。

この記事では、CSVファイルからデータを取得して一覧表を自動作成するVBAを、実際のコードとともに紹介します。

毎日のCSV編集作業に時間をかけている方、不要データが混在したCSVの整形を手作業でこなしている方は、ぜひ最後まで読んでみてください。

 

広告

手作業のCSV編集が招く3つの問題点

CSVファイルを開いてデータを取得するという作業は、1回こなすだけなら大した手間ではありません。

しかし毎日のルーティーン作業として繰り返していると、気づかないうちに大きな時間ロスが積み重なっています。

手作業によるCSVデータの取り込みには、次の3つの問題が発生します。

 

問題①:開く・コピペ・閉じるの繰り返しに時間がかかる

CSVファイルを開き、必要な列を確認し、目的のデータをコピーして別のエクセルファイルに貼り付ける。

この作業を1件こなすだけなら数分で終わりますが、毎日・毎週これを繰り返すとなると話は別です。

ファイルの保存場所を毎回開く手間、複数のウィンドウを行き来する手間、間違えてコピペしたときに確認し直す手間。

こういった細かいロスが積み重なって、月に数時間という無駄な作業時間を生み出しています。

 

問題②:不要なデータが混在していて整形作業が発生する

システムから出力されるCSVファイルには、実際には使わない列が大量に含まれていることがほとんどです。

たとえば20列以上のデータが出力されているのに、実際に使うのは3列だけ、というケースは実務でよく発生します。

不要な列を削除して、必要な情報だけを残すという整形作業が毎回発生するため、コピペ以上の手間がかかります。

 

問題③:コピペミスによるデータの誤転記が起きやすい

手作業でデータをコピペしていると、行がひとつずれていたり、違う列の情報を貼り付けてしまったりというミスが発生します。

処理件数が増えるほどミスは起きやすくなり、そのミスを後から探すのにまた時間がかかる、という悪循環が生まれます。

VBAを使って自動化しておけば、毎回同じ処理が再現されるため、コピペミスは発生しません。

 

エクセル CSV取得 VBAの基本|CSVを開いてデータを取得する仕組みを理解する

CSVファイルからデータを取得するVBAを実装するには、まず「別のエクセルファイルをVBAで操作する」という基本的な考え方を押さえておく必要があります。

VBAでは、Workbooks.Openメソッドを使うことで、指定したパスのCSVファイルをプログラムから開き、データを取得することができます。

取得したデータを自分のエクセルファイルに転記したあとは、Closeメソッドで開いたCSVファイルを閉じるという流れです。

この一連の処理をVBAに組み込むことで、「CSVを開く→必要なデータを取得する→一覧表に転記する→CSVを閉じる」という作業がすべて自動化されます。

 

CSVファイルを開いてデータを取得する基本VBA

まずは最もシンプルなパターンとして、指定したCSVファイルを開き、A列・B列・C列のデータをそのまま自分のシートに転記するVBAを見てみましょう。

Sub CSVデータ取得_基本()

Dim 転記先シート As Worksheet
Dim CSVブック As Workbook
Dim CSVシート As Worksheet
Dim CSVパス As String
Dim 最終行 As Long
Dim i As Long

'--- 転記先のシートを設定 ---
Set 転記先シート = ThisWorkbook.Worksheets("一覧")

'--- 取り込むCSVファイルのパスを指定 ---
CSVパス = "C:\Users\Desktop\データ\売上データ.csv"

'--- CSVファイルを開く ---
Set CSVブック = Workbooks.Open(CSVパス)
Set CSVシート = CSVブック.Worksheets(1)

'--- CSVの最終行を取得 ---
最終行 = CSVシート.Cells(Rows.Count, 1).End(xlUp).Row

'--- 転記先シートの既存データをクリア ---
転記先シート.Rows("2:" & 転記先シート.Rows.Count).ClearContents

'--- CSVのデータを転記先シートに転記 ---
For i = 2 To 最終行
転記先シート.Cells(i, 1).Value = CSVシート.Cells(i, 1).Value
転記先シート.Cells(i, 2).Value = CSVシート.Cells(i, 2).Value
転記先シート.Cells(i, 3).Value = CSVシート.Cells(i, 3).Value
Next i

'--- CSVファイルを保存せずに閉じる ---
CSVブック.Close SaveChanges:=False

MsgBox "CSVデータの取り込みが完了しました。", vbInformation

End Sub

コードの流れを解説します。

 

Set 転記先シート = ThisWorkbook.Worksheets(“一覧")は、このVBAが書かれているエクセルファイル自体の「一覧」シートを転記先として指定しています。

CSVパスの変数にCSVファイルの保存場所をフルパスで指定します。

ここを変更するだけで、どのCSVファイルにも対応できます。

Workbooks.Open(CSVパス)で指定したCSVファイルを開き、CSVブックという変数に格納します。

最終行 = CSVシート.Cells(Rows.Count, 1).End(xlUp).RowでCSVファイルのデータが何行まであるかを自動的に取得しています。

データ件数が変わっても、このコードを使えば常に正確な範囲でループ処理が実行されます。

Forループで2行目から最終行まで1行ずつデータを転記したあと、CSVブック.Close SaveChanges:=FalseでCSVファイルを変更を保存せずに閉じます。

このSaveChanges:=Falseは非常に重要です。

これを省略すると「保存しますか?」というダイアログが表示されてしまい、自動処理が途中で止まってしまいます。

 

不要データを除いて必要な列だけを取り出すVBA

実務で扱うCSVファイルには、システムが自動出力した余分な列が大量に含まれていることが多くあります。

たとえば「日付・担当者コード・担当者名・部署コード・部署名・商品コード・商品名・単価・数量・売上金額・備考・更新日時」という12列が出力されているとして、一覧表に必要なのは

「日付」「担当者名」「商品名」「売上金額」の4列だけ、というケースは実務でよく発生します。

次のVBAは、CSVファイルのヘッダー行(1行目)を検索して列番号を特定し、必要な列のデータだけを取得するという実践的なコードです。

Sub CSVデータ取得_列指定()

Dim 転記先シート As Worksheet
Dim CSVブック As Workbook
Dim CSVシート As Worksheet
Dim CSVパス As String
Dim 最終列 As Long
Dim 最終行 As Long
Dim i As Long
Dim j As Long

'--- 取得したい列名と転記先列番号の対応 ---
Dim 取得列名(3) As String
Dim 取得列番号(3) As Long

取得列名(0) = "日付"
取得列名(1) = "担当者名"
取得列名(2) = "商品名"
取得列名(3) = "売上金額"

Set 転記先シート = ThisWorkbook.Worksheets("一覧")

CSVパス = Application.GetOpenFilename( _
FileFilter:="CSVファイル (*.csv),*.csv", _
Title:="取り込むCSVファイルを選択してください")

If CSVパス = "False" Then
MsgBox "キャンセルされました。", vbInformation
Exit Sub
End If

Set CSVブック = Workbooks.Open(CSVパス)
Set CSVシート = CSVブック.Worksheets(1)

最終列 = CSVシート.Cells(1, Columns.Count).End(xlToLeft).Column
最終行 = CSVシート.Cells(Rows.Count, 1).End(xlUp).Row

'--- ヘッダー行を検索して取得したい列番号を特定 ---
For j = 1 To 最終列
Dim ヘッダー名 As String
ヘッダー名 = CSVシート.Cells(1, j).Value
Dim k As Long
For k = 0 To 3
If ヘッダー名 = 取得列名(k) Then
取得列番号(k) = j
End If
Next k
Next j

'--- 必要な列が見つからない場合はエラーメッセージを表示 ---
For k = 0 To 3
If 取得列番号(k) = 0 Then
MsgBox "「" & 取得列名(k) & "」列が見つかりませんでした。" & _
"CSVのヘッダーを確認してください。", vbCritical
CSVブック.Close SaveChanges:=False
Exit Sub
End If
Next k

'--- 転記先シートのデータをクリア ---
転記先シート.Rows("2:" & 転記先シート.Rows.Count).ClearContents

'--- 必要な列のデータだけを転記 ---
For i = 2 To 最終行
転記先シート.Cells(i, 1).Value = CSVシート.Cells(i, 取得列番号(0)).Value
転記先シート.Cells(i, 2).Value = CSVシート.Cells(i, 取得列番号(1)).Value
転記先シート.Cells(i, 3).Value = CSVシート.Cells(i, 取得列番号(2)).Value
転記先シート.Cells(i, 4).Value = CSVシート.Cells(i, 取得列番号(3)).Value
Next i

CSVブック.Close SaveChanges:=False

MsgBox "必要なデータの取り込みが完了しました。", vbInformation

End Sub

コードの流れを解説します。

 

取得列名という配列に、取り込みたい列のヘッダー名を設定しています。

ここに書いた列名がCSVの1行目に存在するかどうかをFor jループで1列ずつ確認し、一致した列の番号を取得列番号配列に記録しています。

列番号が特定できたあとはFor iループで2行目から最終行まで処理し、CSVシート.Cells(i, 取得列番号(k)).Valueという書き方で列番号を動的に指定してデータを取得します。

このコードの最大のメリットは、CSVの列の並び順が変わってもヘッダー名さえ変わらなければ正しく動作するという点です。

システムのバージョンアップ等で列順が入れ替わっても、修正不要でそのまま使い続けられます。

必要な列が見つからなかった場合に警告メッセージを表示して処理を中断するエラーハンドリングも組み込んでいるため、誤ったデータが転記されるリスクもありません。

 

条件を指定して必要な行だけを抽出するVBA

CSVファイルから「すべての行ではなく、特定の条件に合う行だけを取り込みたい」というケースも実務では頻繁に発生します。

たとえば「売上金額が1万円以上の行だけを一覧表にしたい」「特定の担当者のデータだけを抽出したい」というような場合です。

次のVBAは、CSVから取り込む際に条件フィルタをかけて必要な行だけを転記するコードです。

Sub CSVデータ取得_条件抽出()

Dim 転記先シート As Worksheet
Dim CSVブック As Workbook
Dim CSVシート As Worksheet
Dim CSVパス As String
Dim 最終行 As Long
Dim i As Long
Dim 転記行 As Long
Dim 売上金額 As Long
Dim 抽出条件 As Long

Set 転記先シート = ThisWorkbook.Worksheets("一覧")

'--- 抽出する売上金額の下限値を設定 ---
抽出条件 = 10000

CSVパス = Application.GetOpenFilename( _
FileFilter:="CSVファイル (*.csv),*.csv", _
Title:="取り込むCSVファイルを選択してください")

If CSVパス = "False" Then Exit Sub

Set CSVブック = Workbooks.Open(CSVパス)
Set CSVシート = CSVブック.Worksheets(1)

最終行 = CSVシート.Cells(Rows.Count, 1).End(xlUp).Row

転記先シート.Rows("2:" & 転記先シート.Rows.Count).ClearContents

'--- 転記先の開始行は2行目から ---
転記行 = 2

For i = 2 To 最終行

'--- D列(売上金額)が抽出条件以上の行だけを転記 ---
売上金額 = CSVシート.Cells(i, 4).Value

If 売上金額 >= 抽出条件 Then
転記先シート.Cells(転記行, 1).Value = CSVシート.Cells(i, 1).Value
転記先シート.Cells(転記行, 2).Value = CSVシート.Cells(i, 2).Value
転記先シート.Cells(転記行, 3).Value = CSVシート.Cells(i, 3).Value
転記先シート.Cells(転記行, 4).Value = CSVシート.Cells(i, 4).Value
転記行 = 転記行 + 1
End If

Next i

CSVブック.Close SaveChanges:=False

MsgBox "条件に合うデータの取り込みが完了しました。" & vbCrLf & _
"抽出件数:" & (転記行 - 2) & "件", vbInformation

End Sub

コードの流れを解説します。

 

抽出条件 = 10000という変数で、取り込む下限値を設定しています。

条件を変えたいときは、この数字を変えるだけで対応できます。

For iループの中でCSVの各行を1行ずつ確認し、D列(売上金額)の値が抽出条件以上の場合だけ転記先シートに転記しています。

転記行という変数を用意しているのがポイントです。

CSVの行番号(i)と転記先の行番号(転記行)を分けて管理することで、条件に合わない行をスキップしながら転記先に隙間なくデータを詰めることができます。

処理完了後のメッセージには転記行 – 2で抽出件数を計算して表示しているため、何件のデータが取り込まれたかが一目でわかります。

関連記事「毎日のCSV取り込み作業、手作業で整形してませんか?VBAで一覧表を自動作成する方法」では、CSVを取り込んで一覧表を自動作成するVBAが設定されたエクセルファイルをダウ

ンロードすることができます。

 

VBAをボタンに登録してワンクリックで実行する

ここまで紹介したVBAは、エクセルシート上にボタンを配置してワンクリックで実行できるように設定することが可能です。

「開発」タブから「挿入」→「ボタン(フォームコントロール)」を選んでシート上にドラッグすると「マクロの登録」ダイアログが表示されます。

登録したいマクロ名を選択して「OK」をクリックするだけで設定は完了です。

ボタンを右クリックして「テキストの編集」を選べば「▶ CSV取り込み実行」のような説明文をボタン上に表示することもできます。

一度ボタンを設置しておけば、次回からはCSVファイルを選択してボタンを1回クリックするだけで、毎回同じ正確な処理が実行されます。

 

CSV取得VBAを使う際の注意点

CSV取得VBAを実装するにはいくつか押さえておきたい注意点があります。

これから紹介する注意点を把握しておかなければ、「処理が止まる」「文字化けする」「ファイルが閉じられない」という問題が起きることがあります。

 

CSVファイルは必ずCloseで閉じる

Workbooks.OpenでCSVファイルを開いたあとは、処理の最後に必ずCloseで閉じる処理を入れてください。

閉じる処理を忘れると、エクセルがバックグラウンドでCSVファイルを開いたままの状態になり、処理が重くなったり次回の処理でエラーが出たりします。

エラーが発生したときでもファイルが確実に閉じられるように、On Error GoToを使ったエラーハンドリングを実装するのが実務では理想的です。

 

CSVの文字コードがUTF-8の場合は文字化けに注意する

勤怠管理システムや販売管理システムによっては、CSVをUTF-8で出力するものがあります。

Workbooks.OpenでUTF-8のCSVをそのまま開くと文字化けが発生することがあります。

文字化けが起きる場合は、Workbooks.OpenTextメソッドを使って文字コードを明示的に指定することで解決できます。

'UTF-8のCSVを開く場合
Workbooks.OpenText Filename:=CSVパス, Origin:=65001

'Shift-JISのCSVを開く場合
Workbooks.OpenText Filename:=CSVパス, Origin:=932

Origin:=65001がUTF-8を指定するコードです。

Shift-JISであればOrigin:=932を指定します。

 

データの最終行は動的に取得する

コードの中で使っているCells(Rows.Count, 1).End(xlUp).Rowは、A列の最終行を自動的に取得する命令です。

CSVのデータ件数は毎回変わることがほとんどなので、このコードを使って動的に最終行を取得するようにしておきましょう。

固定値(例:1000行)で範囲を指定すると、データが少ないときは問題ないですが、件数がその固定値を超えたときに取り込めないデータが出てくるので注意が必要です。

 

まとめ ~ CSV取得VBAで毎日の手作業を自動化しよう ~

CSVファイルから必要なデータだけを取得して一覧表を自動作成するVBAは、毎日のルーティーン作業を大幅に効率化できる実用性の高いマクロです。

 

今回紹介した3つのパターンを整理すると、CSVを開いてそのまま転記する基本VBA、ヘッダー名で列を特定して必要な列だけを取り出す列指定VBA、条件フィルタをかけて必要な行だけを抽出する条件抽出VBAという流れです。

手作業で毎回10分以上かけていたCSV編集作業が、ボタン1クリックで完了するようになれば、その時間を本来の業務に使うことができます。

今回紹介したコードをベースに、自分の業務の流れや使用しているCSVの形式に合わせてカスタマイズしてみてください。

 

さらに詳しいCSV自動化の実例については、note記事「毎日のCSV取り込み作業、手作業で整形してませんか?VBAで一覧表を自動作成する方法」もあわせて参考にしてみてください。

 

もし「自分の業務に合わせた複雑なチェック処理を実装したい」「既存のマクロを改良したい」といったご要望がありましたら、マメBlogのエクセルマクロ開発依頼にご相談ください。

業務内容に合わせたオーダーメイドマクロを設定させていただきます。

 

最後まで読んでいただきありがとうございました。

エクセルVBAを使って面倒なルーティーン作業を自動化しちゃいましょう。