C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: CSVデータの一部分のみ読み込む


(過去ログ 103 を表示中)

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■61470 / inTopicNo.1)  CSVデータの一部分のみ読み込む
  
□投稿者/ JRY (7回)-(2011/08/15(Mon) 10:41:16)

分類:[VB.NET/VB2005 以降] 

あるCSVデータの一部分のみを読み込む方法はありますか?

(0,4)のように、縦と横を指定できるのが理想です。

自分でも探しましたが見つかりませんでした。
参考になるサイトや、解説をお願い致します。
引用返信 編集キー/
■61471 / inTopicNo.2)  Re[1]: CSVデータの一部分のみ読み込む
□投稿者/ 魔界の仮面弁士 (2305回)-(2011/08/15(Mon) 11:07:48)
No61470 (JRY さん) に返信
> あるCSVデータの一部分のみを読み込む方法はありますか?
CSV はシーケンシャルテキストなので、ランダムアクセスはできません。
ゆえに先頭から順に読んでいき、不要な部分は読み捨てるといった作業が必要です。

> (0,4)のように、縦と横を指定できるのが理想です。
面倒なら、全データを DataTable か二次元配列に取り込んでおけば、
行・列を指定してデータを取り出す事も容易になるかと思います。

> 自分でも探しましたが見つかりませんでした。
データ中の「改行」「引用符」「カンマ」を許すかどうかで取得難易度が変わりますが、
一部のみを読み取るという行為にさえ拘らなければ、いくつかのサンプルが見つかるかと思います。

http://jeanne.wankuma.com/tips/vb.net/string/split.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/487csvparser/csvparser.html
http://dobon.net/vb/dotnet/file/readcsvfile.html
http://naka.wankuma.com/site/library/dotnet1.1/Wankuma.IO.CSV1d.htm
引用返信 編集キー/
■61476 / inTopicNo.3)  Re[2]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (8回)-(2011/08/15(Mon) 20:28:38)
No61471 (魔界の仮面弁士 さん) に返信
> ■No61470 (JRY さん) に返信
>>あるCSVデータの一部分のみを読み込む方法はありますか?
> CSV はシーケンシャルテキストなので、ランダムアクセスはできません。
> ゆえに先頭から順に読んでいき、不要な部分は読み捨てるといった作業が必要です。
>
>>(0,4)のように、縦と横を指定できるのが理想です。
> 面倒なら、全データを DataTable か二次元配列に取り込んでおけば、
> 行・列を指定してデータを取り出す事も容易になるかと思います。
>
>>自分でも探しましたが見つかりませんでした。
> データ中の「改行」「引用符」「カンマ」を許すかどうかで取得難易度が変わりますが、
> 一部のみを読み取るという行為にさえ拘らなければ、いくつかのサンプルが見つかるかと思います。
>
> http://jeanne.wankuma.com/tips/vb.net/string/split.html
> http://www.atmarkit.co.jp/fdotnet/dotnettips/487csvparser/csvparser.html
> http://dobon.net/vb/dotnet/file/readcsvfile.html
> http://naka.wankuma.com/site/library/dotnet1.1/Wankuma.IO.CSV1d.htm

ありがとうごさいます。
いろいろと試してみたのですが、できませんでした。

http://hanatyan.sakura.ne.jp/vbhlp/txt01.htm
このサイトにて、次のコードがありました。

'CSV形式ファイルを変数毎に読み書きする
  lngDatN = 0
  '使用可能なファイルナンバーを取得
  intFileNo = FreeFile

  'シーケンシャル入力モードで sample.csv をオープン
  Open "sample.csv" For Input As #intFileNo
  'EOF(intFileNo)が True になるまで実行
  Do Until EOF(intFileNo)
    lngDatN = lngDatN + 1   '件数をカウント
    '変数を1個づつ追加宣言
    ReDim Preserve strYubin(lngDatN) As String
    ReDim Preserve strAddre(lngDatN) As String
    ReDim Preserve strNamae(lngDatN) As String
    'データを各変数に読込
    Input #intFileNo, strYubin(lngDatN), strAddre(lngDatN), _
                strNamae(lngDatN)
  Loop
  'ファイルを閉じる
  Close #intFileNo

  '4番目のデータを表示
  Text2.Text = 4
  Text3.Text = strYubin(4)
  Text4.Text = strAddre(4)
  Text5.Text = strNamae(4)
