アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB2010です。

前回、質問させて頂いた続きです。
前回は質問の仕方が失敗で大変皆様にご迷惑をおかけしました・・・・・

本当に申し訳なく思っています・・・

もうだんだん迷路に入ってしまったので、コードをそのまま記載しました。

Itm(7)を基準に数字の大きい順に並び替えしたいのです。
CSVは全部で19列あります。
ファイルによって違いますが、行数はだいたい100行ぐらいです

無理やりしたのコードを書いたのですが、あと一歩でやはりきれいに並び替えができません・・・

大変皆様にお手数ですがお助け下さい・・・・

プロの皆様にはかなり幼稚なコードで大変失礼します。
いろいろと試してみたのですが、これぐらいしか自分の力量では思いつかなくて・・・・

沢山失敗を繰り返したので変なコードも入っているかもですが・・・・・


Dim z As Integer = 0
Dim ReaderA As New IO.StreamReader(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & ".csv", System.Text.Encoding.GetEncoding("Shift-JIS"))
Dim LineA As String = ReaderA.ReadLine
Dim Itm() As String
Dim s As Integer = 0

Do Until IsNothing(LineA)
Itm = LineA.Split(",")
If z = 0 Then
Dim Writer As New IO.StreamWriter(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New.csv", False, System.Text.Encoding.GetEncoding("Shift-JIS"))
Writer.WriteLine(LineA)
Writer.Close()
Else
Dim ReaderB As New IO.StreamReader(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New.csv", System.Text.Encoding.GetEncoding("Shift-JIS"))
Dim Writer As New IO.StreamWriter(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New2.csv", False, System.Text.Encoding.GetEncoding("Shift-JIS"))
Dim LineB As String = ReaderB.ReadLine
Dim Stm() As String
Dim u As Integer = 0

Do Until IsNothing(LineB)
Stm = LineB.Split(",")

If Integer.Parse(Itm(7)) > Integer.Parse(Stm(7)) Then
If u = 0 Then
Writer.WriteLine(LineA)
u += 1
End If
End If


Writer.WriteLine(LineB)

If Integer.Parse(Itm(7)) <= Integer.Parse(Stm(7)) Then
If u = 0 Then
Writer.WriteLine(LineA)
u += 1
End If
End If

s += 1
LineB = ReaderB.ReadLine
Loop
Writer.Close()
ReaderB.Close()


IO.File.Delete(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New.csv")
Microsoft.VisualBasic.FileSystem.Rename(SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New2.csv", SyFolder & Me.Combo0.Text & "\Data\Sales\EachMonth\" & Me.ComboBox1.Text & "New.csv")

End If

z += 1
LineA = ReaderA.ReadLine
Loop
ReaderA.Close()

A 回答 (6件)

すみません。

コード読んでどんなアルゴリズムでやろうとしているのかわかりません。

100行くらいなら、全部読み込んでもメモリが足りないなんてことはないでしょうから、
(1)ファイルから全部読み込んで、配列に入れる
(2) (1)の配列をソート : 8列目で比較する
(3) (2)で並び換えたものをファイルに出力

配列は List(of String)を使えば、ReadLine→Addで追加していけます。

勉強のためなら、自分でソートプログラムを組んでみましょう。
並び換える方法はいろいろあります。
http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC% …
100個程度なら、バブルソートでも十分でしょう。
<や>で比較しているところを、「8列目で比較」にします。

楽をするなら、ListのSortメソッドを使います。
比較方法を変えるには、MSDNのサンプルを参考にするとよいでしょう
http://msdn.microsoft.com/ja-jp/library/w56d4y5z …
    • good
    • 0
この回答へのお礼

kmeeさんのおっしゃるとおり自分でもどこに行っているのかわからなくなっていたのです。

ソート やバブルソート・・・・・・・
listboxのsortをつかってなど・・・

なんども調べて試してきました・・・・ しかし必ずどこかで行き詰ってしまっていたのです。
完全に迷路ですよね・・・・

でも仰っている方法が僕がしたい事なのです・・・・

お礼日時:2012/07/28 15:03

こんにちは、だいぶ頑張ったようですね。

(拍手    サンプルを作成しましたので、参考に  文字制限がありますので、詳細は、説明できません。 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
ここまでしか、記入できませんでしたので、続きは別回答します。
    • good
    • 0
この回答へのお礼

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

お礼日時:2012/07/28 20:33

文字制限がありましたので、途中までしか記入できませんでしたので、続きです。



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

不明点は、再度質問してね。
他の方が良い回答をしてくれると思います。

あともうひといきです、頑張ってください。
    • good
    • 0
この回答へのお礼

ここまでの長文でご説明頂けるとは本当に光栄です!

迷路から脱出できそうです~~~~~♪

お礼日時:2012/07/28 20:37

大変申し訳ありません。


訂正です。
少し実験したところ、エラーがありました。


コードの最初の部分で ↓、
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 '入れ替え前の下の要素


すいません。直してください。
こんな単純なミスをするようでは、回答できませんね。
    • good
    • 0
この回答へのお礼

いえいえ そんなご回答本当に感謝しています~~~

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

お礼日時:2012/07/28 20:37

大変、大変申し訳あいりません。

もう一箇所ありました。


気にはなっていたのですが、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型に変換してください。

重ね重ねお詫び申し上げます。
おかしいな~   自動変換してくれないのかな~

この回答への補足

えっ~~と

全部やってみました!
始めのsavefile1の時点で数字の小さい順に並びえかられているファイルが出力されていますね^^

次の構文にはいるとなぜか順序がまたバラバラになっているのです・・・・
そしてCSVファイルを開こうとするとまだVBが開いていると通知メッセージが出てきます・・・・

どうしてだろう・・・・

もう少しみたいなので自分でも足掻いてみます!

補足日時:2012/07/28 20:40
    • good
    • 0
この回答へのお礼

あああああ 僕の勘違いです!!!

スイマセン

きちんとsavefile2で並び替えられています!!!
あとファイルのreaderBのcloseを入力すれば良いのですね^^

早とちりしてしまいますた・・・・m(__)m

お礼日時:2012/07/28 20:48

またまた、やっちゃったみたいです。

質問は「大きい順に並び替え」ですよね。
先ほどの物は「小さい順」でした。


下記のコードですと「小さい順」になります。
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/al …


あと、Sortで並べ替えは非合法だと思っていましたが、kmeeさんの回答によると、私が前回提案させていただいた、
リスト.Sort() '並べ替え
リスト.Reverse() '降順 
もありのようですね。
Sortの '並べ替えは、数字の大小ではなく、辞書の順番で並べ替えるため少々危険と思い「非合法」といいましたが、「合法」であればSortの '並べ替のほうがず~っと簡単です。

この回答への補足

いえいえ!!!
小さい順は自分でなんと判明出来ましたので、勉強になりました~~~~

たしかに今後の事を考えるとsortもしっかり勉強するべきだと思います

補足日時:2012/07/28 21:14
    • good
    • 0
この回答へのお礼

でも、やっ~~~~~とクリア出来たので今日はここで並び替えは一休みかなぁ・・・
明日からsortに関してはご提案のURLからしっかりx100勉強します!!!

本当にご丁寧にお付き合い下さってありがとうございます^^

最後に初心者なので
savefile2(data(l2))
Private Sub savefile2(ByVal linetest As String)
↑の方法があるのも初めてしりました・・・・・(恥ずかしながら・・・)
凄く便利ですね^^

一つの質問で沢山の勉強をさせて頂きました!!!

この感謝を言葉では言い表せない程ですが、
本当にありがとうございましたm(__)m

お礼日時:2012/07/28 21:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!