'***************************************************************************************************
' CSVテキストファイル読み込みサンプル(FSO版、カンマ数不定対応) Module1(Module)
'
' 作成者:井上治 URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' [参照設定]
' ・Microsoft Scripting Runtime
'***************************************************************************************************
'変更日付 Rev 変更履歴内容------------------------------------------------------------------------>
'03/07/25(1.00)新規作成
'03/12/04(1.01)初回修正
'20/02/26(1.10)*.xlsm化、他
'***************************************************************************************************
Option Explicit
'===================================================================================================
Private Const g_cnsTitle As String = "CSVテキストファイル読み込み"
Private Const g_cnsFilter As String = "CSV形式ファイル (*.csv),*.csv,全てのファイル(*.*),*.*"
Private Const g_cnsSC As String = "'" ' シングルクォーテーション
Private Const g_cnsDC As String = """" ' ダブルクォーテーョン
Private Const g_cnsCOM As String = "," ' カンマ
' ※Tab区切りの場合は上の「g_cnsCOM」を変更して下さい。
'Private Const g_cnsCOM As String = vbTab ' Tab(項目区切り文字)
'***************************************************************************************************
' ■■■ ワークシート側からの呼び出し処理 ■■■
'***************************************************************************************************
'* 処理名 :READ_CsvFile3
'* 機能 :CSVテキストファイル読み込みサンプル
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数 :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2003年07月25日
'* 作成者 :井上 治
'* 更新日 :2020年02月26日
'* 更新者 :井上 治
'* 機能説明:FSO版、カンマ数不定対応
'* 注意事項:サンプルなのでエラー処理は行なっていません
'***************************************************************************************************
Sub READ_CsvFile3()
'-----------------------------------------------------------------------------------------------
Dim objFso As FileSystemObject ' FileSystemObject
Dim objTs As TextStream ' TextStream
Dim lngRow As Long ' 収容するセルの行
Dim lngRec As Long ' レコード件数カウンタ
Dim lngCol As Long ' 行毎の最終カラム
Dim strFileName As String ' OPENするファイル名(フルパス)
Dim vntFileName As Variant ' ファイル名受取り用
Dim vntRec As Variant ' 項目配列受け取り用
'-----------------------------------------------------------------
' ①「ファイルを開く」のダイアログでファイル名の指定を受ける
Application.StatusBar = "読み込むファイル名を指定して下さい。"
vntFileName = Application.GetOpenFilename(FileFilter:=g_cnsFilter, Title:=g_cnsTitle)
' キャンセルされた場合はFalseが返るので以降の処理は行なわない
If VarType(vntFileName) = vbBoolean Then Exit Sub
strFileName = vntFileName
'-----------------------------------------------------------------
' ②FileSystemObject
Set objFso = New FileSystemObject
' 指定ファイルをOPEN(入力モード)
Set objTs = objFso.OpenTextFile(Filename:=strFileName, IOMode:=ForReading)
Set objFso = Nothing
' 先頭行の設定(2行目から掻き出すので1とする)
lngRow = 1
'-----------------------------------------------------------------
' ③ファイルのEOFまで繰り返す
Do Until objTs.AtEndOfStream
' レコード件数カウンタの加算
lngRec = lngRec + 1
Application.StatusBar = "読み込み中です....(" & lngRec & "レコード目)"
' 改行単位に読み込み、レコードを配列化する処理を呼び出す
vntRec = FP_MakeArrayFromCSV(objTs.ReadLine)
' 行を加算
lngRow = lngRow + 1
' 空行対策
If IsArray(vntRec) Then
' 項目配列から最終カラムを算出
lngCol = UBound(vntRec) + 1
' 配列を横のセル範囲(要素数を合わせる)に転記
Range(Cells(lngRow, 1), Cells(lngRow, lngCol)).Value = vntRec
End If
Loop
'-----------------------------------------------------------------
' ④処理終了
objTs.Close
Set objTs = Nothing
Application.StatusBar = False
' 終了の表示
MsgBox "ファイル読み込みが完了しました。" & vbCr & _
"レコード件数=" & lngRec & "件", vbInformation, g_cnsTitle
End Sub
'***************************************************************************************************
' ■■■ サブ処理(Private) ■■■
'***************************************************************************************************
'* 処理名 :FP_MakeArrayFromCSV
'* 機能 :CSVレコードを配列に変換
'---------------------------------------------------------------------------------------------------
'* 返り値 :カンマで分解した配列(Variant)
'* 引数 :Arg1 = 1レコード内容(String)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2003年07月25日
'* 作成者 :井上 治
'* 更新日 :2020年02月26日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:
'***************************************************************************************************
Private Function FP_MakeArrayFromCSV(ByVal strRec As String) As Variant
'-----------------------------------------------------------------------------------------------
Dim lngIx As Long ' 配列INDEX
Dim lngPos As Long ' 文字位置
Dim lngPosMax As Long ' 最終文字位置
Dim lngPos1 As Long ' 項目単位先頭文字位置
Dim vntRec As Variant ' 配列WORK
Dim strChar As String ' 1文字WORK
Dim strChar1 As String ' 1文字WORK
'-----------------------------------------------------------------
' 変数を初期化
lngIx = -1
ReDim vntRec(0)
lngPos = 1
lngPosMax = Len(strRec)
'-----------------------------------------------------------------
' レコード全体のループ
Do While lngPos <= lngPosMax
' 項目当りの先頭文字の判定(セパレータか)
strChar1 = Mid(strRec, lngPos, 1)
Select Case strChar1
Case g_cnsSC ' シングルクォーテーション
lngPos = lngPos + 1
Case g_cnsDC ' ダブルクォーテーョン
lngPos = lngPos + 1
Case Else ' なし(カンマで判定)
strChar1 = g_cnsCOM
End Select
' 項目当りの先頭位置
lngPos1 = lngPos
' 項目当りの終了位置判定
Do While lngPos <= lngPosMax
strChar = Mid(strRec, lngPos, 1)
' 終了文字判定
If strChar = strChar1 Then
' カンマでないか
If strChar1 <> g_cnsCOM Then
' レコード探索終了か
If lngPos >= lngPosMax Then
Exit Do
ElseIf ((Mid(strRec, lngPos + 1, 1) = strChar1) And (strChar1 = g_cnsDC)) Then
' ダブルクォーテーョン連記は1文字として扱う(1文字分進める)
lngPos = lngPos + 1
ElseIf Mid(strRec, lngPos + 1, 1) = g_cnsCOM Then
' カンマなら内ループを抜ける
Exit Do
End If
Else
' カンマなら内ループを抜ける
Exit Do
End If
End If
' 次の文字位置へ
lngPos = lngPos + 1
Loop
' 1項目の配列登録(配列の要素数を増やして登録)
lngIx = lngIx + 1
ReDim Preserve vntRec(lngIx)
' 項目内容があるか
If lngPos > lngPos1 Then
' ※本処理では特にデータ型の判断は行なわない
vntRec(lngIx) = Mid$(strRec, lngPos1, lngPos - lngPos1)
Else
vntRec(lngIx) = Empty
End If
' 次項目の先頭に移動
If strChar <> g_cnsCOM Then
lngPos = lngPos + 2
Else
lngPos = lngPos + 1
End If
Loop
'-----------------------------------------------------------------
' 有効レコードか
If strRec <> "" Then
' レコード右端がカンマの場合は配列要素を1つ増やす
If Mid(strRec, lngPosMax, 1) = g_cnsCOM Then
lngIx = lngIx + 1
ReDim Preserve vntRec(lngIx)
vntRec(lngIx) = Empty
End If
End If
' 戻り値にセット
If lngIx >= 0 Then
FP_MakeArrayFromCSV = vntRec
Else
FP_MakeArrayFromCSV = ""
End If
End Function
'----------------------------------------<< End of Source >>----------------------------------------