• 締切済み

vb2010でCSVファイルを並び替えて保存方法

初心者なので申し訳ございません いろいろとネットで調べてみたのですが、うまく出来ないので質問させて下さい。 CSVファイルで以下の様なデーターがあります。 バナナ,oooo300,xxxx リンゴ,oooo200,xxxx パイナップル,oooo500,xxxx 3番目の項目を数字の大きい順に並び替えて別ファイルに保存したいのです。 ファイルを読み込む ↓ 並び替える ↓ 書き込む ↓ ファイル保存 の順番と思ってやっているのですが・・・・ 並び替え方法が分かりません 宜しくお願いします。m(__)m

みんなの回答

回答No.10

方法として、自分でソートする方法もありますが(ソートアルゴリズムでぐぐってみるといっぱいでてきます) 、VB2010ということなので一番簡単な方法は以下の方法だと思います。 <並び替えの部分だけ> (1)数字の部分を抜き出し、コレクション(arraylist)に投入する。 (2)コレクションのソート機能を利用してソートする。 (3)ソート後、もとのリストがどの位置に移動したか移動後の添字を取得する。 (4)もとのソースを移動後の添字に準じて、配列(コレクションでもok)へ格納する。 なお、上記方法にて行なった場合、同一キーが存在すると不具合が起こるります。 そこで、元のファイルのキーとなる部分にはあらかじめ連番を振っておくことで回避できるかと思います。    300、200、500ー> 3001、2002、5003 みたいに...(振る連番桁数は絶対に桁変更が起きないように    桁数を揃えてね!)これをソートのキーとする。 ソートの方法は色々とあるようですが、自分で導きだす筋道をしっかりと検討して、その方法が一番効率がよい かがポイントとなります。やり方によっては、非常にマシンに負担のかかる処理だったり、件数が多ければ多いほど 、反比例的に遅くなってくるとかなどの現象が発生したりします。  いきなりソースをごちゃごちゃと弄るよりも、紙ベースでしっかりと方式を検討しましょ!   

回答No.9

おはよう御座います。 昨日は、何度も混乱させしまうようなことばかりですいませんでした。 回答する場所がなくなってしまいましたので、ここから返信させていただきました。 実際のCSVファイルがありませんので、十分なテストが出来ていませんので、万が一昨日のサンプルを参考にされる場合は、テストを十分に行ってください。 とくに、降順、昇順の部分は、ひとそれぞれのプログラムの仕方が違いますので、要注意です。 >あとファイルのreaderBのcloseを入力すれば良いのですね^^ 上記のように、KenKen1978さんは十分な力を持っていますので、不備な点はご自分で直してください。 >もうだんだん迷路に入ってしまったので 相当、頑張りましたね。 >いろいろと試してみたのですが プログラムする際は、重要な点だと思います。これからも試行錯誤を続けてください。(一部試行錯誤が禁止されている部分もありますが) >bybalsendercaseさんはレベルの高い部分 それは、ないない、私もVB初心者ですから。 CSVファイルの順番を替えてしまいましたが、もとに戻せますか? 方法は、どこか途中で記入しましたが、それでも、戻せない場合は再度返信してください。 それでは、残りの部部をがんばってください。

回答No.8

何回もすいません、文章を読み違えてしまいました。KenKen1978 さんの場合は降順ですね。コードを追加してください。 artest.Sort() '並べ替え artest.Reverse() '降順   ←この一文を追加してください。 私のサンプルは、非合法ですので、最終手段でお願いします。(Sortを使っているため)

KenKen1978
質問者

お礼

いろいろと教えて下さり、本当に感謝しています 自分の力が無いので実現できませんでした・・・・ 大変申し訳なかったです・・・・・ 別に質問をUPしました スイマセン・・・・・

回答No.7

たびたび申し訳ありません、文字制限のため書ききれませんでしたので再度投稿させて頂きます。 それと先ほどのサンプルはかなり、悪い例ですので他の方の回答で試して、それでも難しい場合に使用してください。 KenKen1978 さんのCSVファイルの数字が7桁以内を想定しています。 数字が、下記のように、全てが7桁ではない事を想定してIf文を挿入しています。 バナナ,oooo300,xxxx リンゴ,oooo200,xxxx パイナップル,oooo500,xxxx イチゴ,50,xxxx 数字が全部7桁ですと、If文は必要ありません。 それと、最後にtest3.csvに保存するときにCInt(st2)のように、数値に変換していますがこれも必要ありません。 CInt(st2)→st2 実験する際プログラムの先頭に下記のコードを入れておくと、実験が楽になります。 IO.File.Delete(Application.StartupPath & "\test2.csv") 'test2.csv削除する IO.File.Delete(Application.StartupPath & "\test3.csv") 'test3.csv削除する 解決を目指してがんばりましょう。

