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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
都道府県穴埋めゲーム
都道府県の名前を1人1つずつ投稿してください。全ての都道府県が出たら締め切ります!
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
VB6.0でダブルクォーテーション
その他(ソフトウェア)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#でstringをポインタとして渡す
-
プログラムによく出てくるst...
-
C++で文字列の右端から特定の文...
-
VB6.0でのバイナリデータの扱い...
-
16進数を2文字ずつ配列に格納し...
-
sprintf関数について教えて下さ...
-
シリアル通信で0x00を送信した...
-
Excelシートを固定長のテキスト...
-
数字の入った配列をファイルへ...
-
K&Rのp.95のgetop(char s[])
-
WSH(VBS)でJSONの文字列を読み...
-
引用符と二重引用符
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C言語のポインタに直接アドレス...
-
CStringからchar*への型変換に...
-
C言語 配列の長さの上限
-
関数から配列を返すには?
-
char*を初期化したいのですが
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムによく出てくるst...
-
C#でstringをポインタとして渡す
-
nullと""、\\0とEOFの違いにつ...
-
WSH(VBS)でJSONの文字列を読み...
-
VB6.0でのバイナリデータの扱い...
-
TCL言語で文字列検索方法を教え...
-
C++で入力した文字列から数字を...
-
シリアル通信で0x00を送信した...
-
16進数を2文字ずつ配列に格納し...
-
char型配列の最大要素数
-
[C++]WCHARの1文字目しか表示で...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
構造体→文字列→構造体 をする方法
-
%dなどの違い
-
数字の入った配列をファイルへ...
-
c#で他のアプリの文字入力フォ...
-
引用符と二重引用符
-
Shift_JIS(16進)を文字に変換す...
-
CSVファイルの「”」について
-
AnsiStringについて
おすすめ情報