- 締切済み
CSV→タブ区切り
CSVファイルでデータを取り込もうとしてますが、金額にカンマが入ってたりして、列がずれたりします。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=361247 ↑等を参照した上ですが、タブ区切りデータでインポートしてみようかと思います。 CSVファイルをタブ区切りファイルに変換するにはどうしたらよいでしょうか?そういうコードはありますでしょうか?
- みんなの回答 (7)
- 専門家の回答
みんなの回答
- KenKen_SP
- ベストアンサー率62% (785/1258)
次の2つを参照設定します。(別にレイトバインドでも構いません) ・Microsoft Scripting Runtime ・Microsofr VBScript Regular Expressions x.x 下記のコードで引数 strCSVpath を指定すれば、桁区切りはそのままで、 フィールド区切りをタブに変換します。 コードを読んでもらえば内容はわかると思いますが、正規表現で””に 囲まれた桁区切りのカンマを一時的に在りえ無そうな別の文字列に置換 しておき、フィールド区切りのカンマをタブに置換、最後に桁区切りを 元に戻しています。 ご希望通りの仕様だと思いますが...コードの中で使うならテキストに 書き出してまた読み込むのは意味がないので、配列で CSV データを返す 関数にした方が良いかな... データ量が増えるとロジックにもよりますが一般に文字列操作には時間 がかかりますので...置換で一気にやれるなら、その方が VB では早いと 思います。 が、一文字毎にチェックした方が確実ではあります。適材適所でやって みて下さい。 Private Sub TEST(ByVal strCSVpath As String) Dim REG As RegExp Dim FSO As FileSystemObject Dim M As Match Dim MC As MatchCollection Dim sBuf As String Dim sTmp As String Dim vRec As Variant Dim sOut As String Dim i As Long Const REG_PATTERN = """" & "(\\|\d+)[\d,]+" & """" Const TMP_COMMA = "%%$$&&%%$$&&" Const REC_SPLIT_CODE = vbCrLf ' レコード区切り On Error GoTo ERROR_HANDLER ' CSV の内容を読み込む Set FSO = New FileSystemObject With FSO.GetFile(strCSVpath).OpenAsTextStream sBuf = .ReadAll .Close End With ' 桁区切りのカンマを一時的に仮の文字列に置換しておく Set REG = New RegExp With REG .IgnoreCase = False .Global = True .PATTERN = REG_PATTERN Set MC = .Execute(sBuf) For Each M In MC sTmp = Replace(M, ",", TMP_COMMA) sBuf = Replace(sBuf, M, sTmp) Next End With ' フィールド区切りのカンマをタブに置換 sBuf = Replace(sBuf, ",", vbTab) ' 桁区切りのカンマを元に戻す sBuf = Replace(sBuf, TMP_COMMA, ",") ' テキストに書き出し vRec = Split(sBuf, REC_SPLIT_CODE) With FSO Do ' 一時ファイル名生成 sOut = .BuildPath(.GetParentFolderName(strCSVpath), _ .GetTempName) Loop Until sOut <> "" End With With FSO.CreateTextFile(sOut, Overwrite:=True) For i = 0 To UBound(vRec) .WriteLine vRec(i) Next i .Close End With Kill strCSVpath Name sOut As strCSVpath TERMINATE: Set REG = Nothing Set FSO = Nothing Exit Sub ERROR_HANDLER: MsgBox Err.Description, vbCritical Resume TERMINATE End Sub
データのパターンを分析して (1)LineInputなどで、一行ずつ読み込み (2)Instrなどでカンマがいくつ余分に入っているかを見つけ出し、 (3)パターンによりどのカンマが不要であるか判断し、取り除く ということになります。 データのパターンによっては不可能になる可能性もあります。 例えば、 aaa,123,456,789,bbb というデータを 4つの列に分類しなくてはいけなくて、 2番目と3番目のデータには桁数の制限がないとしたら、 aaa,123456,789,bbb なのか aaa,123,456789,bbb なのか判断する基準がありません。 そのあたりを踏まえて、CSVデータの分析をするのがまず最初だと思います。
正規表現が使えるなら、LineInputで取り込んでおき、 "/\,([\,\d]+)\,/"で金額部分のみ変数に取り込めるのでは? 頭に¥マークがある場合は "/\\([\,\d]+)\,/"かな?
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。KenKen_SP です。 既に回答があるように CSV ファイルの出力側でなんとかするのが、ベストだと 思いますが... 金額等でカンマが入っているなら CSV データは引用符付になってないですか? 例)"ABC","\123,456","2006/8/1","あああ" # この場合引用符がないと汎用的な CSV フォーマットとは言えません この場合、"," を "(タブコード)" に置換すればいける気がします。引用符が ない場合は手作業になるかも...
補足
今までの4名の皆様、ご回答ありがとうございます。感謝しております。 おっしゃるとおり川上から修正するのが望ましいのですが、別のシステム会社に開発してもらったものであり、触れられない領域になっております。 文字型は確かに"," になってます。 数値型はついておりません。 KenKen_SPさんの方法を考えたことはありました。 文字型ですと対応できそうですが、数値型の列はできそうにありません。 VB.NET上で、 LINEINPUTで1行を取り出し、 FOR i=1 to LEN(テキスト行)-1 mid(テキスト行,i,1) NEXT で、文字を取り出し、 vbtab判定で項目列として判断するように現状はなっております。 当方も引き続き考えますが、 引き続き名案をお待ちしております。
- Hardking
- ベストアンサー率45% (73/160)
CSVファイルの作成側を修正できないならば 私ならまず事前処理として CSVファイルの金額データ中の,カンマを取り除き 全レコードの項目数を統一します。 その後、一括で,カンマを\tタブ文字に変更し、 タブ区切りファイルを作成する。 私は不要と思うのですが、金額データに,カンマを付加するなら 桁数判定し、3桁毎に,カンマを挿入する。
私なら、出来る限りCSVを作り出す側を直そうとしますね。
どうやってCSVファイルを作っているのですか?
補足
皆様、ご助言ありがとうございます。 説明不足もあり、項目内のカンマとはダブルコーテーションに囲まれている中にあります。 "aaa","123,456789",1234 ということです。 16Augustさんのアドバイスにあるような、 aa,123456,789,bbbが aaa,123,456789,bbb ということはないようです。 当方で試行錯誤してみたところ、 1文字分切り出して、ダブルコーテーションだったらフラグ(初期値0)を1加え、カンマで項目を区切ります。 フラグが0の場合(数値型)、2の場合(文字型) と判定し、項目セットします。 フラグが1の場合は、項目内のカンマと判断し、そのまま文字の接続を続けるといったループを組んでみました。今のところ、問題ありません。 これで少し、様子を見ようと思います。