• ベストアンサー

excelVBA 配列ソート方法

こんにちは、 下記のコードを使ってsetint配列の値を 昇順にソートしようとしているのですが、 最小値が最後に来てしまいます。 何か昇順にソートする方法はないでしょうか。 '昇順並び変え For run = 1 To UBound(setint) For run1 = UBound(setint) To 1 Step -1 If setint(run) >= setint(run1) Then swap = setint(run) setint(run) = setint(run1) setint(run1) = swap End If Next Next For run = 1 To UBound(setint) Debug.Print setint(run) Next

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

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

このコードですと、runとrun1が途中で入れ替わってしまいます(ステップインで確認すると分かると思います)。 For run = 1 To UBound(setint) - 1 For run1 = UBound(setint) To run + 1 Step -1 とすればよいかと思います。

その他の回答 (3)

  • okormazd
  • ベストアンサー率50% (1224/2412)
回答No.4

1. runはだめだ。run0にした。 2. 始の配列の添字がいくつからかわからないが、普通は0からだからそうする。 3. 2番目のfor文で、自分と比較する必要はないから、比較しないようにする。これでひととおりできるが、 4. 2番目のfor文を↓ For run1 = run0 To UBound(setint) とするほうがすなおじゃないかと思うが。 For run0 = 0 To UBound(setint) For run1 = UBound(setint) To run0+1 Step -1 If setint(run0) >= setint(run1) Then swap = setint(run0) setint(run0) = setint(run1) setint(run1) = swap End If Next Next For run0 = 0 To UBound(setint) Debug.Print setint(run0) Next

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

下記でテストしたらうまく行くようです。 ご参考に。 Runのようなシステムでも使いそうな名称は避けた方が良いのでは。 「連」の意味でつけた? For Run1 = UBound(d) To j + 1 Step -1 のように1つ手前で比較をストップすべきか。 =の場合はSWAPしないほうが良いのでは。 ーーーー テストデータとして、エクセルのシートのA1:A20までに整数値を入れた。 Option Base 1 Sub test01() Dim d(20) For i = 1 To 20 d(i) = Cells(i, "A") Next i '---- 'MsgBox UBound(d) For j = 1 To UBound(d) For Run1 = UBound(d) To j + 1 Step -1 If d(j) > d(Run1) Then swap = d(j) d(j) = d(Run1) d(Run1) = swap End If Next Run1 Next j '----- For j = 1 To UBound(d) Cells(j, "B") = d(j) Next End Sub

  • keirika
  • ベストアンサー率42% (279/658)
回答No.2

For run = 0 To UBound(setint) - 1 For run1 = UBound(setint) - 1 To 1 Step -1 If setint(run1 - 1) > setint(run1) Then swap = setint(run1 - 1) setint(run1 - 1) = setint(run1) setint(run1) = swap End If Next Next For run = 0 To UBound(setint) - 1 Debug.Print setint(run) Next でどうでしょうか