これは使えると思いましたが、
Open "sample.csv" For Input As #intFileNo
の部分でいくつかエラーが出てしまいました。(宣言はしています)
# = メソッドはカッコで囲む必要があります
open = openは宣言されていません
for = コンマ、')'、または有効な式の継続文字が必要です
"sample.csv" =メソッドの引数は、かっこで囲む必要があります

なにか解決法はありますでしょうか?
引用返信 編集キー/
■61477 / inTopicNo.4)  Re[3]: CSVデータの一部分のみ読み込む
□投稿者/ やんまー (90回)-(2011/08/15(Mon) 22:07:33)
No61476 (JRY さん) に返信
> ■No61471 (魔界の仮面弁士 さん) に返信

> >>(0,4)のように、縦と横を指定できるのが理想です。
>>面倒なら、全データを DataTable か二次元配列に取り込んでおけば、
>>行・列を指定してデータを取り出す事も容易になるかと思います。


魔界の仮面弁士 さんがおっしゃっているように一度二次元配列に入れれば
変数名(0)(4)という感じで取れますよ。

    Dim csvRecords As New System.Collections.ArrayList()
    Dim tfp As New FileIO.TextFieldParser(filename, _
      System.Text.Encoding.UTF8 )
    '区切り文字を,とする
    tfp.Delimiters = New String() {","}

    While Not tfp.EndOfData
      'フィールドを読み込む
      Dim fields As String() = tfp.ReadFields()
      '保存
      csvRecords.Add(fields)
    End While
    
    '後始末
    tfp.Close()


ーーー
こんなふうにすれば
csvRecords(0)(4)
に値が入っていると思います。

引用返信 編集キー/
■61478 / inTopicNo.5)  Re[3]: CSVデータの一部分のみ読み込む
□投稿者/ 魔界の仮面弁士 (2306回)-(2011/08/15(Mon) 22:59:54)
No61476 (JRY さん) に返信
> いろいろと試してみたのですが、できませんでした。
紹介した URL の内容を試してみた結果、どのような状態になったのでしょうか?
状況や不明点を説明してもらわないことには、どこを見直すべきかを指摘する事さえできません…。


> http://hanatyan.sakura.ne.jp/vbhlp/txt01.htm
> このサイトにて、次のコードがありました。
> これは使えると思いましたが、
ちょっと待った。それは VB6/VBA 用のコードですよ。

お使いの環境は、
>> 分類:[VB.NET/VB2005 以降] 
と書かれていましたが、本当は
 分類:[VB6以前]
だったのでしょうか?

そのサイト(VBレスキュー)の内容がお好みであれば、その中の
VB.NET 版のコードを参照してみてください。たとえば
 http://hanatyan.sakura.ne.jp/dotnet/fileio03.htm
 http://hanatyan.sakura.ne.jp/dotnet/fileio04.htm
などといったサンプルが提供されています。

あるいは、Microsoft.JET.OLEDB.4.0 を使って、DataTable に変換するサンプルもあります。
http://hanatyan.sakura.ne.jp/patio/read.cgi?mode=view2&f=251&no=0


> Open "sample.csv" For Input As #intFileNo
> の部分でいくつかエラーが出てしまいました。(宣言はしています)
という事は やはり VB.NET のようですね。そのコードは使えません。

------------
★ VB.NET をお使いの場合は、これ以降の文章は無視してください ★

もしも VB6 用のサンプルをお探しなのであれば、今は亡き「Stadt Homepage for VB」の
「MS形式のCSVテキスト読み書きクラス」が使えるかも知れません。

http://web.archive.org/web/200012100919/http://www.netlaputa.ne.jp/~stadt/vb/p17/csvread.htm
http://web.archive.org/web/200012101011/http://www.netlaputa.ne.jp/~stadt/vb/p17/csvwrite.htm

結果は、1から始まる二次元配列として、data(列番号, 行番号) 形式で解析されるようです。
(細かく検証したわけではないので、保証はしませんけれども)


>     Input #intFileNo, strYubin(lngDatN), strAddre(lngDatN), _
>                 strNamae(lngDatN)

VB6 の Input # ステートメントは、CSV 読み込み用の物ではありません。
本来は、Write # で出力した結果を読み込むための物として用意されています。
(Write の出力結果は CSV 形式に似ていますが、実際には異なる仕様です)

また、一部の文字を含んだデータを正しく処理できないなどの問題もあるので、ご注意あれ。

