[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBA Listboxの値を並び替え』(さんちゃん)
お世話になっております。
userform上にListboxを配置しています。
リストは20000ほどありますが重複データで多くても20程度でよいと思っています、シートのデータをそのままリストとしてListboxへ表示させても使い物になりません。
問題
1.リストをフィルターを掛けて並び替えたデータをListboxへ表示する。
※シートへ書き込み並び替えてListboxへ表示する方法で出来ますが、それでは面白くなく勉強になりません。
Private Sub UserForm_Initialize()
途中抜粋
Dim swap As String Dim data(5) As String Dim v As Long Dim w As Long
w = UserForm1.ListBox1.ListCount - 1 For v = 0 To w data(v) = ListBox1.List(v) Next v For w = 0 To 5 For g = 5 To w Step -1 If data(w) > data(g) Then swap = data(w) data(w) = data(g) data(g) = swap End If Next g Next w ローカルウインドウで見るとdata(0)"",data(1)"",data(3)"AA1",data(4)"AA2",data(5)"AA3" のように並び替えは出来ています。 表示する部分ご教授お願いいたします。
< 使用 Excel:Excel2013、使用 OS:Windows7 >
>>※シートへ書き込み並び替えてListboxへ表示する方法で出来ますが、それでは面白くなく勉強になりません。
いやぁ、立派な方法ですよ。というより、ゴリゴリ、自前コードを書いても、エクセル標準機能のパフォーマンスには 到底かないません。使えるものはどんどん使いましょう。
(アップされたコード内で配列ソートがありますね。でも、エクセルの並び替えよりパフォーマンスはぐっと落ちるはずです)
ただ、今回のテーマなら並び替えというより 重複削除機能でしょうね。並び順にかかわらず一発で必要なキーで 重複が削除され一意のリストになりますよ。
(β) 2016/09/01(木) 00:42
当処理にエクセル標準機能を活用するか、ゴリゴリ 自分でコードを書くかは別にして。
1.もともとのListBox1 へのデータの格納部分が見えませんが、プロパティ RowSource で指定していますか? それとも、元ネタがあるシートのデータを配列に取り込み Listに格納、ないしは AddItem で 1行ずつ追加していますか? 2.ローカルウィンドウで調べた結果、ご自身でも確認されていますけど、このコードでは 空白が 先頭にきます。 もし、空白が多ければ、表示されたListBox1 は 空っぽのように見え、実際のリストは、下のほうにずずずっとスクロールして初めて でてきます。 これでいいのですか? 3.そもそも、空白データもリストに入っていることがおかしいんですが、このListBox1 の内容、列数は1つですか 複数列ですか? 4.複数列だとして、並び替えや重複削除のための列は、どの列ですか?
いずれにしても、仕様が不明なんですが、アップされたコード、なんだかおかしいですねぇ。 0 〜 5 って データの行数分のループ処理ですかね? 0 〜 w は 列数分のループ処理? 何をやりたいのか、コードと説明文が食い違っているような気がします。
(β) 2016/09/01(木) 06:50
Private Sub CommandButton1_Click() Dim i As Long Dim cw As String
With CreateObject("System.Collections.ArrayList") For i = 0 To ListBox1.ListCount - 1 cw = ListBox1.List(i) If cw <> "" And Not .Contains(cw) Then .Add cw End If Next i .Sort ListBox1.Clear For i = 0 To .Count - 1 ListBox1.AddItem .Item(i) Next i End With End Sub (???) 2016/09/01(木) 09:29
本来は、そもそも、ListBox1にListを登録する際に、重複削除と並び替えを行えばいいと思いますが 既にListBox1に登録されているとして。
???さんのコードと基本同じですが、List内にあると思われる空白も削除します。 (とりあえず1列のリストだという前提です。複数列なら別コードになります)
Private Sub UserForm_Initialize() Dim d As Variant Dim w As Variant Dim al As Object
w = ListBox1.List
With CreateObject("System.Collections.ArrayList")
For Each d In w If d <> "" Then If Not .contains(d) Then .Add d End If Next
.Sort ListBox1.RowSource = "" '念のため ListBox1.List = .toarray
End With
End Sub
(β) 2016/09/01(木) 11:10
「コード内で配列ソート」実はこれも動作が遅く、Sortが使えそうですが、2重の質問なので、もうしばらく悩んでみます。
問い合わせ(回答になるかわかりませんが)
1.[データの格納部分]は現在、For NextでAddItem で 1行ずつ追加しています。
2.[空白が 先頭にきます。]まさに、悩みの1つです。いろいろの質問はルール違反なので・・・空白は避けたいです。
3.[列数は1つですか]はい、1つです。基本的には空白は無いのですが、避ける方法も勉強したいです。
4.[複数列]1列です。
他、アップされたコード「0〜5」test用にしています。実際は20程度を予測しています。ですから空白が入ってしまします。本来は Dim data(5) As Stringがdata(20)としておくことで全てを拾えると考えています、実はdata(変数)←この変数をListboxデータ数とする事で、空白が無くなるのですが、いろいろやってみたのですが、 Dim data(5) As Stringとするとローカルウインドウでdata 0 to 5となりループ回数が指定されると考えています、また変数にして(w)としたいのですがエラーとなります。今は今後の課題としています。空白も予想して頂いて、さすがです。
とりあえず、ありがとうございます。頂いた物を勉強します。今後ともよろしくお願いいたします。
(さんちゃん) 2016/09/01(木) 21:32
.Add cwこの辺もすっかり忘れていました。 ListBox1.List = .toarray これは(.toarray)は、ググっても内容が理解できませんでした、また勉強します。 考えは大きくズレていないと思いますが?少しずつスピードアップできるようにやってみます。ご指導ありがとうございました。今後ともよろしくお願いいたします。 (さんちゃん) 2016/09/01(木) 23:40
System.Collections.ArrayList で探せば、情報が得られるでしょう。
これはExcel標準の機能ではなく、OSの追加機能である .Net Framework1.1で追加されたものを利用しているのですよ。
(windows10ならば、OSの標準機能に含まれます)
とりあえずは、こんなコードで重複チェックや空白チェックし、ソートまでできるんだなぁ、くらいの理解で良いです。
数年後、同じ仕様説明を読むと、理解できるようになっているかも?、くらいの難しさですから。
(???) 2016/09/02(金) 10:32
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.