回答No.6

KenKen1978さん、こんにちは。かなり非合法ではありますが、超簡単なサンプルを作成しましたので、コピペして動作を確認してみてください。できればプログラムの先頭で'test2.csvと'test3.csvを削除してください。 Dim reader As New IO.StreamReader(Application.StartupPath & "\test1.csv", System.Text.Encoding.GetEncoding("Shift-JIS")) Dim line As String 'CSVファイルの一行 Dim item1() As String '配列の各項目 Dim st1 As String 'item(0) Dim st2 As String 'item(1) Dim st3 As String 'item(2) Dim int06 As String 'item(1)の文字数が1桁の場合は、先頭に000000を付ける。 Dim int05 As String 'item(1)の文字数が1桁の場合は、先頭に00000を付ける。 Dim int04 As String 'item(1)の文字数が1桁の場合は、先頭に0000を付ける。 Dim int03 As String 'item(1)の文字数が2桁の場合は、先頭に000を付ける。 Dim int02 As String 'item(1)の文字数が2桁の場合は、先頭に00を付ける。 Dim int01 As String 'item(1)の文字数が2桁の場合は、先頭に0を付ける。 Dim stlen As Integer 'item(1)の文字数 line = reader.ReadLine Do Until IsNothing(line) item1 = line.Split(",") st1 = item1(0) st2 = item1(1) st3 = item1(2) stlen = st2.Length 'item1(1)の文字数を調べる。 If stlen = 1 Then 'item(1)の文字数が1桁の場合は、先頭に000000を付ける。 int06 = "000000" & st2 test2(int06, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 2 Then 'item(1)の文字数が1桁の場合は、先頭に00000を付ける。 int05 = "00000" & st2 test2(int05, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 3 Then 'item(1)の文字数が1桁の場合は、先頭に0000を付ける。 int04 = "0000" & st2 test2(int04, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 4 Then 'item(1)の文字数が2桁の場合は、先頭に000を付ける。 int03 = "000" & st2 test2(int03, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 5 Then 'item(1)の文字数が2桁の場合は、先頭に00を付ける。 int02 = "00" & st2 test2(int02, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 6 Then 'item(1)の文字数が2桁の場合は、先頭に0を付ける。 int01 = "0" & st2 test2(int01, st1, st3) '順番を並び替えてtest2.csvに保存 ElseIf stlen = 7 Then test2(st2, st1, st3) '順番を並び替えてtest2.csvに保存 End If line = reader.ReadLine Loop reader.Close() Dim artest As New List(Of String) 'test2.csvの一行をリストにする。 Dim readtest As New IO.StreamReader(Application.StartupPath & "\test2.csv") Dim testlline As String 'test2.csvの一行 testlline = readtest.ReadLine Do Until IsNothing(testlline) artest.Add(testlline) 'test2.csvの一行を、artestにAddする testlline = readtest.ReadLine Loop readtest.Close() artest.Sort() '並べ替え Dim txt As String '要素 Dim item2() As String 'test2.csvファイルの各項目 Dim txt1 As String 'item2(0) Dim txt2 As String 'item2(1) Dim txt3 As String 'item2(2) For Each txt In artest '再度ファイルの一行を分解する。  item2 = txt.Split(",") txt1 = item2(0) txt2 = item2(1) txt3 = item2(2) test3(txt2, txt1, txt3) 'test3ファイルに保存 Next End Sub Private Sub test2(ByVal st1 As String, ByVal st2 As String, ByVal st3 As String) Dim writer As New IO.StreamWriter(Application.StartupPath & "\test2.csv", True) writer.WriteLine(st1 & "," & st2 & "," & st3) writer.Close() End Sub Private Sub test3(ByVal st1 As String, ByVal st2 As String, ByVal st3 As String) 'ファイルパスは、Application.StartupPathになってますが、"C:\~"のように、任意でよい。 Dim writer As New IO.StreamWriter(Application.StartupPath & "\test3.csv", True) writer.WriteLine(st1 & "," & CInt(st2) & "," & st3) writer.Close() End Sub >いろいろとネットで調べてみたのですが←大変立派なことだと思います。文字数制限が~ 他にも書き足りないことが~ プログラムの先頭にファイルを削除するコードがあったんですが、後他のかたの回答も全部良い回答です。 制限が~

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.4

1)ODBCTextDriverでCSVファイルへ接続。 2)項目3をキーとして、降順に取得 3)取得した行を「別ファイル」に出力

回答No.3

