VBを2008を用いてCSVを取り込む ””で区切られていない数値混入 文字列に,が含まれている場合がある。
題名どおりなのですが、以下のようなCSVファイルをVB2008で取り込もうと考えています。
"AAAAA",BBBBB,CCCCC,"DDDD,DDD","EEEEE","FFFFF"
(同じアルファベットが本来同じ項目のデータ、BとCは0-9の数字のみ入ります
またBCには常に””が含まれません。
Dは文字列なのですが、まれに「,」が含まれます)
下のものが現在使用しているソースですがsplitで「,」を指定しているので
当然Dが2つのデータとして認識されています。
BやCが””で囲まれていれば「”,”」で区切ればすむのですが一部が””なしなので
どうやろうか迷っています。
実現したいこととしては
""なしの時は必ず、コンマまでが1つのデータ、
""があれば""で区切られたデータが1つのデータとできればいいんですが。。。
以下ソースです。 ちなみにASPXファイルです。
(replaceDoubleQuotesというのは”を削除するための関数で無視していただいて結構です。
また以下のソースでは取り込み自体はせずにタイトル行がはいっているCSVファイルを弾く作業をしているのですが
CSVからデータを取り出す作業は同じなので短いソースを使用させてもらっています)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim Reader2 As New IO.StreamReader("C:\UploadedFiles\Uriage.txt", System.Text.Encoding.GetEncoding("Shift-JIS"))
Dim Items2() As String 'CSVの各項目を表す配列
Dim Line2 As String = Reader2.ReadLine 'CSVの一行
Items2 = Line2.Split(",")
Dim num_hantei As String = "^[0-9]+$"
If Not (Regex.IsMatch(replaceDoubleQuotes(Items2(3)), num_hantei)) Then
Dim objFSO As Object
objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile("C:\UploadedFiles\Uriage.txt", True)
objFSO = Nothing
Label1.Text = "取り込みエラー。タイトル行がはいっている可能性があります。"
Exit Sub
End If
Reader2.Close()
End Sub
Function replaceDoubleQuotes(ByVal apdata As Object) As String
'文字列に変換する
Dim tmp As String = String.Format("{0}", apdata)
'1つのダブルクォーテーションを0個に置換する つまり消去する
replaceDoubleQuotes = tmp.Replace("""", "")
End Function
No.3ベストアンサー
- 回答日時:
ありがとうございます。参照サイトをみてすごくよさそうなのですが、各項目のデータを引き出すことができない状態です。
ASPXでやっているとConsole.WriteLine()も画面にはまったく表示されず、
他の例でつかっていたLabel1.textに代入させることもできなくて。。。
データの抽出自体は””を取り除き、””内のコロンも無視できるのでこの手法でいきたいのですが。
もうすこし検討してみます。
No.2
- 回答日時:
【考え方】
1.引用符内部のカンマを特定文字に変換する。
2.カンマで区切る。
3.各要素において特定文字をカンマに変換する。
特定文字は入力できないような文字にしておく。
Imports System.Text.RegularExpressions
'---- 中略 ----
Const 特定文字 As String = Chr(0)
Dim 正規表現 As Regex = New Regex("\""(.*?)\""") '引用符内部を示す正規表現
'与えられた文字列をカンマで区切り、文字列の配列を返す
'但し、引用符内部のカンマは区切り文字とは見なさない
Function 分割処理(ByVal 指定文字列 As String) As String()
'★1.引用符内部のカンマを特定文字に変換する
Dim 変換後文字列 As String = 正規表現.Replace(指定文字列, AddressOf 内部変換)
'★2.カンマで分割する
Dim 配列() As String = 変換後文字列.Split(",")
Dim I As Integer
For I = 0 To UBound(配列)
'★3.要素内の特定文字をカンマに変換する
配列(I) = 配列(I).Replace(特定文字, ",")
Next
分割処理 = 配列
End Function
'引用符内部の文字列を置換する
Function 内部変換(ByVal 一致部分 As Match) As String
内部変換 = 一致部分.ToString().Replace(",", 特定文字)
End Function
正規表現の使い方を習得すると、何かと便利なのでお勧めします。
ありがとうございます。
正規表現自体は利用したことがあったのですが、今回の事例も正規表現を使えば、考える挙動がだせると勉強になりました。
今回は、他の回答者のかたのTextFieldParserを使用と思いますが、こちらについても勉強しようと思います。
No.1
- 回答日時:
コードなど書いて質問が長いが、コードを考える前に、どういうロジックでやれるのかはっきりさせる必要がある。
どういう風にやれば旨く行きそうなのかは、質問者で無いとわからない。
頻度や用途にも関係するから。質問には、データ例も挙げられていないし判らない。またプログラムのスキルもある。例えば正規表現に慣れていない人にそれを使う回答は無意味。
特にカンマの誤混入(?)は痛い。本当に誤混入なのか?
このへんを補足で説明してほしい。
ーー
CSVファイルは色々数種の方式がある。項目内容について
カンマで区切る、は動かせないが
A.ダブルクオートで全て囲む
B.文字列だけ囲む。数値は囲まない
C.全て囲まない
など。
>””で区切られていない数値混入
はB。のケースで無いのか?
Aなのに異例的に数値があるということか。
ーーー
>文字列に,が含まれている場合がある。
入力ミスか?本来のカンマの使い方が文字列にあるということか。
参考 http://soudan1.biglobe.ne.jp/qa5012895.html
エクセルなどではカンマもダブルクオートの中だとカンマの扱いのようだが。
http://d.hatena.ne.jp/verdana/20091023/1256322414
ーー
VB.NET固有のCSVを扱うプログラムで処理してどうなりますか
http://www.cocoaliz.com/vb.net/index/25/
など
====
(1000行ぐらいなら)テキストエディタなどで、人間がチェックして、プログラムでは発見・修正が難しくなる個所を手入力で修正し、中間ファイルをつくるのが一番早いと思うが、いかが。
ーー
前段階処理として、またはその疑わしきでもよい、個所をプログラムで摘出し、数を限定・少数に出来ないか。
ありがとうございます。
確かに質問が長くて見づらいとは思うのですが、ソースは書いてあるほうが回答者の方も理解しやすいと思い、記載しました。
今回のデータは業務で使用しているPCから出力されるCSVで売り上げデータなどが入力されているものです。
実際のデータは都合上、掲載できませんが、Dに該当する部分が商品名にあたるもので
たとえで言うと「炭酸水 1,000mL」という感じです。
テストしていた段階では商品名に「,」がはいっていなかったのでうまく動作していたのですが、ごくごく一部に「,」が含まれていたために、今回の質問をいたしました。
また今回のプログラムはWEB上に設置して、各店が売り上げデータを中央のサーバーに送り、DBに登録するようなものなので元のCSVファイルを人間がチェックというのは考えておりません。(リテラシーがないひとでも動作できるものを作らないといけないので)
業務で使用しているPCから出力されるCSVもすべてを””を括ってくれれば苦労しないのですが、それも業務用のものなので仕様の変更はできません。
他の方が提案されている方法でいろいろ検討しようと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
16進数を2文字ずつ配列に格納し...
-
プログラムによく出てくるst...
-
シリアル通信で0x00を送信した...
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
[C++]WCHARの1文字目しか表示で...
-
コールバック関数
-
WSH(VBS)でJSONの文字列を読み...
-
アルファベットをカウント、
-
%dなどの違い
-
C#でstringをポインタとして渡す
-
CSVファイルの「”」について
-
C言語 配列の長さの上限
-
セグメントエラー
-
ファイル名「1.jpg ~10.jpg~...
-
関数から配列を返すには?
-
VBAのプログラムで、DIAG = 1# ...
-
VB.NETでファイル名順にファイ...
-
defineを使った配列
-
strcat関数を自作したいです
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
プログラムによく出てくるst...
-
%dなどの違い
-
WSH(VBS)でJSONの文字列を読み...
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
16進数を2文字ずつ配列に格納し...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C++で文字列の右端から特定の文...
-
シリアル通信で0x00を送信した...
-
VBA-DLLの引数受け渡しについて
-
数字の入った配列をファイルへ...
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
Shift_JIS(16進)を文字に変換す...
-
バイナリファイル中の日本語文...
-
C言語の課題で困っています;
-
[C++]WCHARの1文字目しか表示で...
-
VB6.0でのバイナリデータの扱い...
おすすめ情報