コンボボックスの中身を任意順で並べ替え VBA

このQ&Aのポイント
  • Excel2003を使用しております。ユーザーフォームに置いてあるコンボボックスのデータの順番が毎回変わるのですが、指定順に並び替えたいです。
  • 項目は必ず全てあるわけではなく、東京、北海道だけの場合もあります。(コンボボックスの最後には必ず空白が1行あります)
  • 現在のコードは遠回りな方法かもしれません。より効率的な方法があれば教えてください。
回答を見る
  • ベストアンサー

コンボボックスの中身を任意順で並べ替え VBA

いつも大変お世話になっております。 Excel2003を使用しております。 ユーザーフォームに置いてある コンボボックスのデータの順番が毎回変わるのですが、 指定順に並び替えたいです。 例えば、 東京 大阪 北海道 青森 沖縄 仙台 福岡 という順番でコンボボックスに入っている場合、 北海道 青森 仙台 東京 大阪 福岡 沖縄 という順番に自動で並べ替えたいのです。 項目は必ず全てあるわけではなく、 東京 北海道 だけの場合もあります。(コンボボックスの最後には必ず空白が1行あります) Sub ComboboxNarabi() Dim i As Long Dim j As Long Dim Count As Long Dim Swap As String Dim SortListData As Variant SortListData = Array("北海道", "青森", "仙台", "東京", "大阪", "福岡", "沖縄", "") Count = 0 For j = 0 To UBound(SortListData) For i = 0 To ComboBox2.ListCount - 1 If ComboBox2.List(i) = SortListData(j) Then Swap = ComboBox2.List(Count) '現在の位置の内容をSwapにコピー ComboBox2.List(Count) = ComboBox2.List(i) '現在位置に、検索したワードをコピー ComboBox2.List(i) = Swap 'もとの内容をコピー Count = Count + 1 End If Next Next End Sub なんだか遠回りしているような気もします。 もう少し、良い方法はありますでしょうか? 以上、よろしくお願い致します!

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

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 十分シンプルに纏っていますし、問題なく作動しますから、 そのままでもいいようにも思いますが。 一方で、何度も何度も忙しくリストの内容を書き換えるループが気になる、 ということであれば、理解、共感できる部分ではあります。 参考として、3例挙げてみます。 ここには書きませんが私個人の実務としては 今回のような複雑なソートの場合はADODBでSQLやRecordSet.Sort等を用いることが比較的多かったり、 ソートオーダーが可変な場合などではCollectionやDictionary等のオブジェクトを 配列ソートアルゴリズム等と組み合わせたり、とかもします。 より簡単に書けるものは簡単に済ませるようにも心がけていますけれども、、、。 書換えを考える時には、書換える意図を明確にしておくようにして、 一定の方向性を常に意識しながら書く様にするといいです。 今回は、複雑な処理は避けなるべく簡素に、実行プロシージャの編集が容易なもの、 という意図で3案挙げてみました。 メンテナンスに自信が持てる書き方を選ぶ、というのも、とても大切なことですので。 #余談。蛇足。 IF Then ステートメントには色々あります。   If 条件 Then 真の処理 Else 偽の処理 のように1行で書くことだって出来るのですけれど、 これはまぁ、やり過ぎ、というか非常に読み難いので使いませんが、   If 条件 Then Exit Sub のような排他処理の書き方は、VBAでは定番です。   If 条件 Then     1ページに収まらない程の長ったらしい処理   End If のように書くとEnd Ifの由来を確認するのも面倒ですし、、、。 無論、サブルーチン化するなどの検討も必要ですが、 目にすることの多い例として、特にイベントプロシージャなどでは、 Exit Sub(1行で記す If ... Then ... ステートメント)の使いこなしは重要な基本です。 #余談2。 VBEコードペイン上のインデントを投稿に反映させる方法ですが、 私は投稿文をメモ帳で書いてから全文をコピペして投稿する習慣がある(自分に課している)ので、 メモ帳にて、半角スペース4つを全角スペース2つに全置換しておくことで、 インデント擬きを表示させています。 昔はコードに全角スペースなど言語道断と仰る方多かったですが、 現行のExcel環境では、全角スペース2つをVBEコードペイン上にコピペすれば、 正しくインデント(タブ、というより半角スペース4つ)に置換してくれるようにもなっています。 以下3例。 ' ' 〓〓〓〓〓〓〓〓〓〓 Option Explicit Private arrSortOrder ' ! モジュールで宣言。 ' ' ↑ FnSortOrder用。頻繁に並べ替えをするならソートオーダーは固定した方が有利。 ' ' ======== 1◆ベーシック版 ' ' #せめて記述上だけでも。同じ事を繰り返さない(参照や取得は1回に纏める)ようにしてみる、とか。 Sub Re8668860b() ' ▼実行proc Dim i As Long Dim j As Long Dim Count As Long Dim Temp As String Dim Swap As String Dim SortListData As Variant   SortListData = Array("北海道", "青森", "仙台", "東京", "大阪", "福岡", "沖縄", "")   With ComboBox2     Count = 0     For j = 0 To UBound(SortListData)       For i = 0 To .ListCount - 1         Temp = .List(i)         If Temp = SortListData(j) Then           Swap = .List(Count) '現在の位置の内容をSwapにコピー           .List(Count) = Temp '現在位置に、検索したワードをコピー           .List(i) = Swap 'もとの内容をコピー           Count = Count + 1         End If       Next     Next   End With End Sub ' ' ======== 2◆配列操作List設定版(並べ替えは関数(配列変数))で ' ' #コンボボックスのリスト書換えを1回に纏める、とか。 Sub Re8668860c() ' ▼実行proc)   With ComboBox2     .List = FnSortOrder(.List)   End With End Sub Function FnSortOrder(ByVal arrCurList As Variant) As Variant Dim sBuf As String Dim nUBO As Long Dim nUBC As Long Dim nRank As Long Dim i As Long Dim j As Long   If Not IsArray(arrSortOrder) Then     arrSortOrder = Array("北海道", "青森", "仙台", "東京", "大阪", "福岡", "沖縄", "")   End If   arrCurList = ComboBox2.List ' ! 二次元配列   For j = 0 To UBound(arrSortOrder)     For i = 0 To UBound(arrCurList)       If arrCurList(i, 0) = arrSortOrder(j) Then         sBuf = arrCurList(nRank, 0)         arrCurList(nRank, 0) = arrCurList(i, 0)         arrCurList(i, 0) = sBuf         nRank = nRank + 1       End If     Next   Next   FnSortOrder = arrCurList End Function ' ' ======== 3◆Excelのユーザー設定と作業シート(非表示)を事前に用意しておいて ' ' #Excelの並べ替え機能を活用し、実行側では何も考えないで済むようにする、とか。 Private Sub 初期設定() Dim shSelected As Sheets   Set shSelected = ActiveWindow.SelectedSheets   With Worksheets.Add     .Name = "Work"     .Visible = xlSheetHidden   End With   shSelected.Select   Application.AddCustomList Array("北海道", "青森", "仙台", "東京", "大阪", "福岡", "沖縄", "") End Sub ' ↑ 実行は事前に、一度だけ。 Sub Re8668860e() ' ▼実行proc   With ComboBox2     .List = FnSortCustom(.List)   End With End Sub Function FnSortCustom(ByVal arrCurList As Variant) As Variant   With Sheets("work").Columns(1)     .Value = Empty ' .ClearContents     With .Resize(UBound(arrCurList) + 1)       .Value = arrCurList       .Sort Key1:=.Cells(1), Order1:=xlAscending, _         Header:=xlNo, OrderCustom:=Application.CustomListCount + 1, _         MatchCase:=True, Orientation:=xlTopToBottom, _         SortMethod:=xlStroke, DataOption1:=xlSortNormal       FnSortCustom = .Value     End With   End With End Function ' ' ======== ' ' 〓〓〓〓〓〓〓〓〓〓

