こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

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

初心者なので申し訳ございません
いろいろとネットで調べてみたのですが、うまく出来ないので質問させて下さい。
CSVファイルで以下の様なデーターがあります。

バナナ,oooo300,xxxx
リンゴ,oooo200,xxxx
パイナップル,oooo500,xxxx

3番目の項目を数字の大きい順に並び替えて別ファイルに保存したいのです。

ファイルを読み込む

並び替える

書き込む

ファイル保存

の順番と思ってやっているのですが・・・・
並び替え方法が分かりません

宜しくお願いします。m(__)m

投稿日時 - 2012-07-25 11:21:48

QNo.7609579

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.10

方法として、自分でソートする方法もありますが(ソートアルゴリズムでぐぐってみるといっぱいでてきます)
、VB2010ということなので一番簡単な方法は以下の方法だと思います。
<並び替えの部分だけ>
(1)数字の部分を抜き出し、コレクション(arraylist)に投入する。
(2)コレクションのソート機能を利用してソートする。
(3)ソート後、もとのリストがどの位置に移動したか移動後の添字を取得する。
(4)もとのソースを移動後の添字に準じて、配列(コレクションでもok)へ格納する。

なお、上記方法にて行なった場合、同一キーが存在すると不具合が起こるります。
そこで、元のファイルのキーとなる部分にはあらかじめ連番を振っておくことで回避できるかと思います。

   300、200、500ー> 3001、2002、5003 みたいに...(振る連番桁数は絶対に桁変更が起きないように
   桁数を揃えてね!)これをソートのキーとする。
ソートの方法は色々とあるようですが、自分で導きだす筋道をしっかりと検討して、その方法が一番効率がよい
かがポイントとなります。やり方によっては、非常にマシンに負担のかかる処理だったり、件数が多ければ多いほど
、反比例的に遅くなってくるとかなどの現象が発生したりします。
 いきなりソースをごちゃごちゃと弄るよりも、紙ベースでしっかりと方式を検討しましょ!



  

投稿日時 - 2012-08-10 10:46:00

おはよう御座います。
昨日は、何度も混乱させしまうようなことばかりですいませんでした。
回答する場所がなくなってしまいましたので、ここから返信させていただきました。

実際のCSVファイルがありませんので、十分なテストが出来ていませんので、万が一昨日のサンプルを参考にされる場合は、テストを十分に行ってください。

とくに、降順、昇順の部分は、ひとそれぞれのプログラムの仕方が違いますので、要注意です。

>あとファイルのreaderBのcloseを入力すれば良いのですね^^
上記のように、KenKen1978さんは十分な力を持っていますので、不備な点はご自分で直してください。


>もうだんだん迷路に入ってしまったので
相当、頑張りましたね。


>いろいろと試してみたのですが
プログラムする際は、重要な点だと思います。これからも試行錯誤を続けてください。(一部試行錯誤が禁止されている部分もありますが)


>bybalsendercaseさんはレベルの高い部分
それは、ないない、私もVB初心者ですから。

CSVファイルの順番を替えてしまいましたが、もとに戻せますか?
方法は、どこか途中で記入しましたが、それでも、戻せない場合は再度返信してください。
それでは、残りの部部をがんばってください。

投稿日時 - 2012-07-29 05:19:57

何回もすいません、文章を読み違えてしまいました。KenKen1978 さんの場合は降順ですね。コードを追加してください。

artest.Sort() '並べ替え
artest.Reverse() '降順   ←この一文を追加してください。

私のサンプルは、非合法ですので、最終手段でお願いします。(Sortを使っているため)

投稿日時 - 2012-07-27 20:23:13

お礼

いろいろと教えて下さり、本当に感謝しています

自分の力が無いので実現できませんでした・・・・

大変申し訳なかったです・・・・・
別に質問をUPしました

スイマセン・・・・・

投稿日時 - 2012-07-28 03:54:40

たびたび申し訳ありません、文字制限のため書ききれませんでしたので再度投稿させて頂きます。
それと先ほどのサンプルはかなり、悪い例ですので他の方の回答で試して、それでも難しい場合に使用してください。

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削除する


解決を目指してがんばりましょう。

投稿日時 - 2012-07-26 16:34:09

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
>いろいろとネットで調べてみたのですが←大変立派なことだと思います。文字数制限が~ 他にも書き足りないことが~ プログラムの先頭にファイルを削除するコードがあったんですが、後他のかたの回答も全部良い回答です。 制限が~

投稿日時 - 2012-07-26 08:28:52

ANo.4

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

投稿日時 - 2012-07-25 22:32:13

ANo.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

投稿日時 - 2012-07-25 17:00:38

お礼

きっと出来ると思ってeternazx9rさんの教えて下さったコードも自分用に置き換えて試してみました・・・・
しかし、僕がアホ過ぎて失敗に終わりました。

大変失礼しました・・・・

新しく自分のコードを入れて質問を再UPしました。

スイマセン

投稿日時 - 2012-07-28 03:57:11

ANo.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

投稿日時 - 2012-07-25 15:46:24

ANo.1

> 並び替え方法が分かりません
原始的な方法は分からないとかじゃないと思う。

If 前の行の数値 < 後の行の数値 Then
 データを入替える
End If
これだけのことでは?
それを繰り返すのが一番単純なバブルソート。

クイックソートくらいになればちょっと教えてもらわないと
ぱっと見では理解できない事もあるだろうけど、
データの並び替えなんてプログラムの学校なり、入門書なり
入門サイトなりで紹介されている初歩的なもの。
自分で勉強して分からないなら、プログラム自体しない方がいい。

投稿日時 - 2012-07-25 13:45:33

補足

おっしゃっている事は凄く良く分かるのですが、その方法を教えて下さると助かるのですが・・・・

現在ReadLineで読み込んでsplitで分けてIfで比較しようとしていたのですが、どの様に次の行と(前の行と)比較したらよいのやら・・・・

手厳しいお言葉おそれいります・・・・

投稿日時 - 2012-07-25 15:00:10

あなたにオススメの質問