Module Module1 '果物データ構造体 Structure KUDAMONO_DATA_STRUCT '果物名 Public strFruitsName As String '説明 Public strScript As String '価格 Public nPrice As Integer '予備説明2 Public strScript2 As String End Structure Public gAllKudamonoData() As KUDAMONO_DATA_STRUCT '果物データ Public gnAllKudamonoNum As Integer '果物データ総件数 Sub KudamonoDataBSort(ByVal nEnd As Integer, ByVal UpperFlag As Byte) Dim Loop1 As Integer Dim Loop2 As Integer Dim Tmp As KUDAMONO_DATA_STRUCT For Loop1 = 1 To nEnd - 1 Tmp.nPrice = gAllKudamonoData(Loop1).nPrice Tmp.strFruitsName = gAllKudamonoData(Loop1).strFruitsName Tmp.strScript = gAllKudamonoData(Loop1).strScript Tmp.strScript2 = gAllKudamonoData(Loop1).strScript2 For Loop2 = Loop1 To 1 Step -1 If (UpperFlag = 1) Then If gAllKudamonoData(Loop2 - 1).nPrice > Tmp.nPrice Then gAllKudamonoData(Loop2).nPrice = gAllKudamonoData(Loop2 - 1).nPrice gAllKudamonoData(Loop2).strFruitsName = gAllKudamonoData(Loop2 - 1).strFruitsName gAllKudamonoData(Loop2).strScript = gAllKudamonoData(Loop2 - 1).strScript gAllKudamonoData(Loop2).strScript2 = gAllKudamonoData(Loop2 - 1).strScript2 Else Exit For End If End If If (UpperFlag = 2) Then If gAllKudamonoData(Loop2 - 1).nPrice < Tmp.nPrice Then gAllKudamonoData(Loop2).nPrice = gAllKudamonoData(Loop2 - 1).nPrice gAllKudamonoData(Loop2).strFruitsName = gAllKudamonoData(Loop2 - 1).strFruitsName gAllKudamonoData(Loop2).strScript = gAllKudamonoData(Loop2 - 1).strScript gAllKudamonoData(Loop2).strScript2 = gAllKudamonoData(Loop2 - 1).strScript2 Else Exit For End If End If Next Loop2 gAllKudamonoData(Loop2).nPrice = Tmp.nPrice gAllKudamonoData(Loop2).strFruitsName = Tmp.strFruitsName gAllKudamonoData(Loop2).strScript = Tmp.strScript gAllKudamonoData(Loop2).strScript2 = Tmp.strScript2 Next Loop1 End Sub End Module ソートボタンなんかでKudamonoDataBSort(データ総数、1:昇順 2:降順)関数をCallすれば 入れ替えソートをやってくれるはずです。

参考URL:
http://japan.internet.com/developer/20080418/26.html
KenKen1978
質問者

お礼

きっと出来ると思ってeternazx9rさんの教えて下さったコードも自分用に置き換えて試してみました・・・・ しかし、僕がアホ過ぎて失敗に終わりました。 大変失礼しました・・・・ 新しく自分のコードを入れて質問を再UPしました。 スイマセン

回答No.2

やり方としては、 1.データを入れるための構造体を用意して、Dim データ() As データ構造体 で宣言しておく 2.ファイルを開いて行数を取得してファイルを閉じる 3.行数=データ件総数なので Redim データ(行数)で改めて宣言 4.またファイルを開いて一件1項目ずつデータを格納していきファイルを閉じる 5.バブルソートをする 6.ファイルを開いて一行分の情報をPrintLineで書き込んでファイルを閉じる というような流れになります。 まずは「バブルソート VB」で検索してみましょう。 サンプルがどこかに転がっているはずです。 5.のバブルソートは データの入っている配列を先頭から次の配列のデータと大小の比較していき(この場合は価格のところですね)、 昇順或いは降順の状態にマッチしていたら入れ替える、という処理を行います。 入れ替えの方法は バッファ←A A←B B←バッファ という順序でできますよ。

参考URL:
http://www5d.biglobe.ne.jp/~tomoya03/shtml/algorithm/BSort.htm
  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.1

> 並び替え方法が分かりません 原始的な方法は分からないとかじゃないと思う。 If 前の行の数値 < 後の行の数値 Then  データを入替える End If これだけのことでは? それを繰り返すのが一番単純なバブルソート。 クイックソートくらいになればちょっと教えてもらわないと ぱっと見では理解できない事もあるだろうけど、 データの並び替えなんてプログラムの学校なり、入門書なり 入門サイトなりで紹介されている初歩的なもの。 自分で勉強して分からないなら、プログラム自体しない方がいい。

KenKen1978
質問者

補足

おっしゃっている事は凄く良く分かるのですが、その方法を教えて下さると助かるのですが・・・・ 現在ReadLineで読み込んでsplitで分けてIfで比較しようとしていたのですが、どの様に次の行と(前の行と)比較したらよいのやら・・・・ 手厳しいお言葉おそれいります・・・・

関連するQ&A