引用返信 編集キー/
■61493 / inTopicNo.6)  Re[4]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (9回)-(2011/08/16(Tue) 20:23:25)
No61477 (やんまー さん) に返信
> ■No61476 (JRY さん) に返信
>>■No61471 (魔界の仮面弁士 さん) に返信
>
>>>>(0,4)のように、縦と横を指定できるのが理想です。
> >>面倒なら、全データを DataTable か二次元配列に取り込んでおけば、
> >>行・列を指定してデータを取り出す事も容易になるかと思います。
>
>
> 魔界の仮面弁士 さんがおっしゃっているように一度二次元配列に入れれば
> 変数名(0)(4)という感じで取れますよ。
>
>     Dim csvRecords As New System.Collections.ArrayList()
>     Dim tfp As New FileIO.TextFieldParser(filename, _
>       System.Text.Encoding.UTF8 )
>     '区切り文字を,とする
>     tfp.Delimiters = New String() {","}
>
>     While Not tfp.EndOfData
>       'フィールドを読み込む
>       Dim fields As String() = tfp.ReadFields()
>       '保存
>       csvRecords.Add(fields)
>     End While
>     
>     '後始末
>     tfp.Close()
>
>
> ーーー
> こんなふうにすれば
> csvRecords(0)(4)
> に値が入っていると思います。
>

ありがとうございました。
次のように編集しましたが、エラーが発生しました。
Dim wc As WebClient = New WebClient()

wc.DownloadFile( _
csvurl, _
savedir)

Dim csvRecords As New System.Collections.ArrayList()
Dim tfp As New FileIO.TextFieldParser("test.csv", _
System.Text.Encoding.UTF8)
'区切り文字を,とする
tfp.Delimiters = New String() {","}

While Not tfp.EndOfData
'フィールドを読み込む
Dim fields As String() = tfp.ReadFields()
'保存
csvRecords.Add(fields)
Label3.Text = csvRecords(1)(0)
End While
'後始末
tfp.Close()

>Label3.Text = csvRecords(1)(0)
の部分で、
System.ArgumentOutOfRangeException はハンドルされませんでした。
Message=インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメータ名: index
というエラーが出ました。
1,0の部分には、ちゃんと値が入っています。
引用返信 編集キー/
■61496 / inTopicNo.7)  Re[5]: CSVデータの一部分のみ読み込む
□投稿者/ 魔界の仮面弁士 (2309回)-(2011/08/16(Tue) 21:07:56)
No61493 (JRY さん) に返信
> wc.DownloadFile( _
>    csvurl, _
>    savedir)
> Dim tfp As New FileIO.TextFieldParser("test.csv", _
>   System.Text.Encoding.UTF8)

tfp に渡しているのは、WebClient でダウンロードしたファイルではなく
固定名 "test.csv" というファイルのようですが、ファイルの取り違いはありませんか?

また、そのファイルの文字コードが、UTF-8 以外になっている可能性はありませんか?


> Dim csvRecords As New System.Collections.ArrayList()
ArrayList 型でも一応蓄えられますが、この場合は List(Of String()) 型の方が良いかも。


>     Dim fields As String() = tfp.ReadFields()
>     csvRecords.Add(fields)
>     Label3.Text = csvRecords(1)(0)
> End While

Label3.Text への表示処理を、ループ内に入れてしまってはまずいかと。


ループ処理の 1 回目で、先頭行のフィールドが 配列fields に渡されますよね。
次の行ではそれを、csvRecords.Add で蓄えています。

しかしループの 1 回目の段階では、蓄えられた csvRecords は 1 件分だけです。
つまり、csvRecords(0) はあっても、csvRecords(1) はまだありません。
そのため、先のエラーになってしまっているというわけです。


2 行目も読み取りたいなら、ループ処理をそのまま続行させ、
1 行目のさらに後のデータも読み取るようにしましょう。

引用返信 編集キー/
■61497 / inTopicNo.8)  Re[5]: CSVデータの一部分のみ読み込む
□投稿者/ サバール (1回)-(2011/08/16(Tue) 21:10:52)
> >Label3.Text = csvRecords(1)(0)
> の部分で、
> System.ArgumentOutOfRangeException はハンドルされませんでした。
> Message=インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
> パラメータ名: index
> というエラーが出ました。

