Dim f As Integer
Dim line As String
f = FreeFile
Open "CSVファイルのフルパス" For Input As #f ' 読み込みたいCSVのパス
Line Input #f, line ' 1行だけ読み込む
Range("A1").Value = line
Close #f
Public Sub ファイルを選択して1行読み込む()
Dim fPath As String '※追加①
Dim f As Integer
Dim line As String
' CSVを選ぶ※追加②
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
' キャンセル対応※追加③
If fPath = "False" Then Exit Sub
' 読み込み
f = FreeFile
Open fPath For Input As #f
Line Input #f, line '最初の1行を読み込み
Range("A1").Value = line
Close #f
End Sub
Public Sub ファイルを1行ずつ読み込む()
Dim fPath As String
Dim f As Integer
Dim line As String
Dim row As Long '※追加①
Dim arr As Variant '※追加②
' CSVを選ぶ
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
' キャンセル対応
If fPath = "False" Then Exit Sub
' ファイル読み込み
f = FreeFile
Open fPath For Input As #f
'1行ずつ繰り返し読み込み※追加③
row = 1
Do Until EOF(f)
Line Input #f, line ' 1行読み込む
arr = Split(line, ",") ' カンマで分割
Range("A" & row).Resize(1, UBound(arr) + 1).Value = arr
row = row + 1
Loop
Close #f
End Sub
Public Sub ゼロ落ち対策前()
Dim fPath As String
Dim f As Integer
Dim line As String
Dim row As Long
Dim arr As Variant
Dim i As Long
' CSVを選ぶ
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
' キャンセル対応
If fPath = "False" Then Exit Sub
' ファイル読み込み
f = FreeFile
Open fPath For Input As #f
'1行ずつ繰り返し読み込み
row = 1
Do Until EOF(f)
Line Input #f, line ' 1行読み込む
arr = Split(line, ",") ' カンマで分割
'▼▼▼ 1セルずつ書き込むコードに変更 ▼▼▼
For i = LBound(arr) To UBound(arr)
Cells(row, i + 1).Value = arr(i)
Next i
'▲▲▲ この場合はゼロ落ちが発生する ▲▲▲
row = row + 1
Loop
Close #f
End Sub
Public Sub ゼロ落ち対策後()
Dim fPath As String
Dim f As Integer
Dim line As String
Dim row As Long
Dim arr As Variant
Dim i As Long
' CSVを選ぶ
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
' キャンセル対応
If fPath = "False" Then Exit Sub
' ファイル読み込み
f = FreeFile
Open fPath For Input As #f
'1行ずつ繰り返し読み込み
row = 1
Do Until EOF(f)
Line Input #f, line ' 1行読み込む
arr = Split(line, ",") ' カンマで分割
'▼▼▼ 1セルずつ書き込むコードに変更 ▼▼▼
For i = LBound(arr) To UBound(arr)
Cells(row, i + 1).NumberFormat = "@" '※追加
Cells(row, i + 1).Value = arr(i)
Next i
'▲▲▲ この場合はゼロ落ちが発生しない ▲▲▲
row = row + 1
Loop
Close #f
End Sub
Public Sub CSV読み込みカスタム関数版()
Dim fPath As String
Dim f As Integer
Dim line As String
Dim row As Long
Dim arr As Variant
Dim i As Long
' CSVを選ぶ
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
If fPath = "False" Then Exit Sub
' ファイル読み込み
f = FreeFile
Open fPath For Input As #f
row = 1
Do Until EOF(f)
Line Input #f, line ' 1行読み込む
arr = SafeSplit(line) ' 行ズレ防止版 Split(カスタム関数)
For i = 0 To UBound(arr)
Cells(row, i + 1).NumberFormat = "@"
Cells(row, i + 1).Value = arr(i)
Next i
row = row + 1
Loop
Close #f
End Sub
Function SafeSplit(ByVal line As String) As Variant ' カスタム関数の設定
Dim insideQuote As Boolean
Dim i As Long
Dim ch As String
Dim temp As String
Dim result As Collection
Dim arr() As String
Set result = New Collection
For i = 1 To Len(line)
ch = Mid(line, i, 1)
If ch = """" Then
insideQuote = Not insideQuote
ElseIf ch = "," And Not insideQuote Then
result.Add temp
temp = ""
Else
temp = temp & ch
End If
Next i
result.Add temp
ReDim arr(0 To result.Count - 1)
For i = 1 To result.Count
arr(i - 1) = result(i)
Next i
SafeSplit = arr
End Function
Public Sub CSV読み込みカスタム関数版()~End SubでCSVファイルを読み込むコードが書かれています。
Function SafeSplit(ByVal line As String) As Variant~End Functionの部分では、カスタム関数SafeSplitを定義しています。
Public Sub CSV読み込み_UTF8対応版()
Dim fPath As String
Dim stm As Object
Dim text As String
Dim lines As Variant
Dim one As Variant
Dim arr As Variant
Dim row As Long
Dim i As Long
'CSVを選択
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
If fPath = "False" Then Exit Sub
'UTF-8対応 ADODB.Stream
Set stm = CreateObject("ADODB.Stream")
With stm
.Type = 2 ' adTypeText
.Charset = "utf-8" ' UTF-8を指定
.Open
.LoadFromFile fPath
text = .ReadText(-1) ' 全文読み込み
.Close
End With
'改行統一(CRLF/LFどちらでも対応)
text = Replace(text, vbCrLf, vbLf)
text = Replace(text, vbCr, vbLf)
'行ごとに分割
lines = Split(text, vbLf)
row = 1
'行ループ
For Each one In lines
If Trim(one) <> "" Then
'SafeSplitで列崩れ対策
arr = SafeSplit(one)
'0落ち防止+書き込み
For i = 0 To UBound(arr)
Cells(row, i + 1).NumberFormat = "@"
Cells(row, i + 1).Value = arr(i)
Next i
row = row + 1
End If
Next one
End Sub
Function SafeSplit(ByVal line As String) As Variant ' カスタム関数の設定
Dim insideQuote As Boolean
Dim i As Long
Dim ch As String
Dim temp As String
Dim result As Collection
Dim arr() As String
Set result = New Collection
For i = 1 To Len(line)
ch = Mid(line, i, 1)
If ch = """" Then
insideQuote = Not insideQuote
ElseIf ch = "," And Not insideQuote Then
result.Add temp
temp = ""
Else
temp = temp & ch
End If
Next i
result.Add temp
ReDim arr(0 To result.Count - 1)
For i = 1 To result.Count
arr(i - 1) = result(i)
Next i
SafeSplit = arr
End Function
Public Sub QueryTablesでCSV読み込み()
Dim fPath As String
Dim colCount As Long
Dim types() As Long
Dim i As Long
'CSVファイルを選ぶ
fPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv")
If fPath = "False" Then Exit Sub
'想定する最大列数を決める(例:30列)
colCount = 30 ' ※CSVの列数に合わせて調整してください
ReDim types(1 To colCount)
For i = 1 To colCount
types(i) = xlTextFormat ' 各列を「文字列」として扱う
Next i
'QueryTables で CSV を読み込む
With ActiveSheet.QueryTables.Add( _
Connection:="TEXT;" & fPath, _
Destination:=Range("A1"))
.TextFileParseType = xlDelimited ' 区切り形式
.TextFileCommaDelimiter = True ' カンマ区切り
.TextFilePlatform = 65001 ' UTF-8想定※Shift-JISの場合は65001を932に変更
.TextFileColumnDataTypes = types ' 全列を文字列扱いに固定
.Refresh BackgroundQuery:=False ' 実際に読み込む
.Delete ' 読み込み後にQueryTable自体は削除
End With
End Sub
コードのポイントは次のとおりです。
colCount = 30 ReDim types(1 To colCount) For i = 1 To colCount types(i) = xlTextFormat Next i
Public Sub CSVを書き出すShiftJIS版()
Dim fPath As String
Dim f As Integer
Dim lastRow As Long, lastCol As Long
Dim r As Long, c As Long
Dim line As String
Dim cellValue As String
'保存先を選択
fPath = Application.GetSaveAsFilename("output.csv", _
"CSVファイル (*.csv), *.csv")
If fPath = "False" Then Exit Sub
'上書き対策
If Dir(fPath) <> "" Then
If MsgBox("同じファイルが存在します。" & vbCrLf & _
"上書きしてもよろしいですか?", _
vbYesNo + vbExclamation) = vbNo Then
Exit Sub
End If
End If
'表のサイズを取得
lastRow = Cells(Rows.Count, 1).End(xlUp).row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column
f = FreeFile
Open fPath For Output As #f
'1行ずつ書き出し
For r = 1 To lastRow
line = ""
'列の最後まで処理を繰り返す
For c = 1 To lastCol
cellValue = Cells(r, c).value
' セル内にCSVが壊れる原因がある場合(セル内にカンマ・ダブルクォーテーション・改行がある)
If InStr(cellValue, ",") > 0 Or _
InStr(cellValue, """") > 0 Or _
InStr(cellValue, vbLf) > 0 Or _
InStr(cellValue, vbCr) > 0 Then
' ダブルクォーテーションをつける
cellValue = Replace(cellValue, """", """""""")
cellValue = """" & cellValue & """"
End If
line = line & cellValue
If c < lastCol Then line = line & ","
Next c
Print #f, line
Next r
Close #f
End Sub
コードのポイントは次のとおりです。
fPath = Application.GetSaveAsFilename("output.csv", "CSVファイル (*.csv), *.csv") If fPath = "False" Then Exit Sub
line = line & cellValue If c < lastCol Then line = line & ","
セルの値をつなぎ合わせて、最後の列以外は値の後ろにカンマを挿入します。
変数lineにセルの値をどんどんつぎ足しているイメージです。
Print #f, line
行を書き込んでいます。
また、参考として、CSVファイルを書き出すVBAの文字コードUTF-8版もご紹介します。
Public Sub CSVを書き出すUTF8版()
Dim fPath As String
Dim lastRow As Long, lastCol As Long
Dim r As Long, c As Long
Dim line As String
Dim cellValue As String
Dim utf8Text As String
Dim stm As Object
' 保存先の選択
fPath = Application.GetSaveAsFilename("output.csv", _
"CSVファイル (*.csv), *.csv")
If fPath = "False" Then Exit Sub
' 上書き確認
If Dir(fPath) <> "" Then
If MsgBox("同名ファイルがあります。上書きしますか?", _
vbYesNo + vbExclamation) = vbNo Then
Exit Sub
End If
End If
' 表のサイズ取得
lastRow = Cells(Rows.Count, 1).End(xlUp).row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column
utf8Text = "" ' 一旦すべて文字列として作る
'CSV組み立て
For r = 1 To lastRow
line = ""
For c = 1 To lastCol
cellValue = Cells(r, c).value
' セル内にCSVが壊れる原因がある場合(セル内にカンマ・ダブルクォーテーション・改行がある)
If InStr(cellValue, ",") > 0 Or _
InStr(cellValue, """") > 0 Or _
InStr(cellValue, vbLf) > 0 Or _
InStr(cellValue, vbCr) > 0 Then
' ダブルクォーテーションをつける
cellValue = Replace(cellValue, """", """""""")
cellValue = """" & cellValue & """"
End If
line = line & cellValue
If c < lastCol Then line = line & ","
Next c
utf8Text = utf8Text & line & vbCrLf
Next r
'UTF-8 書き出し(BOMあり)
Set stm = CreateObject("ADODB.Stream")
With stm
.Type = 2 ' テキストモード
.Charset = "utf-8" ' UTF-8指定
.Open
.WriteText utf8Text
.SaveToFile fPath, 2
.Close
End With
End Sub
Public Sub 複数CSVをまとめて読み込む()
Dim folderPath As String
Dim fileName As String
Dim f As Integer
Dim line As String
Dim row As Long
'フォルダを選ぶ
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show <> -1 Then Exit Sub
folderPath = .SelectedItems(1) & "\"
End With
'最初のCSVファイルを取得
fileName = Dir(folderPath & "*.csv")
row = 1
'CSVを1つずつ処理
Do While fileName <> ""
f = FreeFile
Open folderPath & fileName For Input As #f
Do Until EOF(f)
Line Input #f, line
'カンマで分割※行ズレ防止版にしたい場合はarr = SafeSplit(line)にし、このコードの下にカスタム関数の定義を追加
arr = Split(line, ",")
'1列ずつ書き込み
For i = 0 To UBound(arr)
Cells(row, i + 1).NumberFormat = "@"
Cells(row, i + 1).value = arr(i)
Next i
row = row + 1
Loop
Close #f
' 次のCSVへ
fileName = Dir()
Loop
End Sub
Public Sub CSV複数読み込み_UTF8版()
Dim folderPath As String
Dim fileName As String
Dim fPath As String
Dim stm As Object
Dim text As String
Dim lines As Variant
Dim one As Variant
Dim arr As Variant
Dim row As Long, i As Long
'CSVフォルダを選択する
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show <> -1 Then Exit Sub
folderPath = .SelectedItems(1) & "\"
End With
'取り込み開始位置
row = 1
'フォルダ内のCSVを順番に取得
fileName = Dir(folderPath & "*.csv")
Do While fileName <> ""
fPath = folderPath & fileName
' ADODB.Stream で UTF-8 読み込み
Set stm = CreateObject("ADODB.Stream")
With stm
.Type = 2 ' adTypeText
.Charset = "utf-8"
.Open
.LoadFromFile fPath
text = .ReadText(-1) ' 全文取得
.Close
End With
'改行を統一
text = Replace(text, vbCrLf, vbLf)
text = Replace(text, vbCr, vbLf)
lines = Split(text, vbLf)
'行ループ
For Each one In lines
If Trim(one) <> "" Then
'カンマで分割※行ズレ防止版にしたい場合はarr = SafeSplit(one)
arr = Split(one, ",")
'0落ち防止+書き込み
For i = 0 To UBound(arr)
Cells(row, i + 1).NumberFormat = "@"
Cells(row, i + 1).value = arr(i)
Next i
row = row + 1
End If
Next one
' 次のCSVへ
fileName = Dir()
Loop
End Sub
On Error GoTo SkipLine
For Each one In lines
' データの読み込み
arr = SafeSplit(one)
For i = 0 To UBound(arr)
Cells(row, i + 1).NumberFormat = "@"
Cells(row, i + 1).Value = arr(i)
Next i
row = row + 1
ContinueLoop:
On Error GoTo SkipLine
Next one
Exit Sub
SkipLine:
' この行はスキップして次へ
row = row + 1
Resume ContinueLoop