Excel VBAを使って、CSVファイルをExcelに取り込むときに、不要な列だけを除外する方法を紹介します。
今回は、ユーザーが「1,3,5」のように除外したい列番号を指定し、その列をスキップして、残りの列だけをExcelシートへ転記します。
毎回CSVを開いて不要な列を削除している場合や、取り込む列をユーザー側で簡単に変更したい場合に便利です。
このマクロでできること
このマクロでは、CSVファイルを1行ずつ読み込み、指定した列だけを除外してExcelに取り込みます。
たとえば、CSVに次のような列があるとします。
1列目:ID
2列目:名前
3列目:部署
4列目:住所
5列目:電話番号
このうち、1列目と5列目を除外したい場合は、ExcelのA1セルに次のように入力します。
1,5
すると、1列目と5列目をスキップし、2列目・3列目・4列目だけをExcelに取り込みます。
このマクロで行う処理
- ユーザーが除外したい列番号を入力する。
- 入力された列番号をVBA内で使いやすい形に変換する。
- CSVファイルを1行ずつ読み込む。
Split関数で1行をカンマ区切りに分割する。- 指定された列番号に該当する列をスキップする。
- 残りの列だけをExcelシートへ書き込む。
このサンプルでは
Split 関数でCSVを分割しています。そのため、セル内にカンマが含まれるCSVや、ダブルクォーテーションで囲まれた複雑なCSVには対応していません。
単純なカンマ区切りCSVを想定したサンプルです。
除外する列番号をA1セルに入力する
今回は、除外したい列番号を A1 セルに入力する形にします。
たとえば、1列目・3列目・5列目を除外したい場合は、A1 セルに次のように入力します。
1,3,5
VBAの配列は0から始まるため、ユーザーが入力した「1列目」は、VBA上では「0番目」として扱います。
| Excel上の列番号 | VBA配列の番号 |
|---|---|
| 1列目 | 0 |
| 2列目 | 1 |
| 3列目 | 2 |
そのため、コード内では入力された列番号から1を引いて、VBAで扱える番号に変換しています。
マクロの例
以下が、指定した不要列を除外してCSVを取り込むマクロです。
今回は A1 セルを設定用に使うため、CSVデータは 3行目 から書き込むようにしています。
Sub ImportCsvExcludeColumnsFromCell()
'===【設定項目】=======================================
Dim csvFilePath As String
csvFilePath = "C:\temp\sample.csv" ' CSVファイルのパスを指定
Dim delimiter As String
delimiter = "," ' CSVの区切り文字
Dim wsDest As Worksheet
Set wsDest = ThisWorkbook.Worksheets("Sheet1") ' 取り込み先シート
Dim startRow As Long: startRow = 3 ' A1を設定用に使うため、3行目から書き込み
Dim startCol As Long: startCol = 1
'===================================================
Dim excludeColumnsString As String
Dim excludeCols() As Long
Dim fileNo As Integer
Dim textLine As String
Dim spl() As String
Dim currentRow As Long
Dim writeCol As Long
Dim colIndex As Long
Dim fileOpened As Boolean
On Error GoTo ErrHandler
' A1セルから除外列番号を取得
excludeColumnsString = Trim(wsDest.Range("A1").Value)
If Len(excludeColumnsString) = 0 Then
MsgBox "A1セルに除外したい列番号を入力してください。" & vbCrLf & _
"例:1,3,5", vbExclamation
Exit Sub
End If
' ユーザー入力の列番号をVBA用の0-based配列に変換
excludeCols = ConvertCommaStringToArray(excludeColumnsString, True)
' 必要に応じて、前回の取り込み結果をクリア
wsDest.Rows(startRow & ":" & wsDest.Rows.Count).ClearContents
' CSVファイルを開く
fileNo = FreeFile
Open csvFilePath For Input As #fileNo
fileOpened = True
currentRow = startRow
' CSVを1行ずつ読み込み
Do Until EOF(fileNo)
Line Input #fileNo, textLine
' 空行はスキップ
If Len(Trim(textLine)) > 0 Then
' 1行を区切り文字で分割
spl = Split(textLine, delimiter)
writeCol = startCol
' 各列を確認
For colIndex = LBound(spl) To UBound(spl)
' 除外列に含まれていなければ書き込む
If Not IsInLongArray(colIndex, excludeCols) Then
wsDest.Cells(currentRow, writeCol).Value = spl(colIndex)
writeCol = writeCol + 1
End If
Next colIndex
currentRow = currentRow + 1
End If
Loop
Close #fileNo
fileOpened = False
MsgBox "CSVの取り込みが完了しました。", vbInformation
Exit Sub
ErrHandler:
If fileOpened Then
Close #fileNo
End If
MsgBox "エラーが発生しました:" & Err.Description, vbExclamation
End Sub
補助関数①:カンマ区切りの文字列を配列に変換する
次の関数では、A1 セルに入力された 1,3,5 のような文字列を、VBAで扱いやすい配列に変換します。
また、数値以外が入力された場合はエラーを表示できるようにしています。
Private Function ConvertCommaStringToArray(str As String, isUser1Based As Boolean) As Long()
Dim tmp As Variant
Dim result() As Long
Dim i As Long
Dim valueText As String
Dim valueNum As Long
tmp = Split(str, ",")
ReDim result(LBound(tmp) To UBound(tmp))
For i = LBound(tmp) To UBound(tmp)
valueText = Trim(CStr(tmp(i)))
If Not IsNumeric(valueText) Then
Err.Raise vbObjectError + 1000, , "列番号には数値を入力してください。"
End If
valueNum = CLng(valueText)
If isUser1Based Then
valueNum = valueNum - 1
End If
If valueNum < 0 Then
Err.Raise vbObjectError + 1001, , "列番号は1以上で入力してください。"
End If
result(i) = valueNum
Next i
ConvertCommaStringToArray = result
End Function
補助関数②:指定した列番号が除外対象か判定する
次の関数では、現在の列番号が除外対象に含まれているかを判定します。
除外対象に含まれている場合は True、含まれていない場合は False を返します。
Private Function IsInLongArray(ByVal targetValue As Long, ByRef arr() As Long) As Boolean
Dim i As Long
For i = LBound(arr) To UBound(arr)
If arr(i) = targetValue Then
IsInLongArray = True
Exit Function
End If
Next i
IsInLongArray = False
End Function
InputBoxで除外列を指定する場合
A1セルではなく、マクロ実行時に表示される入力画面で除外列を指定したい場合は、InputBox を使う方法もあります。
次のように変更すると、マクロ実行時に除外したい列番号を入力できます。
excludeColumnsString = InputBox( _
Prompt:="除外したい列番号をカンマ区切りで入力してください。" & vbCrLf & "例:1,3,5", _
Title:="除外列の指定", _
Default:="1,3,5" _
)
A1セルから取得している次の部分を、
excludeColumnsString = Trim(wsDest.Range("A1").Value)
上記の InputBox に差し替えることで、毎回ユーザーが除外列を指定できるようになります。
カスタマイズのポイント
CSVファイルのパスを変更したい場合
CSVファイルのパスは、次の部分で指定しています。
csvFilePath = "C:\temp\sample.csv"
実際に取り込みたいCSVファイルの場所に合わせて変更してください。
取り込み先シートを変更したい場合
取り込み先シートは、次の部分で指定しています。
Set wsDest = ThisWorkbook.Worksheets("Sheet1")
別のシートへ取り込みたい場合は、シート名を変更してください。
書き込み開始行を変更したい場合
今回のコードでは、A1セルを設定用に使うため、CSVデータは3行目から書き込むようにしています。
Dim startRow As Long: startRow = 3
1行目から書き込みたい場合は、A1セル以外に設定値を置くか、InputBox方式に変更してください。
よくあるエラーと対処法
| エラー・症状 | 原因 | 対処法 |
|---|---|---|
| 列番号には数値を入力してください | A1セルに文字や全角カンマなどが入っている | 1,3,5 のように半角数字と半角カンマで入力する |
| 列番号は1以上で入力してください | 0以下の数字が入力されている | Excel上の列番号として1以上の数字を入力する |
| CSVファイルが開けない | CSVファイルのパスが間違っている | csvFilePath のパスを確認する |
| 列がずれて取り込まれる | CSV内の値にカンマが含まれている | 単純なCSVか確認する。複雑なCSVの場合は別の読み込み方法を検討する |
まとめ
Excel VBAを使うと、CSVファイルから不要な列を除外して、必要な列だけをExcelに取り込むことができます。
今回の方法では、ユーザーが 1,3,5 のように除外したい列番号を指定できるため、CSVの形式が少し変わっても柔軟に対応できます。
ただし、Split 関数を使ったシンプルなサンプルのため、セル内にカンマが含まれるCSVや、ダブルクォーテーションで囲まれた複雑なCSVには注意が必要です。


コメント