【VBS】CSVを2次元配列に読み込んでCSVに書き出し

```vb:main.vbs
'他のスクリプトの関数を実行する
'関数を呼び出す側「a.vbs」

'Option Explicit

Dim objPB, objFso
Dim arr(), row_arr()
Dim i

Set objFso = Wscript.CreateObject("Scripting.FileSystemObject")
Execute objFso.OpenTextFile("CsvToArray.vbs", 1).ReadAll()
Execute objFso.OpenTextFile("FProgressBar.vbs", 1).ReadAll()

WScript.Echo "sample.vbs Start"

Set objPB = new ProgressBar
objPB.SetTitle "実行中"

For i = 0 To 1
    objPB.SetProgress i / 2        ' 実行数／全体数  （1.00で全部終了）
    CsvToArray "C:\Users\take2\Desktop\study\VBA\test.csv", arr
Next

set f = objFso.OpenTextFile("test.csv", 8, True)

Redim row_arr(UBound(arr,2)) '1行分取得用配列(列数にRedim)
For r_i = 0 To UBound(arr, 1) '行数繰り返し
    For c_i = 0 To UBound(arr, 2) '列数繰り返し
        row_arr(c_i) = arr(r_i, c_i) '1行分取得
    Next
    f.Writeline(Join(row_arr, ",")) 'カンマ区切りで1行書き出し
Next

Set objPB = Nothing
Set objFso = Nothing
WScript.Echo "sample.vbs End"
WScript.Quit(0)
```

```vb:FProgressBar.vbs
'-------------------------------------------------------------------------------
' ProgressBar : 進捗バークラス
'-------------------------------------------------------------------------------
Const WIDTH = 400
Const HEIGHT = 150
Const BAR_WIDTH = 350
Const BAR_HEIGHT = 16
Const BAR_BG = "#C0C0C0"
Const BAR_FG = "#0066FF"

Class ProgressBar

    '----------------------------------------------------
    ' クラス変数定義
    '----------------------------------------------------
    Private strTitle1
    Private nCurrent1
    Private nStartTime, nCurrentTime
    Private objIE
    Private div1, div2, div3

    '----------------------------------------------------
    ' コンストラクタ
    '----------------------------------------------------
    Private Sub Class_Initialize
        Set objIE = CreateObject("InternetExplorer.Application")
        objIE.Visible = False
        objIE.Navigate2 "about:blank"
        objIE.Document.Title = "進捗状況"
        objIE.AddressBar = False
        objIE.MenuBar = False
        objIE.ToolBar = False
        objIE.Resizable = False
        objIE.Width = WIDTH
        objIE.Height = HEIGHT
        objIE.Top = 0
        objIE.Left = 0
        Set div1 = objIE.Document.CreateElement("div")
        div1.Id = "div1"
        div1.style.position = "absolute"
        div1.style.top = "10px"
        div1.style.left = "10px"
        div1.style.backgroundColor = BAR_BG
        div1.style.width = BAR_WIDTH & "px"
        div1.style.height = BAR_HEIGHT & "px"
        div1.style.border = "1px solid"
        div1.style.overflow = "hidden"
        Set div2 = objIE.Document.CreateElement("div")
        div2.Id = "div2"
        div2.style.position = "relative"
        div2.style.top = "1px"
        div2.style.left = "1px"
        div2.style.backgroundColor = BAR_FG
        div2.style.width = "0px"
        div2.style.height = (BAR_HEIGHT - 2) & "px"
        div2.style.overflow = "hidden"
        Set div3 = objIE.Document.CreateElement("div")
        div3.Id = "div3"
        div3.style.position = "absolute"
        div3.style.top = "45px"
        div3.style.left = "10px"

        objIE.Document.Body.AppendChild(div1)
        div1.AppendChild(div2)
        objIE.Document.Body.AppendChild(div3)

        nStartTime = Timer()
    End Sub

    '----------------------------------------------------
    ' デストラクタ
    '----------------------------------------------------
    Private Sub Class_Terminate
        on error resume next
        objIE.Quit
        Set objIE = Nothing
        on error goto 0
    End Sub

    '----------------------------------------------------
    ' 表示タイトルの設定
    '----------------------------------------------------
    Public Sub SetTitle (t)
        strTitle1 = t
        objIE.Document.Title = t & String(40, "　")
        objIE.Visible = True
    End Sub

    '----------------------------------------------------
    ' 進捗パーセントの設定
    '----------------------------------------------------
    Public Sub SetProgress(n1)
        nCurrent1 = n1
        Repaint
    End Sub

    '----------------------------------------------------
    ' 進捗バー再描画
    '----------------------------------------------------
    Private Sub Repaint

    Dim nAverage
    Dim nElapsedTime
    Dim nRemain
    Dim strRemain
    Dim strPercent

    Dim w1
    Dim style1, style2

        nCurrentTime = Timer()
        nElapsedTime = nCurrentTime - nStartTime

        w1 = BAR_WIDTH * (nCurrent1)
        strRemain = "不明"
        If nElapsedTime <> 0 Then
            nAverage = nCurrent1 / nElapsedTime
            If nAverage <> 0 Then
                nRemain = Round((1 - nCurrent1) / nAverage, 1)
            End If
            If nRemain > 60 Then
                strRemain = "約" & CStr(Round(nRemain / 60, 0)) & "分"
            Else
                strRemain = FormatNumber(nRemain, 1) & "秒"
            End If
        End If

        strPercent = FormatNumber(nCurrent1 * 100, 1)

        on error resume next
        div2.style.width = (w1 -1) & "px"
        div3.innerText = strPercent & "%終了　--　残り推定：" & strRemain
        objIE.Visible = True
        objIE.Document.all(0).Click
        on error goto 0
    End Sub
End Class
```

