• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:csvを新ファイルに8番目で大きい順に並び替え)

csvを新ファイルに8番目で大きい順に並び替え

このQ&Aのポイント
  • VB2010です。Itm(7)を基準に数字の大きい順に並び替えたい。CSVは全部で19列あり、行数はだいたい100行ぐらいです。
  • Do Untilループを使用して、ファイル内の各行を読み取ります。最初の行は、新しいファイルに書き込まれます。2番目以降の行は、新しいファイルの適切な位置に書き込まれます。
  • Itm(7)の値が現在の行のItm(7)の値よりも大きい場合、その行を新しいファイルに書き込みます。それ以外の場合、現在の行の位置に書き込みます。最後に、元のファイルを削除し、新しいファイルの名前を変更します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

またまた、やっちゃったみたいです。質問は「大きい順に並び替え」ですよね。 先ほどの物は「小さい順」でした。 下記のコードですと「小さい順」になります。 For l1 = 1 To dtcnt For l2 = 0 To dtcnt - 1 - l1 Dim txt1 As String = data(l2) Dim txt2 As String = data(l2 + 1) Dim txtint1 As Integer = txt1.IndexOf(",") 'カンマの位置を取得 Dim txtint2 As Integer = txt2.IndexOf(",") 'カンマの位置を取得 If CInt(data(l2).Substring(0, txtint1)) < CInt(data(l2 + 1).Substring(0, txtint2)) Then uptmp = data(l2) '入れ替え前の上の値 downtmp = data(l2 + 1) '入れ替え前の下の値 data(l2) = downtmp '入れ替え後の上の値 data(l2 + 1) = uptmp '入れ替え後の下の値 End If Next 「大きい順に並び替え」は下記のようになります。 For l1 = 0 To dtcnt - 1 For l2 = l1 + 1 To dtcnt - 1 Dim txt1 As String = data(l1) Dim txt2 As String = data(l2) Dim txtint1 As Integer = txt1.IndexOf(",") 'カンマの位置を取得 Dim txtint2 As Integer = txt2.IndexOf(",") 'カンマの位置を取得 If CInt(data(l1).Substring(0, txtint1)) < CInt(data(l2).Substring(0, txtint2)) Then uptmp = data(l2) '入れ替え前の上の値 downtmp = data(l1) '入れ替え前の下の値 data(l2) = downtmp '入れ替え後の上の値 data(l1) = uptmp '入れ替え後の下の値 End If Next 何回もすみません。(汗 もう謝り様がありません、返すことばもありません。 ごめんなさ~い。 それと、並び替えの画像が下記URLでわかりやすく書かれています。 [いろいろなソートアルゴリズム] http://www.ibe.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/ あと、Sortで並べ替えは非合法だと思っていましたが、kmeeさんの回答によると、私が前回提案させていただいた、 リスト.Sort() '並べ替え リスト.Reverse() '降順  もありのようですね。 Sortの '並べ替えは、数字の大小ではなく、辞書の順番で並べ替えるため少々危険と思い「非合法」といいましたが、「合法」であればSortの '並べ替のほうがず~っと簡単です。

KenKen1978
質問者

お礼

でも、やっ~~~~~とクリア出来たので今日はここで並び替えは一休みかなぁ・・・ 明日からsortに関してはご提案のURLからしっかりx100勉強します!!! 本当にご丁寧にお付き合い下さってありがとうございます^^ 最後に初心者なので savefile2(data(l2)) Private Sub savefile2(ByVal linetest As String) ↑の方法があるのも初めてしりました・・・・・(恥ずかしながら・・・) 凄く便利ですね^^ 一つの質問で沢山の勉強をさせて頂きました!!! この感謝を言葉では言い表せない程ですが、 本当にありがとうございましたm(__)m

KenKen1978
質問者

補足

いえいえ!!! 小さい順は自分でなんと判明出来ましたので、勉強になりました~~~~ たしかに今後の事を考えるとsortもしっかり勉強するべきだと思います

その他の回答 (5)

回答No.5

大変、大変申し訳あいりません。もう一箇所ありました。 気にはなっていたのですが、VBが自動変換してくれると思い、そのままにいしていましたが、自動変換はしてくれないようです。 誤 If data(l2).Substring(0, txtint1) < data(l2 + 1).Substring(0, txtint2) Then 正 If CInt(data(l2).Substring(0, txtint1)) < CInt(data(l2 + 1).Substring(0, txtint2)) Then Integer型に変換してください。 重ね重ねお詫び申し上げます。 おかしいな~   自動変換してくれないのかな~

KenKen1978
質問者

お礼

あああああ 僕の勘違いです!!! スイマセン きちんとsavefile2で並び替えられています!!! あとファイルのreaderBのcloseを入力すれば良いのですね^^ 早とちりしてしまいますた・・・・m(__)m

KenKen1978
質問者

補足

えっ~~と 全部やってみました! 始めのsavefile1の時点で数字の小さい順に並びえかられているファイルが出力されていますね^^ 次の構文にはいるとなぜか順序がまたバラバラになっているのです・・・・ そしてCSVファイルを開こうとするとまだVBが開いていると通知メッセージが出てきます・・・・ どうしてだろう・・・・ もう少しみたいなので自分でも足掻いてみます!

回答No.4

大変申し訳ありません。 訂正です。 少し実験したところ、エラーがありました。 コードの最初の部分で ↓、 Dim data As New List(Of String) 'リスト dataをStringに指定してあるのに、下記のコードをIntegerに指定してしまいました。 誤 Dim uptmp As Integer '小さい値 Dim downtmp As Integer '入れ替え前の下の要素 正 Dim uptmp As String '小さい値 Dim downtmp As String '入れ替え前の下の要素 すいません。直してください。 こんな単純なミスをするようでは、回答できませんね。

KenKen1978
質問者

お礼

いえいえ そんなご回答本当に感謝しています~~~ 僕もよく小数点まで必要な宣言でIntegerを使っていて、どうしてなんだろう・・・って悩んで自分の注意深さがない事に思い知らされます^^; が、bybalsendercaseさんはレベルの高い部分でのミスだと思いますので羨ましいです!!!

回答No.3

文字制限がありましたので、途中までしか記入できませんでしたので、続きです。 KenKen1978さんのコードは良くできていましたので、それをそのまま使いたかったのですが、私のレベルでは少々無理のようでしたので、こんな風になってしまいました、すいません。できれば、KenKen1978さんのコードでどこがどのようにおかしいのか、具体的な情報を頂ければ、他の方がKenKen1978さんのコードを直してもらえると思います。 前回の回答の中で、CSVファイルの順番を入れ替えてしまいましたが、下記のコードの部分を変更すれば、入れ替えをする必要はありません。 Dim txtint1 As Integer = txt1.IndexOf(",") 'カンマの位置を取得 Dim txtint2 As Integer = txt2.IndexOf(",") 'カンマの位置を取得 降順する場所のカンマの位置を取得すれば、CSVファイルの順番を入れ替えなくても、そのまま降順できます。 CSVファイルの順番を入れ替を入れ替えた場所のコードは↓ savefile1(s8, s1, s2, s3, s4, s5, s6, s7, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19)       ↑ ここで入れ替えてます。 先ほどの回答の続きに下記のコードを追加してください。 Private Sub savefile1(s1 As String, s2 As String, s3 As String, s4 As String, s5 As String, s6 As String, s7 As String, s8 As String, s9 As String, s10 As String, s11 As String, s12 As String, s13 As String, s14 As String, s15 As String, s16 As String, s17 As String, s18 As String, s19 As String) Dim writer As New IO.StreamWriter("ここに、任意のパスを入れる", True) writer.WriteLine(s1 & "," & s2 & "," & s3 & "," & s4 & "," & s5 & "," & s6 & "," & s7 & "," & s8 & "," & s9 & "," & s10 & "," & s11 & "," & s12 & "," & s13 & "," & s14 & "," & s15 & "," & s16 & "," & s17 & "," & s18 & "," & s19) writer.Close() 'ファイル保存のメソッド End Sub Private Sub savefile2(ByVal linetest As String) Dim writer As New IO.StreamWriter("ここに、任意のパスを入れる", True) writer.WriteLine(linetest) writer.Close() 'ファイル保存のメソッド End Sub 不明点は、再度質問してね。 他の方が良い回答をしてくれると思います。 あともうひといきです、頑張ってください。

KenKen1978
質問者

お礼

ここまでの長文でご説明頂けるとは本当に光栄です! 迷路から脱出できそうです~~~~~♪

回答No.2

こんにちは、だいぶ頑張ったようですね。(拍手    サンプルを作成しましたので、参考に  文字制限がありますので、詳細は、説明できません。 KenKen1978さんのコードをそのまま利用したかったのですが、少し難解なてんがありまして、できません Dim data As New List(Of String) 'リスト Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click IO.File.Delete(Application.StartupPath & "\test2.txt") IO.File.Delete(Application.StartupPath & "\test3.txt") Dim readerA As New IO.StreamReader(Application.StartupPath & "\test1.txt", System.Text.Encoding.GetEncoding("shift-jis")) Dim line1 As String 'CSVファイルの一行 Dim itm1() As String '配列の各項目 Dim s1 As String, s2 As String, s3 As String, s4 As String, s5 As String, s6 As String, s7 As String, s8 As String, s9 As String, s10 As String, s11 As String, s12 As String, s13 As String, s14 As String, s15 As String, s16 As String, s17 As String, s18 As String, s19 As String line1 = readerA.ReadLine Do Until IsNothing(line1) itm1 = line1.Split(",") s1 = itm1(0) '書く場所がないので、ここに記入します s2 = itm1(1) 'なるべくKenKen1978 さんのコードに s3 = itm1(2) '近づけたつもりですが、こんな風に s4 = itm1(3) 'してしまいました。 s5 = itm1(4) s6 = itm1(5) s7 = itm1(6) s8 = itm1(7) s9 = itm1(8) s10 = itm1(9) s11 = itm1(10) s12 = itm1(11) s13 = itm1(12) s14 = itm1(13) s15 = itm1(14) s16 = itm1(15) s17 = itm1(16) s18 = itm1(17) s19 = itm1(18) savefile1(s8, s1, s2, s3, s4, s5, s6, s7, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19) line1 = readerA.ReadLine Loop '項目数が多いためテストはしてません readerA.Close() Dim readerB As New IO.StreamReader(Application.StartupPath & "\test2.txt") Dim line2 As String 'CSVファイルの一行 Dim itm2() As String '配列の各項目 Dim dtcnt As Integer 'リストの数 Dim st1 As String, st2 As String, st3 As String, st4 As String, st5 As String, st6 As String, st7 As String, st8 As String, st9 As String, st10 As String, st11 As String, st12 As String, st13 As String, st14 As String, st15 As String, st16 As String, st17 As String, st18 As String, st19 As String line2 = readerB.ReadLine Do Until IsNothing(line2) data.Add(line2) 'CSVファイルの一行をリストにAddする itm2 = line2.Split(",") st1 = itm2(0) st2 = itm2(1) st3 = itm2(2) st4 = itm2(3) st5 = itm2(4) st6 = itm2(5) st7 = itm2(6) st8 = itm2(7) st9 = itm2(8) st10 = itm2(9) st11 = itm2(10) st12 = itm2(11) st13 = itm2(12) st14 = itm2(13) st15 = itm2(14) st16 = itm2(15) st17 = itm2(16) st18 = itm2(17) st19 = itm2(18) line2 = readerB.ReadLine Loop dtcnt = data.Count Dim uptmp As Integer '小さい値 Dim downtmp As Integer '入れ替え前の下の要素 Dim l1 As Integer 'ループカウンター Dim l2 As Integer 'ループカウンター For l1 = 1 To dtcnt For l2 = 0 To dtcnt - 1 - l1 Dim txt1 As String = data(l2) Dim txt2 As String = data(l2 + 1) Dim txtint1 As Integer = txt1.IndexOf(",") Dim txtint2 As Integer = txt2.IndexOf(",") If data(l2).Substring(0, txtint1) < data(l2 + 1).Substring(0, txtint2) Then uptmp = data(l2) '入れ替え前の上の値 downtmp = data(l2 + 1) '入れ替え前の下の値 data(l2) = downtmp '入れ替え後の上の値 data(l2 + 1) = uptmp '入れ替え後の下の値 End If Next savefile2(data(l2)) 'ファイルの保存  順番が違います。 Next '不明な点は、返信おねがいします。 End Sub ここまでしか、記入できませんでしたので、続きは別回答します。

KenKen1978
質問者

お礼

本当にいつもご丁寧にありがとうございますm(__)m

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

すみません。コード読んでどんなアルゴリズムでやろうとしているのかわかりません。 100行くらいなら、全部読み込んでもメモリが足りないなんてことはないでしょうから、 (1)ファイルから全部読み込んで、配列に入れる (2) (1)の配列をソート : 8列目で比較する (3) (2)で並び換えたものをファイルに出力 配列は List(of String)を使えば、ReadLine→Addで追加していけます。 勉強のためなら、自分でソートプログラムを組んでみましょう。 並び換える方法はいろいろあります。 http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC%E3%83%88 100個程度なら、バブルソートでも十分でしょう。 <や>で比較しているところを、「8列目で比較」にします。 楽をするなら、ListのSortメソッドを使います。 比較方法を変えるには、MSDNのサンプルを参考にするとよいでしょう http://msdn.microsoft.com/ja-jp/library/w56d4y5z%28v=vs.90%29

KenKen1978
質問者

お礼

kmeeさんのおっしゃるとおり自分でもどこに行っているのかわからなくなっていたのです。 ソート やバブルソート・・・・・・・ listboxのsortをつかってなど・・・ なんども調べて試してきました・・・・ しかし必ずどこかで行き詰ってしまっていたのです。 完全に迷路ですよね・・・・ でも仰っている方法が僕がしたい事なのです・・・・

関連するQ&A