エクセル「UTF-8のcsvなんかに絶対負けたりしないっ！」

# うっ…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/526228cd-28a5-bb53-3f7c-382739233204.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/12cc8134-7230-8842-b0c2-22b5a60f3314.png)

# た、たまたま調子が悪かっただけよ！

『テキストまたはCSVから』を使えば、あんたなんか…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ccbb6a2e-b021-7b06-46bd-cbb6530df504.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4d5b41c0-ced4-8df3-0476-b2cef1b7004c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/861a37c8-d836-ce32-caa7-c7c65763f7e5.png)
ほら、この通り！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/770e013e-4b46-3fa9-0ffc-df35940f5bd7.png)
自動でフィルターが付いて、さらに1行ずつ色分けまでしちゃうんだから！
まいったか！

# さらに使いやすくしちゃうんだからっ！

『エンコード』と『ヘッダー行有無』を選んで…

ボタン押して…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/dd4af9ab-7bc8-96a6-69f1-f5b7635ee54c.png)
ファイル選択するだけで…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cd03000f-0b4f-2b35-1e23-a605a86967da.png)
ほら、この通りっ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/48e68fa9-30f3-08ff-0399-dc0ed29fcaa4.png)
『取込日時』と『どのファイルの内容か』まで後から確認できるんだからっ！

改行があったって…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1c4ffc01-d59d-b51d-1cce-dd63f140e721.png)

ちゃんと取り込むんだからっ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7710d906-17be-5b3d-824a-ecd658819045.png)

先頭に0が付いてる奴でも…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ba4f86bf-4994-494b-598e-1c57cb938612.png)

勝手に数字に変換せずに、そのまま取り込むんだからっ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7c88297f-1973-09fc-e209-e2ccc7203e52.png)


# ソースコード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/81767cf7-d42d-33d1-43c8-bc12fb9074c5.png)


```vb:『csv選択して読込』のボタン押した時に呼び出してる関数
Option Explicit


'=======================================================================================================================
'外部csvを見やすい形でエクセルに取込
'=======================================================================================================================
Public Sub InputFromCsv()

    
    '---------------------------------------------------------------------------------------------
    Dim file_path_ As String
    Dim query_name_ As String
    Dim encoding_ As Long
    Dim is_header_exist_ As Boolean
    
    
    '---------------------------------------------------------------------------------------------
    '■csvのエンコーディング
    'csvファイルから動的にエンコードを判別するのが難しかったので作らなかった。
    '『ユーザー側で指定してもらう』でもさほど不便ではないのでこれでよし。
    Select Case Range("B2").Value
        Case "UTF-8"
            encoding_ = 65001
        Case "SJIS"
            encoding_ = 932
        Case Else
            MsgBox "エンコーディングが分からない！", vbExclamation, "エラー"
            Exit Sub
    End Select
    
    
    '---------------------------------------------------------------------------------------------
    '■ヘッダー行有無
    '『ファイル内容からヘッダー行有無を動的に判定』は難しいので無し。
    '『ユーザー側で指定してもらう』でもさほど不便ではないのでこれでよし。
    Select Case Range("B3").Value
        Case "あり"
            is_header_exist_ = True
        Case "無し"
            is_header_exist_ = False
        Case Else
            MsgBox "ヘッダー有無が分からない！", vbExclamation, "エラー"
            Exit Sub
    End Select
    
    
    '---------------------------------------------------------------------------------------------
    '■ファイル選択
    With Application.FileDialog(msoFileDialogOpen)
        .Title = "csv選択"
        .Filters.Clear
        .Filters.Add "csvファイル", "*.csv"
        .FilterIndex = 1
        .AllowMultiSelect = False '1ファイルのみ。
        .InitialFileName = ThisWorkbook.Path '初期フォルダーはエクセルが置いてあるフォルダー。
        If .Show <> 0 Then
            file_path_ = Trim(.SelectedItems.Item(1))
        Else
            Exit Sub
        End If
    End With

    
    '---------------------------------------------------------------------------------------------
    '■読み込みバッチ識別用タイムスタンプとクエリ名
    Dim input_datetime_ As String
    input_datetime_ = Format(Now(), "yyyymmdd_hhnnss")
    
    query_name_ = "q_" & input_datetime_
    

    '---------------------------------------------------------------------------------------------
    '■csv読み込み定義作成
    
    'すっごい読みずらいけど、csvの中身確認用のプチツールだからこれでよし。
    
    Dim formula_ As String
    
    formula_ = ""
    formula_ = formula_ & "let "
    formula_ = formula_ & vbCrLf
    
    formula_ = formula_ & "    DataSource = "
    formula_ = formula_ & "Csv.Document( "
        formula_ = formula_ & "File.Contents( "
            formula_ = formula_ & """" & file_path_ & """ "
        formula_ = formula_ & "), "
        
        '『QuoteStyle.Csv』にすることで、改行を含む値があっても行ずれせずに取り込める。
        'また『QuoteStyle.csv』だと例外。『QuoteStyle.Csv』と指定する必要あり。（大文字小文字の区別あり）
        formula_ = formula_ & "[Delimiter="","", Encoding=" & encoding_ & ", QuoteStyle=QuoteStyle.Csv] "
        
    formula_ = formula_ & ") "
    
    If is_header_exist_ Then
    
        formula_ = formula_ & ", "
        formula_ = formula_ & vbCrLf
        
        formula_ = formula_ & "    ChangeType = "
        formula_ = formula_ & "Table.TransformColumnTypes( "
            formula_ = formula_ & "Table.PromoteHeaders(DataSource, [PromoteAllScalars=true]), {} "
        formula_ = formula_ & ") "
        formula_ = formula_ & vbCrLf
        
        formula_ = formula_ & "in "
        formula_ = formula_ & vbCrLf
        formula_ = formula_ & "    ChangeType"
    
    Else
    
        formula_ = formula_ & "in "
        formula_ = formula_ & vbCrLf
        formula_ = formula_ & "    DataSource"
    
    End If
    
    'Debug.Print formula_
    
    ActiveWorkbook.Queries.Add Name:=query_name_, Formula:=formula_
    
    
    '---------------------------------------------------------------------------------------------
    '■csv読込先シート追加
    ActiveWorkbook.Worksheets.Add
    ActiveSheet.Name = input_datetime_ 'シート名で『いつ取り込んだのか』が分かるように。
    
    
    '---------------------------------------------------------------------------------------------
    '■csv読み込み
    With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & query_name_ & ";Extended Properties=""""" _
        , Destination:=Range("$A$1")).QueryTable
        
        .CommandType = xlCmdSql
        .CommandText = Array("SELECT * FROM [" & query_name_ & "]")
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = True
        
        'DisplayNameは『20220101_1100』のような値を設定しようとすると例外になるので、プレフィックス付ける。
        .ListObject.DisplayName = "csv_" & input_datetime_
        
        .Refresh BackgroundQuery:=False
        
    End With
    
    
    '---------------------------------------------------------------------------------------------
    '■1行追加してファイル名
    '『どのファイルから読み込んだのか』が後で分かるように。
    ActiveSheet.Rows(1).Insert
    ActiveSheet.Range("A1").Value = file_path_
    
    
    '---------------------------------------------------------------------------------------------
    MsgBox "処理が終了しました。", vbInformation, "通知"

    
    
End Sub
```


# 参考サイトさん

https://www.tekizai.net/entry/2021/09/17/063000

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311
Microsoft Excel for Microsoft 365 MSO (バージョン 2210 ビルド 16.0.15726.20188) 32 ビット