PR

Excel VBA|ユーザーが指定した不要列を除外してCSVを取り込む方法

スポンサーリンク
この記事は約12分で読めます。

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に取り込みます。

このマクロで行う処理

  1. ユーザーが除外したい列番号を入力する。
  2. 入力された列番号をVBA内で使いやすい形に変換する。
  3. CSVファイルを1行ずつ読み込む。
  4. Split 関数で1行をカンマ区切りに分割する。
  5. 指定された列番号に該当する列をスキップする。
  6. 残りの列だけを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には注意が必要です。

にほんブログ村 IT技術ブログ IT技術メモへ

コメント

タイトルとURLをコピーしました