```vb:CsvToArray.vbs
Function CsvToArray (a_sFilePath, a_sArLine())
    Dim oFS                         '// FileSystemObjectインスタンス
    Dim oTS                         '// TextStream変数
    Dim sLine                       '// CSVファイルの行文字列
    Dim iLineCount                  '// CSVファイル行数
    Dim iCommaCount                 '// カンマ数
    Dim v                           '// カンマ分割後の配列
    Dim i                           '// ループカウンタ
    Dim iColumn
    
    Set oFS = CreateObject("Scripting.FileSystemObject")

    '// TextStreamオブジェクト作成
    Set oTS = oFS.OpenTextFile(a_sFilePath)
        
    iLineCount = 0
    iCommaCount = 0

    '// ファイルループ
    Do While oTS.AtEndOfStream <> True
        '// 1行読み込み
        sLine = oTS.ReadLine
        
        '// カンマで文字列を分割し配列化
        v = Split(sLine, ",")
        
        '// 現在行をカンマで分割した数が今までより多い場合
        If (iCommaCount < UBound(v)) Then
            '// 最大カンマ数を更新
            iCommaCount = UBound(v)
        End If
        
        iLineCount = iLineCount + 1
    Loop

    Call oTS.Close
    
    Erase a_sArLine
    ReDim a_sArLine(iLineCount - 1, iCommaCount)
    
    '// TextStreamオブジェクト作成
    Set oTS = oFS.OpenTextFile(a_sFilePath)
    
    i = 0
    
    '// ファイルループ
    Do While oTS.AtEndOfStream <> True
        '// 1行読み込み
        sLine = oTS.ReadLine
        
        '// カンマで文字列を分割し配列化
        v = Split(sLine, ",")
        
        '// カンマ区切り配列をループ
        For iColumn = 0 To UBound(v)
            '// カンマ区切りの内容を二次元配列に格納
            a_sArLine(i, iColumn) = v(iColumn)
        Next
        
        i = i + 1
    Loop
    Call oTS.Close
End Function
```

>参考
https://qiita.com/fusafusa/items/14be276291233116f5b5
https://vbabeginner.net/vba%E3%81%A7csv%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BA%8C%E6%AC%A1%E5%85%83%E9%85%8D%E5%88%97%E3%81%AB%E6%A0%BC%E7%B4%8D%E3%81%99%E3%82%8B/