While〜End WhileのループでcsvRecordsにデータを追加しているのですから、
Label3.Text = csvRecords(1)(0) の行は、このループの後に記載しなければ意味がありません。
このループ内に記載してしまった場合、ループの初回にcsvRecordsにデータを1つ追加した後にcsvRecords(1)の参照しようとしても
csvRecords(1)はまだ追加されていない(この時点ではcsvRecords(0)しか存在しない)わけですから、
当然「インデックスが範囲を超えています...」の例外が発生します。
End Whileの後にLabel3.Text = csvRecords(1)(0)を置けば、(CSVに(1,0)のデータがあれば)ちゃんと動くはずです。
引用返信 編集キー/
■61542 / inTopicNo.9)  Re[6]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (10回)-(2011/08/18(Thu) 20:50:34)
No61496 (魔界の仮面弁士 さん) に返信
> ■No61493 (JRY さん) に返信
>>wc.DownloadFile( _
>> csvurl, _
>> savedir)
>>Dim tfp As New FileIO.TextFieldParser("test.csv", _
>> System.Text.Encoding.UTF8)
>
> tfp に渡しているのは、WebClient でダウンロードしたファイルではなく
> 固定名 "test.csv" というファイルのようですが、ファイルの取り違いはありませんか?
>
> また、そのファイルの文字コードが、UTF-8 以外になっている可能性はありませんか?
>
>
>>Dim csvRecords As New System.Collections.ArrayList()
> ArrayList 型でも一応蓄えられますが、この場合は List(Of String()) 型の方が良いかも。
>
>
>> Dim fields As String() = tfp.ReadFields()
>> csvRecords.Add(fields)
>> Label3.Text = csvRecords(1)(0)
>>End While
>
> Label3.Text への表示処理を、ループ内に入れてしまってはまずいかと。
>
>
> ループ処理の 1 回目で、先頭行のフィールドが 配列fields に渡されますよね。
> 次の行ではそれを、csvRecords.Add で蓄えています。
>
> しかしループの 1 回目の段階では、蓄えられた csvRecords は 1 件分だけです。
> つまり、csvRecords(0) はあっても、csvRecords(1) はまだありません。
> そのため、先のエラーになってしまっているというわけです。
>
>
> 2 行目も読み取りたいなら、ループ処理をそのまま続行させ、
> 1 行目のさらに後のデータも読み取るようにしましょう。

ありがとうございます。
ですが、指定した場所を正常に読み取りませんでした。
指定したところの7個以上先を読み取ってしまいます。
どうすればいいでしょうか?
引用返信 編集キー/
■61549 / inTopicNo.10)  Re[7]: CSVデータの一部分のみ読み込む
□投稿者/ shu (944回)-(2011/08/19(Fri) 07:41:20)
No61542 (JRY さん) に返信

> ありがとうございます。
> ですが、指定した場所を正常に読み取りませんでした。
> 指定したところの7個以上先を読み取ってしまいます。
> どうすればいいでしょうか?
どのように修正されたのか分かりませんので修正後のプログラムを提示
した方が良いと思います。
引用返信 編集キー/
■61551 / inTopicNo.11)  Re[8]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (11回)-(2011/08/19(Fri) 09:05:47)
No61549 (shu さん) に返信
> ■No61542 (JRY さん) に返信
>
>>ありがとうございます。
>>ですが、指定した場所を正常に読み取りませんでした。
>>指定したところの7個以上先を読み取ってしまいます。
>>どうすればいいでしょうか?
> どのように修正されたのか分かりませんので修正後のプログラムを提示
> した方が良いと思います。
現在のプログラムは次のようになっています。<br>
Dim csvRecords As New System.Collections.ArrayList()
Dim tfp As New FileIO.TextFieldParser("test.csv", _
System.Text.Encoding.Default)
'区切り文字を,とする
tfp.Delimiters = New String() {","}

While Not tfp.EndOfData
'フィールドを読み込む
Dim fields As String() = tfp.ReadFields()
'保存
csvRecords.Add(fields)

End While
Label1.Text = csvRecords(279)(3)
'問題点 7個以上先を読み取ってしまう(横の軸)
引用返信 編集キー/
■61553 / inTopicNo.12)  Re[9]: CSVデータの一部分のみ読み込む
□投稿者/ shu (945回)-(2011/08/19(Fri) 09:47:27)
No61551 (JRY さん) に返信

> '問題点 7個以上先を読み取ってしまう(横の軸)

HasFieldsEnclosedInQuotes がTrueになっているとすると
"aaa,bbbb"

"aaa
bbb" ※2行分
を1つの項目としてみますが、これは1つの項目として考えてよいでしょうか?
駄目な場合はFalseにすると良いかもしれません。
引用返信 編集キー/
■61554 / inTopicNo.13)  Re[9]: CSVデータの一部分のみ読み込む
□投稿者/ サバール (2回)-(2011/08/19(Fri) 09:50:05)
2011/08/19(Fri) 09:52:54 編集(投稿者)