satoron666
質問者

お礼

回答ありがとうございます。 タブを入れたつもりが、入っていませんでした! 見づらいプログラムで申し訳ありませんでした。 おぉお、すごいです! 同じことをやるのに3パターンも考えられるなんて… 2次元配列って難しいですね! プログラムを読むだけで精一杯です(苦笑 元々ある、Excelの並び替え機能が使えるとは思っていませんでした! 確かに、その方法なら今後も…使えそうな気がします! If文の横にExit Sub などが基本ですか。 全然使っておりませんでしたorz その横にEnd If をつける…のも良いのでしょうか? 中々、プログラムというのは奥が深いですね…! ありがとうございました^^ 大変参考になりました!

関連するQ&A

  • Excel VBAのコンボボックス

    お世話になります。 コンボボックス1と2と3は選択されますが コンボボックス4には何の表示もされません。 選択して条件設定は4つ以上できないのでしょうか? Dim ITE As Variant Dim flg As Variant Private Sub ComboBox3_Change() 'ComboBox4セット Dim ico As Long ico = 1 With ThisWorkbook.Worksheets("data") KEY = Me.ComboBox1.Text KEY2 = Me.ComboBox2.Text KEY3 = Me.ComboBox3.Text Me.ComboBox4.Clear Do While .Cells(ico, 1) <> "" If .Cells(ico, 1) = KEY And .Cells(ico, 2) = KEY2 And .Cells(ico, 3) = KEY3 Then ITE = .Cells(ico, 4).Value flg = 0 For I = 0 To Me.ComboBox4.ListCount - 1 If ITE = Me.ComboBox4.List(I) Then flg = 1 Next If flg = 0 Then Me.ComboBox4.AddItem ITE End If ico = ico + 1 Loop End With Me.ComboBox4.SetFocus End Sub

  • EXCEL コンボボックスのリスト設定

    リストインデックスが複数ある場合は動くのですが、 インデックスが0 もしくは1個しかない場合は、どのように処理を追加したらいいでしょうか。。 実行時エラー381 Lisプロパティを設定できません。プロパティの配列のインデックスが無効です、と メッセージが出ます。 いろいろ試してるのですがわかりません。 コンボボックスの値は別シートで参照先を指定しています。 ----------- Private Sub ComboBox3_DropButtonClick() Dim lRow As Long Dim i As Long, myCnt As Long Dim myData With Worksheets("部門名") lRow = .Range("O" & Rows.Count).End(xlUp).Row ’O列の最終行を確認 myData = .Range("O2:O" & lRow).Value ’コンボボックスのリストデータ End With With ComboBox3 .ColumnCount = 1 .ColumnWidths = "50" .List = myData End With End Sub

  • コンボボックス 連動 VBA

    VBA初心者です。 ご教授ください。 入力フォームにコンボボックスを4っつ リストボックスを一つ作成し 一つ目のコンボでシートを選択後 二つ目以降のコンボボックスでセル範囲を選択し絞り込み、最終のリストボックスに 絞り込み表示を行い、コマンドボタンにて フィルター操作を行いたいのですが 重複表示させずに、絞り込んでいく方法がうまくいきません。下記コードにコンボボックス3以降も記述したのですが、絞り込みができません。よろしくお願いします。 Private Sub UserForm_Initialize() For i = 2 To Worksheets.Count 'シートの数だけ繰り返す ComboBox1.AddItem Worksheets(i).Name '取得したシート名をリストボックスへ Next End Sub Private Sub ComboBox1_Change() Dim Index As Integer Dim strBuf As String Index = ComboBox1.ListIndex 'ワークシートリストの選択された位置 strBuf = ComboBox1.List(Index) 'ワークシート名を取得 Worksheets(strBuf).Activate ' セルA1を左上端にする Application.Goto Reference:=Range("A1"), Scroll:=True ComboBox2.Clear Dim リスト As New Collection Dim 列 As String, 上端セル As String, 最下端セル As String Dim セル範囲 As Range, 各セル As Range 列 = "b" '※3 上端セル = 列 & "4" '※4 最下端セル = 列 & "65536" With Worksheets(strBuf) '※5 Set セル範囲 = .Range(.Range(上端セル), .Range(最下端セル).End(xlUp)) End With For Each 各セル In セル範囲 'セル範囲の各セルについて繰り返し処理 On Error Resume Next '次行が実行時エラーならその次行から継続 リスト.Add 各セル.Value, CStr(各セル.Value) 'Collectionオブジェクトにメンバを追加 If Err.Number = 0 Then '実行時エラーが発生していなければ Me.ComboBox2.AddItem 各セル.Value 'コンボボックスのリストに項目を追加 End If On Error GoTo 0 Next End Sub

  • 同じコンボボックス、リストボックスを使うには?

    よろしくお願いします。 今、ユーザーフォームを使って製造計画表を作っています。 コンボボックスで会社名、リストボックスで会社ごとの製品名を選択させるとこまで出来ました。 1日に3つの製品を作ることが出来るので、同じ中身のコンボボックス、リストボックスを使って3つ作りたいと思っています。 ユーザーフォームの形的にはこのような感じですが。 1. コンボボックス  リストボックス 2. コンボボックス  リストボックス 3. コンボボックス  リストボックス 今は、1.のとこだけは出来たのですが、2.3.は1.と同じコードをコピーして必要と思われるとこだけをコンボボックス2と変えたりしてみたのですが、上手くいきませんでした。こんなコードですが。 Private Sub UserForm_initialize() 'ComboBox1セット Dim ico As Long ico = 1 With ThisWorkbook.Worksheets("Sheet1") Do While .Cells(1, ico) <> "" Me.ComboBox1.AddItem .Cells(1, ico).Value ico = ico + 1 Loop End With Me.ComboBox1.SetFocus End Sub Private Sub ComboBox1_Change() 'ListBox1セット Dim ico As Long 'Me.ListBox1.Clear ico = Me.ComboBox1.ListIndex + 1 With ThisWorkbook.Worksheets("Sheet1") Me.ListBox1.List = .Range(.Cells(2, ico), _ .Cells(.Cells(Rows.Count, ico).End(xlUp).Row, ico)).Value End With End Sub VBAも初めたばかりで質問の内容もわかりづらいとも思いますが、よろしくお願いします。

  • エクセルVBAコンボボックスについて

    図の左のように、商品リスト欄のセルA3から下方向に大分類(A16まで14種類) セルB3~O3(Bから数えて14個目のO)列から下方向に小分類があります。 P2~P11には1から10までの数字が入っています。 図の右側がユーザフォームで、コンボボックスの番号を入れています。 コンボボックス「1.4.・・・28.」までは大分類を選べるようにして、 コンボボックス「2.5.・・・29.」までは左の大分類に応じた小分類の値を表示させたいと思っています。 大分類「111」→小分類「あ~そ」 大分類「222」→小分類「た~と」といった具合です。 そのコンボボックスの値を指定したセルに入力しようと思っています。 下のように記述した結果、問題が発生しました。 (1)大分類で14個ほどあるリストの3つほどしかでてこない。 (2)Select Caseの構文を使用していて、大分類が14個だから「Case 13」までと しているが、「大分類の数-1」までの変えられる数までにしたい。 アドバイスをいただけると助かります。 ------------------------------------------------------------------ Private Sub UserForm_Initialize() Dim MyVar1 As Variant MyVar1 = Sheets("商品リスト").Range("A3:A" & Range("A3").End(xlDown).Row) Dim MyVar20 As Variant MyVar20 = Sheets("商品リスト").Range("P2:P" & Range("P2").End(xlDown).Row) '種類欄を指定 With ComboBox1 .List() = MyVar1 End With ※・・・(省略)・・・ コンボボックス4から25まで※ With ComboBox28 .List() = MyVar1 End With '数量欄を指定 With ComboBox3 .List() = MyVar20 End With ※・・・(省略)・・・ コンボボックス6から27まで※ With ComboBox30 .List() = MyVar20 End With End Sub '1番目 Private Sub ComboBox1_Change() Dim MyVar1 As Variant ※・・・(省略)・・・ MyVar2~13 As Variant※ Dim MyVar14 As Variant Dim MyVar20 As Variant MyVar1 = Sheets("商品リスト").Range("A3:A" & Range("A3").End(xlDown).Row) ※・・・(省略)・・・ B列からN列まで※ MyVar15 = Sheets("商品リスト").Range("O3:O" & Range("O3").End(xlDown).Row) MyVar20 = Sheets("商品リスト").Range("P2:P11") Select Case ComboBox1.ListIndex Case 0 With ComboBox2 .List() = MyVar2 End With ※・・・(省略)・・・ Case1~ Case12 ※ Case 13 With ComboBox2 .List() = MyVar15 End With End Select End Sub

  • オプションボタン選択でコンボボックス有効

    ExcelVBAでユーザーフォームを作成しているのですが、昨日までうまく動作していたことが、突然動かなくなりました。 オプション1を選択 ↓ コンボボックス1有効  ※他のコンボボックスは無効 ↓ オプション2を選択 ↓ コンボボックス2有効  ※コンボボックス1も含め他のコンボボックスは無効 という感じで動作させたいです。 書いたコードはこんな感じです。 Private Sub OptionButton1_Click () Dim i As Long Dim lastRow As Integer lastRow = Cells(Row.Count, 1).End(xlUp).Row If OptionButton1.Value = True Then OptionButton1.Enabled = True With ComboBox1 If ComboBox1 = "" Then For i = 2 To lastRow .AddItem Worksheets("sheet1").Cells(i, 1).Value Next i End If End With ComboBox1.ListIndex = 0 ComboBox2.Enabled = False ComboBox3.Enabled = False End If End Sub コードの間違いや改善点などありましたら教えて下さい。 よろしくお願いします。

  • Excelのワークシートでのコンボボックスについて

    Excelのワークシートでコンボボックスを設定する方法を教えてください。 「フォームコントロール」と「ActiveXコントロール」の違いがわかりません。 添付の画像の通りコンボボックスに西暦を入力(別シートに入力済みの値を表示するように設定)してあるのですが、ファイルを保存しているにも関わらず、再度ファイルを開くとコンボボックスの中のリストは空欄になってしまいます。 今は「ActiveXコントロール」のコンボボックスで設定しています。 コードは以下のように設定してみたのですが、設定内容や設定箇所が違うのでしょうか? ////////////////////////////////////////////////////// Private Sub ComboBox1_DropButtonClick() Dim sh As Worksheet Set sh = Worksheets("マクロ") Dim i As Integer Dim lastRow As Integer lastRow = sh.Cells(Rows.Count, 1).End(xlUp).Row With ComboBox1 For i = 2 To lastRow If ComboBox1 = "" Then .AddItem sh.Cells(i, 1).Value End If Next i End With End Sub ////////////////////////////////////////////////////// コンボボックスのリストの内容が消えてしまうので、 コードの内容は同じで以下のところにもコードを書いてみました。 ////////////////////////////////////////////////////// Private Sub Worksheet_Activate() Dim sh As Worksheet Set sh = Worksheets("マクロ") Dim i As Integer Dim lastRow As Integer lastRow = sh.Cells(Rows.Count, 1).End(xlUp).Row With ComboBox1 For i = 2 To lastRow If ComboBox1 = "" Then .AddItem sh.Cells(i, 1).Value End If Next i End With End Sub ////////////////////////////////////////////////////// なんだかもう、訳がわからずぐちゃぐちゃです。 コンボボックスの中に値が入っていると、実行ボタンをクリックしたときは正常にやりたい結果を出すことが実現できます。 ファイルを閉じた後に再度開いてもコンボボックスの中に値があるようにするにはどうしたらよいのか、ド素人の私にご教授いただきたくお願いいたします。

  • エクセル2010 シート上のコンボボックス

    エクセル2010を使用しております。 シート1にコンボボックス1(アクティブXコントロール)を設置しており、 コードは下記です。 Private Sub ComboBox1_DropButtonClick() Dim i As Long With Worksheets("シート操作").OLEObjects("ComboBox1").Object .Clear    For i = 1 To 100 .AddItem i Next i End With End Sub コンボボックス1のドロップボタンで リスト1~100の数字の中から、任意の数字を選び テキスト表示部分に表示させたいだけなのですが、 上記コードではリストから選択しても何も表示されません。 コードの誤りと詳しい説明を希望します。 よろしくお願いいたします。

  • エクセルVBAのコンボボックス

    エクセル2002使用です。 生年月日とかを入力できるコンボボックスを作っているのですが、同じコンボボックスを5つ作ろうとしています。例えば和暦を入力するには Private Sub userform_initialize() With ComboBox(1) .AddItem "昭和" .AddItem "平成" End sub でうまくいくのですが、2個目から5つ目まで同じものを作成する場合、 With ComboBox(2) ・・・ With ComboBox(3) ・・・ と、コードを記述していかないと駄目なのでしょうか? できれば With ComboBox(1: 5) とか、 変数を使って Private Sub userform_initialize() Dim i As Integer For i = 1 To 5 With ComboBox(i) .AddItem "昭和" .AddItem "平成" End With Next End sub といった具合にまとめたいのですが、コンパイルエラーとなってしまいます。 初歩的な質問で申し訳ないのですが、よろしくお願いします。

  • Excel VBAのコンボボックスにて条件で絞込みをしたいのですが

    いつもお世話になっています。 コンボボックスの3個目が表示されません。 コンボボックス1と2はうまく表示されます。 よろしくお願いします。 Private Sub ComboBox2_Change() Dim ico As Long ico = 1 With ThisWorkbook.Worksheets("data") KEY = Me.ComboBox1.Text KET2 = Me.ComboBox2.Text KET3 = Me.ComboBox3.Text Me.ComboBox3.Clear Do While .Cells(ico, 1) <> "" If .Cells(ico, 1) = KEY And .Cells(ico, 2) = KEY2 Then ITE = .Cells(ico, 3).Value flg = 0 For I = 0 To Me.ComboBox3.ListCount - 1 If ITE = Me.ComboBox3.List(I) Then flg = 1 Next If flg = 0 Then Me.ComboBox3.AddItem ITE End If ico = ico + 1 Loop End With Me.ComboBox3.SetFocus End Sub

専門家に質問してみよう