VB6でCSVファイルを読み込みたいのですが、
以下のような項目だと、1項目として読み込むことができません。
例) AAA,"BBB,CCC,"" """,DDD
"BBB,CCC,"" """ を1項目として読み込みたいのですが
ダブルコーテーションの括りの中に、更にダブルコーテーションがあると
うまくいかないみたいです。
何か方法がありますでしょうか?
Open DownLoadFile For Input As #1 Len = 32000
Input #1, rec
Do Until EOF(1)
処理1
Loop
close #1
No.5ベストアンサー
- 回答日時:
>出力フォーマットを変更する事はできないので、
やはり処理を組み込むしかないようですね。
参考になればよいのですが、サンプルを作成しました。
ExcelのVBAで動いたので多分大丈夫だとは思うのですが、、、
ダメっぽかったらそちらで修正して^^;
Option Explicit
Public Const DEF_CHR34 As String = """" 'ダブルコーテーション
Public Const DEF_SPLIT_CHAR As String = "," '区切り文字
Sub Main()
Dim l_strバッファ As String
Dim l_str一行 As String
Dim l_strAryバッファ() As String
Dim i As Integer
Dim l_strAry一行() As String
'ファイルを一気に読み込む
l_strバッファ = ファイル読込み("C:\test.csv")
'改行コードで配列化を行う
l_strAryバッファ = Split(l_strバッファ, vbCrLf)
'改行数のループ処理を行う
For i = LBound(l_strAryバッファ) To UBound(l_strAryバッファ)
l_str一行 = l_strAryバッファ(i)
Debug.Print l_str一行
'文字が存在していなければ、ループを抜ける
If RTrim$(l_str一行) = "" Then
MsgBox i + 1 & "行目が空データなので、ループをぬける"
Stop
Exit For
End If
Stop
'一行を区切り文字で配列化する
If Not 変換_ライン_配列(l_str一行, l_strAry一行, DEF_SPLIT_CHAR) Then
MsgBox "えらー終了"
Stop
Exit For
End If
Stop
Next i
End Sub
Public Function ファイル読込み(ByVal p_strファイル名 As String) As String
Dim intFile As Integer
Dim lngLen As Long
Dim bytBuff() As Byte
intFile = FreeFile
lngLen = FileLen(p_strファイル名)
If lngLen = 0 Then
Exit Function
End If
ReDim bytBuff(0 To lngLen - 1)
Open p_strファイル名 For Binary Access Read As intFile
Get intFile, , bytBuff
Close intFile
ファイル読込み = StrConv(bytBuff, vbUnicode)
End Function
'文字列を、指定の区切りキャラで、配列化を行う
Public Function 変換_ライン_配列( _
ByVal p_str一行 As String, _
ByRef p_strAry一行() As String, _
Optional ByVal p_str区切 As String = "," _
) As Boolean
Dim l_bln実行結果 As Boolean
Dim l_strAry区切() As String
Dim l_str文字列 As String
Dim i As Integer
Dim l_intカウント取得数 As Integer
Dim l_strAry返却() As String
l_bln実行結果 = True
'区切り文字で配列化する
l_strAry区切 = Split(p_str一行, p_str区切)
'配列要素数でループを行う
For i = LBound(l_strAry区切) To UBound(l_strAry区切)
'取得する
If Not 補正取得(l_strAry区切, i, l_str文字列, p_str区切) Then
'エラー処理
l_bln実行結果 = False
Exit For
End If
'取得した文字列を、配列として記憶する
ReDim Preserve l_strAry返却(l_intカウント取得数)
l_strAry返却(l_intカウント取得数) = l_str文字列
l_intカウント取得数 = l_intカウント取得数 + 1
Next i
'記憶した配列を返却する
p_strAry一行 = l_strAry返却
'取得結果のステータスを返却する
変換_ライン_配列 = l_bln実行結果
End Function
Private Function 補正取得( _
ByRef p_strAry区切() As String, _
ByRef p_int開始位置 As Integer, _
ByRef p_str取得文字 As String, _
ByVal p_str区切 As String _
) As Boolean
Dim l_bln実行結果 As Boolean
Dim i As Integer
Dim l_str文字 As String
Dim l_strAryChr34() As String
Dim l_intカウントChr34 As Integer
Dim l_str文字連結 As String
l_str文字 = p_strAry区切(p_int開始位置)
If Left$(l_str文字, 1) = DEF_CHR34 Then
'ダブルコーテーションで文字列が始まる場合
For i = p_int開始位置 To UBound(p_strAry区切)
l_str文字 = p_strAry区切(i)
'初回のループでなければ、区切りキャラを追加する
If i <> p_int開始位置 Then
l_str文字連結 = l_str文字連結 & p_str区切
End If
'文字列の連結を行う
l_str文字連結 = l_str文字連結 & l_str文字
'内部に存在するダブルコーテーションの数を取得する
l_strAryChr34 = Split(l_str文字, DEF_CHR34)
l_intカウントChr34 = l_intカウントChr34 + UBound(l_strAryChr34)
'一番右の文字がダブルコーテーションである 且つ ダブルコーテーションのカウントが偶数である
If (Right$(l_str文字, 1) = DEF_CHR34) And ((l_intカウントChr34 Mod 2) = 0) Then
'先頭と最後のダブルコーテーションを抹消
p_str取得文字 = Mid$(l_str文字連結, 2, Len(l_str文字連結) - 2)
'呼び出し元のループカウンタのポジションを進める
p_int開始位置 = i
'正常処理であることを通知
l_bln実行結果 = True
Exit For
End If
Next i
Else
'ダブルコーテーションで文字列が始まらない場合
'取得した値をそのままセット
p_str取得文字 = l_str文字
'正常処理であることを通知
l_bln実行結果 = True
End If
'取得結果のステータスを返却する
補正取得 = l_bln実行結果
End Function
No.6
- 回答日時:
もう一つのサンプルを作成しました。
OLEDBドライバ+ADOでのサンプルです。
OLEDBがテキストに対応していたら、テキストをデータセットとして取得することも出来ます。
おそらくテキストの拡張子が
txt
csv
tab
asc
であれば可能だと思います。
Public Const DEF_CHR34 As String = """" 'ダブルコーテーション
Sub テスト()
Dim l_adoRec As Object 'ADODB.Recordset
Dim l_adoFld As Object 'ADODB.Field
Dim i As Integer
Dim l_intCount As Integer
Set l_adoRec = GetAdoRecordSet("C:\test.asc", False)
Do Until l_adoRec.EOF
l_intCount = l_intCount + 1
If IsNull(l_adoRec.Fields(0)) Then
Debug.Print l_intCount & "件目の先頭が未設定なので、処理を抜けました"
Exit Do
End If
Debug.Print String(15, "-")
Debug.Print l_intCount & "件目"
Debug.Print String(15, "-")
For Each l_adoFld In l_adoRec.Fields
'ADOの仕様で、ダブルコーテーション2個は1個に置き換えられるので、それを戻す処理も同時に行う
Debug.Print Replace(l_adoFld.Value, DEF_CHR34, String(2, DEF_CHR34))
Next
l_adoRec.MoveNext
Loop
End Sub
Private Function GetAdoRecordSet(ByVal p_strPath As String, p_bln先頭がヘッダ項目 As Boolean) As Object
Dim l_adoCnn As Object 'ADODB.Connection
Dim l_strCnn As String
Dim l_strSQL As String
Dim l_fsoFile As Object 'Scripting.File
Dim l_strヘッダオプション As String
'テキストの先頭がヘッダを含むかどうかの設定
If p_bln先頭がヘッダ項目 Then
l_strヘッダオプション = "YES"
Else
l_strヘッダオプション = "NO"
End If
'ファイルを取得する
Set l_fsoFile = GetFsoFileObject(p_strPath)
'コネクションオープン
Set l_adoCnn = CreateObject("ADODB.Connection")
l_strCnn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& l_fsoFile.ParentFolder.Path _
& ";Extended Properties=""Text;HDR=" & l_strヘッダオプション & """"
l_adoCnn.Open l_strCnn
'レコードセットを取得
l_strSQL = "SELECT * FROM [" & l_fsoFile.Name & "]"
Set GetAdoRecordSet = l_adoCnn.Execute(l_strSQL)
End Function
Private Function GetFsoFileObject(ByVal p_strPath As String) As Object
Set GetFsoFileObject = CreateObject("Scripting.FileSystemObject").GetFile(p_strPath)
End Function
No.4
- 回答日時:
カンマの点から、Input#のステートメントに頼れないと思うので
Line Input #ステートメントを使って、1行全部を文字列として受け取り、内容にしたがって、後はしたいように、切り出しを、ロジックを工夫してコーディングするより他ないと思う。
そのロジックは、規則性があるのかないのかも、質問に内容が掲示できてないので、判りません。
最悪Input¥ステートメトで指定文字数分受け取り、レコード分解も
自力でになるかも。
No.2
- 回答日時:
例) AAA,"BBB,CCC,"" """,DDD
を読み込んだときどのような結果を希望しているのでしょうか?
2つ連続するダブルクォーテーションはデータのダブルクォーテーションとみなす
というルールなら、左側から1文字ずつ読んで
項目1=AAA
項目2=BBB,CCC," "
項目3=DDD
ということになると思います。
項目分けは自力で行うしかないでしょう。
Open DownLoadFile For Input As #1 Len = 32000
Do Until EOF(1)
Line Input #1, rec
recを先頭から1文字ずつ見て項目分けする処理
処理1
Loop
close #1
No.1
- 回答日時:
解決策ではありませんが、、、、
このCSVのフォーマットは、もう確定ですか?
というのは、
・「カンマ」区切り
・文字列を「ダブルコーテーション」で囲む
という仕様のCSVであれば、CSVのデータは
・「カンマ」
・「ダブルコーテーション」
は禁則文字にすることが前提だと思います。
しかし、データとして存在しているからこそこういう問題が発生していると思うので、、、
※出力フォーマットとして
・「TAB」区切りを利用する
・文字列を""で囲む事をしない
というルールに変更が可能であれば、そちらをお勧めしたいです。
ありがとうございます。
解決策はありませんか。。。
でも、出力フォーマットを変更する事はできないので、
何か手を考えなければいけない・・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) ¥マークを含むパスの処理について(マクロ、または関数) 2 2022/12/25 02:11
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
- その他(プログラミング・Web制作) Pythonで、データファイルと列名ファイルを1つのファイルにしたいです。 1 2023/07/27 20:29
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- その他(プログラミング・Web制作) Windowsのバッチファイルについてご教示ください 5 2023/07/25 20:23
- Perl perl このテキストファイルを簡単に配列に入れるには? 2 2022/04/27 20:24
- SQL Server ACCESSで3ファイルを結合して、表を作成するやり方を教えて下さい。 17 2022/08/15 20:34
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- その他(Microsoft Office) パワークエリの複数ファイルのデータ統合について 3 2022/07/14 17:06
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCL言語で文字列検索方法を教え...
-
nullと""、\\0とEOFの違いにつ...
-
プログラムによく出てくるst...
-
C++で入力した文字列から数字を...
-
シリアル通信で0x00を送信した...
-
16進数を2文字ずつ配列に格納し...
-
文字コードによる表記
-
C#でstringをポインタとして渡す
-
WSH(VBS)でJSONの文字列を読み...
-
%dなどの違い
-
Perlでの文字列操作について
-
バイナリファイル中の日本語文...
-
char型配列の最大要素数
-
C言語の勉強しています。すみま...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
[Excel VBA]デフォルトプロパティ
-
エクセルVBAで部分検索でのアラ...
-
関数に文字列を渡すことについて
-
VBA-DLLの引数受け渡しについて
-
Integer変数をカラにしたいので...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
C++で入力した文字列から数字を...
-
%dなどの違い
-
C#でstringをポインタとして渡す
-
16進数を2文字ずつ配列に格納し...
-
TCL言語で文字列検索方法を教え...
-
プログラムによく出てくるst...
-
WSH(VBS)でJSONの文字列を読み...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
数字の入った配列をファイルへ...
-
構造体→文字列→構造体 をする方法
-
VB6.0でのバイナリデータの扱い...
-
char型配列の最大要素数
-
[C++]WCHARの1文字目しか表示で...
-
アルファベットをカウント、
-
C言語の勉強しています。すみま...
-
VBA-DLLの引数受け渡しについて
-
c#で他のアプリの文字入力フォ...
-
Shift_JIS(16進)を文字に変換す...
-
バイナリファイル中の日本語文...
おすすめ情報