関連するQ&A

  • VB6での配列の SORT の使い方 

     お世話になります。   下記のように、配列にランダムな数値を入れて、それを昇順、降順にしたいのですが、この場合の SORT の使い方を教えて欲しいです。  Dim YUI(100) As Integer   YUI(1) =88:YUI(2) =53:YUI(3) =7 ~ YUI(98) =13:YUI(99) =2:YUI(100) =94 下記のような並べ替えをしていますが、SORT を使った場合の書き方を教えて下さい。 Dim I1,I4,D7 As Integer For I1 = 1 To 100 - 1 For I4 = I1 + 1 To 100 If YUI(I1) < YUI(I4) Then D7 = YUI(I4) YUI(I4) = YUI(I1) YUI(I1) = D7 End If Next I4 Next I1

  • 配列のソート 

    使用ソフト VB.NET 配列に入っている値の大きい順にソートする 値は重複することもある。その場合は配列の値が若いほうを優先 具体的には ロト6にて、出現した番号が多い順番にソートしたい。 date_last_st() には出現回数 date_sort() には出現回数が多い番号が順番にいれる 例 date_last_st(1)=2 date_last_st(2)=5 date_last_st(3)=2 の場合 date_sort(1)は2 date_sort(2)は1 date_sort(3)は3 となるようにしたい 一応自分で考えたのですがもっと簡素にできたりはしないのでしょうか? ---------------- Do For i = 1 To 43 If date_last_st(i) > date_max Then date_max_no = i date_max = date_last_st(i) End If Next date_last_st(date_max_no) = 0 date_sort(c) = date_max_no date_max = 0 c = c + 1 '1番~43番まですべて0か 判断 For i = 1 To 43 If date_last_st(i) = 0 Then date_TF = True Else date_TF = False Exit For End If Next '1番~43番まですべて0なら無限ループを抜ける If date_TF = True Then Exit Do End If Loop ---------

  • 構造体配列のクイックソート

    こんにちわ。 構造体配列のリストを ポインタのつなぎ変えによるクイックソートで 以下のようなソートをしたいのですが、悩んでおります。 struct info { int count; struct info *prev; struct info *next; }; int main () { struct info info[5]; /* 初期値設定 */ quick_sort(info, 0, 5); return 0; } 上記のようにして、クイックソートをしたいのですが、 よくあるクイックソートだと 例えば初期値を <配列のindex>要素の値を <0> <1> <2> <3> <4> 5 1 4 3 2 などと定義した場合 普通のクイックソートだと <0> <1> <2> <3> <4> 1 2 3 4 5 というように並び変えられてしまい <配列のindex>と 要素の値の組み合わせが変わってしまいますが、 この組み合わせを変えず、 struct info *if; if = info; for (i=0; i<MAX; i++){ printf("%d", if->count); if = if->next; } printf("\n"); とすることで、indexとしては昇順になっていないが *nextをたどっていくことでちゃんと目的の値の昇順になっている というのを実現したいのですが、ポインタのつなぎ変えか何かが 間違っているようで うまいことできていません。 どなたかご教授いただけますでしょうか。 申し訳ありませんが、よろしウお願いいたします。

  • 1次元配列のソート方法

    配列のソートメソッドについて質問させていただきます。 VB.NET初心者なので日本語がおかしいかもしれませんが、宜しくお願いいたします。 データテーブルが格納されている配列があり、 その配列をソートしたいと思っています。 データテーブルの中に「NO」と「ID」というフィールドがあります。 NOで昇順し、NOが同じだったらIDの昇順でソートといったことがしたいのですが、 条件によっては上手くいきません。 よろしければ、教えていただけないでしょうか? また、もっと効率の良い方法とかありましたら、具体的はソース等教えていただけないでしょうか? 宜しくお願いいたします。 [例] workDT() ← 元のデータテーブル配列 Dim Datatable(workDt.Rows.Count-1) As DataTable ← ソート後のデータテーブル配列 Dim tmpDatatable(workDT.Rows.Count-1) As DataTable ← 途中で使うデータテーブル配列 Dim NO(workDT.Rows.Count-1) As Integer ← 元のデータテーブル配列の各「NO」フィールドを格納する配列 Dim ID(workDT.Rows.Count-1) As String ← 途中で使うデータテーブル配列の各「ID」フィールドを格納する配列 Dim Index(workDT.Rows.Count-1) As Integer ← インデックスに使用 ' IDでソート For i = 0 To workDt.Length - 1 ID(i) = workDt(i).Rows(0).Item("ID") Index(i) = i Next ' 配列をIDでソート Array.Sort(ID, Index) ' ソート後配列をテンプ配列に格納 For i = 0 To workDt.Length - 1 tmpDatatable(i) = workDt(Index(i)).Copy Next ' NOでソート For i = 0 To tmpDatatable.Length - 1 NO(i) = tmpDatatable(i).Rows(0).Item("NO") Index(i) = i Next ' 配列をNOでソート Array.Sort(NO, Index) ' ソート後配列を格納 For i = 0 To tmpDatatable.Length - 1 Datatable(i) = tmpDatatable(Index(i)).Copy Next これで各配列を初期化します。 workDTに5つのデータテーブルが入っていて workDT(0):ID=3、NO=1 workDT(0):ID=1、NO=5 workDT(0):ID=2、NO=5 workDT(0):ID=4、NO=5 workDT(0):ID=5、NO=7 (IDは重複不可設定、NOは重複可設定です。) とした場合、NOのソートのところで変な順番になってしまいます。 Array.Sort(NO, Index) このメソッドは同じ値だった場合、何を優先してソートしているのでしょうか? 環境はWindowsXPSP3とVB2005です。

  • 配列データのソートについて

    配列データのソートについて 配列データAAA(1000,10)があるとします。 このデータを5番目のデータにて降順にソートしたいと考えています。 現在、次の方法にて実施していますが、効率が悪いようなので、効率の良い方法を教えて下さい。 Sheets("荷捌場").Select Range(Cells(1, 1), Cells(1000, 10))="" For A=1 To 1000 For B=1 To 10 Cells(A,B)=AAA(A,B) Next B Next A Range(Cells(1, 1), Cells(1000, 10)).Select Selection.Sort Key1:=Range("E1"), Order1:=xlDescending For A=1 To 1000 For B=1 To 10 BBB(A,B)=Cells(A,B).Value Next B Next A Sheets("ソート後のデータ貼付場").Select For A=1 To 1000 For B=1 To 10 Cells(A,B)=BBB(A,B) Next B Next A

  • ソートの時間比較について

    ランダムな数値群をソートする際の時間比較をしています。 計測時間を見てみると バブルソート(交換法)<挿入<選択 の順番になるのですがこれってあってますか? Sub 基本選択法() t = Timer n = Cells(2, 3).Value swap = 0 compare = 0 For i = 1 To n - 1 For j = i + 1 To n If Cells(i, 1).Value > Cells(j, 1).Value Then wk = Cells(j, 1).Value Cells(j, 1).Value = Cells(i, 1).Value Cells(i, 1).Value = wk swap = swap + 1 'Sleep (300) 'Calculate End If compare = compare + 1 Next j Calculate Next i Range("C3").Select Selection.Value = compare Range("C4").Value = swap Range("C5").Value = (Timer - t) Range("C1") = "選択法" End Sub Sub 基本挿入法() t = Timer n = Cells(2, 3).Value swap = 0 compare = 0 For i = 2 To n For j = i To 2 Step -1 If Cells(j, 1).Value < Cells(j - 1, 1).Value Then wk = Cells(j, 1).Value Cells(j, 1).Value = Cells(j - 1, 1).Value Cells(j - 1, 1).Value = wk swap = swap + 1 Else Exit For 'Sleep (40300) 'Calculate End If compare = compare + 1 Next j Calculate Next i Range("C3").Select Selection.Value = compare Range("C4").Value = swap Range("C5").Value = (Timer - t) Range("C1") = "挿入法" End Sub Sub 基本交換法() ActiveSheet.Shapes("Button 1").Select Selection.Characters.Text = "並べ替え中" t = Timer n = Cells(2, 3).Value swap = 0 compare = 0 For i = n - 1 To 1 Step -1 For j = 1 To i If Cells(j, 1).Value > Cells(j + 1, 1).Value Then wk = Cells(j, 1).Value Cells(j, 1).Value = Cells(j + 1, 1).Value Cells(j + 1, 1).Value = wk swap = swap + 1 'Sleep (300) 'Calculate End If compare = compare + 1 Next j Calculate Next i ActiveSheet.Shapes("Button 1").Select Selection.Characters.Text = "基本交換法" Range("C3").Select Selection.Value = compare Range("C4").Value = swap Range("C5").Value = (Timer - t) Range("C1") = "交換法" End Sub

  • 構造体配列のソート

    VB6 ソートのやり方は知っていますが、構造体の定義が変わると対応できません。 ソート処理部分だけを共通関数にできますでしょうか? Private Type Sort strCol1 As String intCol2 As Integer sttCol3 As String End Type Private Sub A() Dim typSort(3) As Sort 'ここに、構造体データ設定処理を記述 Call subSort(typSort(), typSortCopy) End Sub Private Sub subSort(typTaget() As Sort) Dim lngOutLoop As Long Dim lngCurent As Long Dim lngInLoop As Long Dim Min As Variant Dim typSortCopy As Sort For lngOutLoop = LBound(typTaget) To UBound(typTaget) - 1 Min = typTaget(lngOutLoop).strCol1 lngCurent = lngOutLoop For lngInLoop = lngOutLoop + LBound(typTaget) + 1 To UBound(typTaget) If typTaget(lngInLoop).strCol1 < Min Then Min = typTaget(lngInLoop).strCol1 lngCurent = lngInLoop End If Next lngInLoop typTagetCopy = typTaget(lngOutLoop) typTaget(lngOutLoop) = typTaget(lngCurent) typTaget(lngCurent) = typTagetCopy Next lngOutLoop End Sub

  • Fortran77で多次元配列を並び替え(ソート)する方法

    Fortran77のプログラミングを勉強しています。 多次元配列の並び替えをする時に、各行の組み合わせを変えずにある列に含まれる要素についてソートを行いたいのですが、やり方が分かりません。どなたか方法を教えてくださいますでしょうか。 例えば、 (1,1)A,(1,2)あ,(1,3)3 (2,1)B,(2,2)い,(2,3)1 (3,1)C,(3,2)う,(3,3)2 という3×3の配列を読み込み、3列目を昇順に並べ替えて、 (1,1)B,(1,2)い,(1,3)1 (2,1)C,(2,2)う,(2,3)2 (3,1)A,(3,2)あ,(3,3)3 とした上で、別のファイルに出力したいのです。 初歩的な質問で恐縮ですが、どなたかご教授よろしくお願い致します。

  • EXCEL VBA 配列について

    リストボックスの選択から重複しないリストボックスに値を抽出する コードを作成しました。 しかし、スペックの低いPCで動作させると、処理に時間が かかってしまいます。 配列を使うと処理が早くなるとウェブで調べたのですが、 いまいち理解が出来ません。 やりたいこと ・配列にリストボックスの値を入れる ・配列から重複を削除する? どなたかご教授ください。 コードは下記のようになっています。    If Not UserForm1.ListBox6.Value = 0 Then      For w = UserForm1.ListBox1.ListCount - 1 To 0 Step -1 If Not UserForm1.ListBox6.Value = _ UserForm1.ListBox1.List(w, 5) Then UserForm1.ListBox1.RemoveItem (w) End If Next w    End If For w = UserForm1.ListBox1.ListCount - 1 To 1 Step -1 If UserForm1.ListBox1.List(w - 1, 6) = UserForm1.ListBox1.List(w, 6) Then UserForm1.ListBox1.RemoveItem (w) End If Next w

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

専門家に質問してみよう