エクセルVBA　csvファイル出力　メモ

# はじめに
メモ用程度のため、まとまりなし。

# csvファイル読み込み（文字コード変換前）

下記処理だと、ファイル自体は読み込むことが出来るがUTF-8のcsvファイルは文字化けしてしまう。
というのもExcelでは、初期設定でShift_JISという文字コードで開いてしまうからである。

```
Sub openCsv()
    Dim filePath As String
    Dim intFree As Integer 'ファイル番号用変数
    intFree = FreeFile '空番号を取得
    
    filePath = Cells(5, 5)
    
    Open filePath For Input As #intFree 'csvファイルを読み込み　Open ファイルパス For 目的 As #番号
    
    Dim i As Long
    Dim j As Long
    Dim strLine As String '各行のデータを格納するための変数
    Dim strSplit() As String '配列を宣言する場合は（）をつける。配列の要素数が決まっている場合は（）に数字を指定する　ただし要素数-1
    
    i = 0
    'Do Until 条件式　で条件式が成り立つまで処理を繰り返す。EOF(intFree)は、intFreeの番号のファイルの読み取りポイントがEnd Of FIle（終端）までということ
    Do Until EOF(intFree)
        Line Input #intFree, strLine 'Line Input #番号,変数　でOpenで開いた指定番号のファイルから一行読み取り変数に格納する
        i = i + 1
        strSplit = Split(strLine, ",") 'カンマ区切りで配列に格納
        For j = 0 To UBound(strSplit)
            Debug.Print strSplit(j)
            Cells(i, j + 1) = strSplit(j)
        Next
    Loop
    
    Close #intFree
End Sub
```

そのため、UTF-8でファイルを読み込むための処理を追加する必要がある。

#CSVファイル（UTF-8）を読み込む
※VBA初のためとりあえずたくさんコメントあり

```
Sub openCsv()
    Dim i As Long
    Dim j As Long
    Dim strList As String 'ファイルから取得した行データを格納する変数
    Dim strSplit() As String
    
    Dim adoSt As New ADODB.Stream 'ADODB.Stream型？の変数を宣言　参照設定でのADO使用
    i = 1
    
    'Withは主語（今回であればadoSt）を省略する際に使うステートメント
    With adoSt
        .Type = adTypeText 'Streamオブジェクト内のデータ型の設定　今回はテキスト型を指定
        .Charset = "UTF-8" '文字コードを設定
        .Open 'Streamオブジェクトを開く
        .LoadFromFile ("ファイルパス") '指定のファイルを読み込む（日本語のディレクトリだとエラーが出る）
        
        Do While Not (.EOS) 'EOSプロパティは、Streamオブジェクトの現在位置が末尾かどうか確認する。末尾であればTrue。While Notは条件式がFalseの間処理を繰り返す
            strList = .ReadText(adReadLine) 'データを読み取る
            strSplit = Split(strList, ",") '読み取ったデータをカンマ区切りで分けて配列に格納する
            For j = LBound(strSplit) To UBound(strSplit) 'LBoundは指定配列の最小の添え字を取得　UBoundは指定配列の最大の添え字を取得
                Cells(i, j + 1) = strSplit(j)
            Next
            i = i + 1 '行の更新処理
        Loop
        .Close 'Streamオブジェクトを閉める
    End With
End Sub
```

下記サイトがとても参考になった
[テキストファイル（UTF-8）を読み込み、書き出し（ADODB.Stream）](https://excelwork.info/excel/adodbstream/)


# ファイルパス取得（おまけ）

```
Sub getFilePath()
    Dim filePath As Variant
    
    filePath = Application.GetOpenFilename()
    
    Cells(1, 1) = filePath
End Sub
```

上記処理は、[ファイルを開く]ダイアログボックスを表示して、ユーザーにファイルを選択してもらいそのファイルパスを取得する。

[ファイルを開く]ダイアログボックスを使用するには、ApplicationオブジェクトのgetOpenFilenameメソッドを使用する。

しかし、この処理だとファイルを選択しなかった場合セルに「False」と入ってしまう。
そこで、ファイルを選択しなかった場合は処理を中断するように修正したい。また、今回はcsvファイルのパスを取得したいため、選択肢をcsv形式のファイルのみに絞りたい。これらの点を改善した処理が以下のものである。

```
Sub getFilePath()
    Dim filePath As Variant
    
    '取得ファイルパスはcsvファイルとする
    filePath = Application.GetOpenFilename("CSVファイル(*.csv),*.csv")
    
    'ファイルを選択せずFalseの場合、プロシージャを終了させる
    If filePath = False Then
        Exit Sub
    End If
    
    Cells(1, 1) = filePath
    
End Sub
```

変更点は以下の通り。

***選択ファイル形式をcsvファイルとする***
GetOpenFilename()の第一引数で、ファイルの候補を指定する文字列「CSVファイル(*.csv),*.csv」を記載することで指定することが出来る。

***プロシージャの中断処理***
ファイルを選択しなかった場合、filePath変数にFalseが格納される。
その場合、Exit SubでgetFilePathプロシージャを中断する。ファイルが選択された場合はセルにファイルパスを表示させる。


# 参考
[第74回.ファイルを開くダイアログ（GetOpenFilename）](https://excel-ubara.com/excelvba1/EXCELVBA374.html)
[CSVの読み込み方法](https://excel-ubara.com/excelvba5/EXCEL111.html)
[UTF-8でCSVの読み書き（ADODB.Stream）](https://excel-ubara.com/excelvba5/EXCEL220.html)
[第12回.変数宣言のDimとデータ型](https://excel-ubara.com/excelvba1/EXCELVBA312.html)
[FreeFile](http://officetanaka.net/excel/vba/function/FreeFile.htm)
[Split関数で文字列を区切る](http://officetanaka.net/excel/vba/tips/tips62.htm)
[テキストファイル（UTF-8）を読み込み、書き出し（ADODB.Stream）](https://excelwork.info/excel/adodbstream/)
[LBound](http://officetanaka.net/excel/vba/function/LBound.htm)
[UBound](http://officetanaka.net/excel/vba/function/UBound.htm)