No61551 (JRY さん) に返信
> '問題点 7個以上先を読み取ってしまう(横の軸)

CSVの横方向のデータがずれているということでしょうか?
可能性としては、CSVの該当行のデータが思うように分解できていない可能性がありますので、
差し支えなければ、上記コードでの

> Label1.Text = csvRecords(279)(3)

の値と、該当するCSVの行のデータ(カンマ等の区切り文字を含めて)を投稿してもらえますでしょうか?

また、7個以上とありますが、このケースでは何個分ずれているのでしょうか?(追記分)
引用返信 編集キー/
■61562 / inTopicNo.14)  Re[10]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (12回)-(2011/08/19(Fri) 14:15:27)
No61554 (サバール さん) に返信
> 2011/08/19(Fri) 09:52:54 編集(投稿者)
>
> ■No61551 (JRY さん) に返信
>>'問題点 7個以上先を読み取ってしまう(横の軸)
>
> CSVの横方向のデータがずれているということでしょうか?
> 可能性としては、CSVの該当行のデータが思うように分解できていない可能性がありますので、
> 差し支えなければ、上記コードでの
>
>>Label1.Text = csvRecords(279)(3)
>
> の値と、該当するCSVの行のデータ(カンマ等の区切り文字を含めて)を投稿してもらえますでしょうか?
>
> また、7個以上とありますが、このケースでは何個分ずれているのでしょうか?(追記分)

test.csvとなっていますが、今回は東京電力の電力使用状況CSVを使用しています。(juyo-j.csv)
データURL→http://www.tepco.co.jp/forecast/html/images/juyo-j.csv
引用返信 編集キー/
■61563 / inTopicNo.15)  Re[11]: CSVデータの一部分のみ読み込む
□投稿者/ サバール (4回)-(2011/08/19(Fri) 15:19:59)
No61562 (JRY さん) に返信
> test.csvとなっていますが、今回は東京電力の電力使用状況CSVを使用しています。(juyo-j.csv)
> データURL→http://www.tepco.co.jp/forecast/html/images/juyo-j.csv

上記CSVを見てみましたが、7個も横にずれるようなデータは入っていません。
こんなものを見せられても、残念ながら、何の解決にもなりません。

実際、test.csvを使ってプログラムを動かして、現在の問題が出ているとのことなので、
test.csvを見せてもらわないと、誰も回答できませんよ。
(おそらく、test.csvに問題があるのでは?)

> 差し支えなければ、上記コードでの
>
>> Label1.Text = csvRecords(279)(3)
>
> の値と、該当するCSVの行のデータ(カンマ等の区切り文字を含めて)を投稿してもらえますでしょうか?
>
> また、7個以上とありますが、このケースでは何個分ずれているのでしょうか?(追記分)

と先ほど投稿したのですが、これについてはどうでしょう?
引用返信 編集キー/
■61570 / inTopicNo.16)  Re[12]: CSVデータの一部分のみ読み込む
□投稿者/ JRY (14回)-(2011/08/19(Fri) 20:24:10)
2011/08/19(Fri) 20:25:38 編集(投稿者)

No61563 (サバール さん) に返信
> ■No61562 (JRY さん) に返信
>>test.csvとなっていますが、今回は東京電力の電力使用状況CSVを使用しています。(juyo-j.csv)
>>データURL→http://www.tepco.co.jp/forecast/html/images/juyo-j.csv
>
> 上記CSVを見てみましたが、7個も横にずれるようなデータは入っていません。
> こんなものを見せられても、残念ながら、何の解決にもなりません。
>
> 実際、test.csvを使ってプログラムを動かして、現在の問題が出ているとのことなので、
> test.csvを見せてもらわないと、誰も回答できませんよ。
> (おそらく、test.csvに問題があるのでは?)
>
>>差し支えなければ、上記コードでの
> >
> >> Label1.Text = csvRecords(279)(3)
> >
>>の値と、該当するCSVの行のデータ(カンマ等の区切り文字を含めて)を投稿してもらえますでしょうか?
> >
>>また、7個以上とありますが、このケースでは何個分ずれているのでしょうか?(追記分)
>
> と先ほど投稿したのですが、これについてはどうでしょう?

ありがとうございます。
この用件は難しそうなので、他の手を考えてみます。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=61569
に、この目的などが書いてあります。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -