VBA ListViewのデータを取得したり並べ替えたりしてみる

前回の続きです。「ListViewコントロール」でセル範囲のデータを表示できるようになりましたが、今度は表示しているデータを取得する方法について検証していきます。

くるみこ
くるみこ

ListView」からデータを取得する方法について勉強しましょう。「リストボックス」の時に使ったコードを変更していけばよさそうですが、さてどうなるでしょうか(^^)

ListView」用に「リストボックス」のコードを書き換えるんですね。違いが良くわかって、すごく勉強になりそうです! よろしくお願いしますm(__)m

【この記事でわかること
・「ListView」に表示しているデータを取得して利用する方法がわかります
ListViewのデータをソートする方法がわかります

前回記事のおさらいは、下のカードをクリックすれば開きます(^^ゞ

くるみこ
くるみこ

前回記事では「ListView」コントロールの設置からデータ表示までの方法を解説しています。是非あわせて覗いてみてね(^^)/

「ListView」の選択データを取得してみます

・では早速「リストボックス」で使ったコードを「ListView」用に変更してみましょう。

コードを並べて比較してみます

・あえて、それぞれのコードを横並びにしてみました。

【左側が今回の ListView 用コード】

'ListViewのリストをダブルクリック時に発生するイベント
Private Sub ListView1_DblClick()
 Dim sRow As Long
 With ListView1
  If .ListItems.Count = 0 Then Exit Sub
  sRow = .SelectedItem.Index '選択ItemのIndex取得
  If .ListItems(sRow).Selected = False Then Exit Sub
  With .ListItems(sRow)
   LData = True    'モジュールレベル変数をTrueに設定
   MultiPage1.Value = 0    '先頭ページを表示して設定
   '分類
   Cmb1.Text = .ListSubItems(1).Text
   'ID
   Cmb3.Text = .ListSubItems(2).Text
   'mKey
   Cmb4.Text = .ListSubItems(3).Text
   '開始
   TxtBox0.Text = .ListSubItems(4).Text
   '終了
   TxtBox1.Text = .ListSubItems(5).Text
   SpinB1.Value = TxtBox1.Value 'スピンボタンの値を初期化
   '文字数
   TxtBox2.Value = Val(TxtBox1.Value) _
                   - Val(TxtBox0.Value) + 1
   '名称
   Cmb2.Text = .Text
   '記号(Option設定を反映させる)
   Select Case .ListSubItems(6).Text
    Case OptB1.Caption: OptB1.Value = True '任意
    Case OptB2.Caption: OptB2.Value = True '指定
    Case OptB3.Caption: OptB3.Value = True '禁止
   End Select
   LData = False   'モジュールレベル変数をFlseに戻す
  End With
 End With
End Sub

【右側がリストボックスのコード】

'リスト行でダブルクリック時の発生イベント
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
 With ListBox1
  If .ListIndex = -1 Then
   MsgBox "リストが未選択です!"
  Else
   LData = True    'モジュールレベル変数をTrueに
   MultiPage1.Value = 0
   '分類
   Cmb1.Text = .List(.ListIndex, 0)
   'ID
   Cmb3.Text = .List(.ListIndex, 2)
   'mKey
   Cmb4.Text = .List(.ListIndex, 3)
   'L
   TxtBox0.Text = .List(.ListIndex, 4)
   'R
   TxtBox1.Text = .List(.ListIndex, 5)
   SpinB1.Value = TxtBox1.Value 'スピンボタンの値を初期化
   '文字数
   TxtBox2.Value = Val(TxtBox1.Value) _
                   - Val(TxtBox0.Value) + 1
   '名称
   Cmb2.Text = .List(.ListIndex, 1)
   'Option設定を反映させる
   Select Case .List(.ListIndex, 6)
    Case OptB1.Caption: OptB1.Value = True '任意
    Case OptB2.Caption: OptB2.Value = True '指定
    Case OptB3.Caption: OptB3.Value = True '禁止
   End Select
   LData = False   'モジュールレベル変数をFlseに戻す
  End If
 End With
End Sub

左側の「ListView」での動作について説明します
・まず、リストが選択されていた部分を特定する方法が「リストボックス」と違っています。
・5行目、ListItemsコレクションのCountプロパティでデータ数「0」なら中止して抜けます。
・6行目、選択されているListView1.ItemIndexを取得しています。
・7行目、念のため再度選択をチェックしてFalseだったら処理を中止して抜けます。
・12行目以降で、ListSubItemsコレクションの各IndexからTextデータを取得していきます
・26行目で、「名称」のデータをListItems(Index番号).Textでデータ取得しています。

「リストボックス」の場合は.List(.ListIndex, 0)のようにList(行,列)でデータ取得します。
ListView」では、表形式の詳細ビュー(lvwReport)の場合、ListItemsコレクションは左端列(1列目)がItemを表すテキストです。2列目以降が、1列目に登録されたListItemのサブアイテムとして一覧表示されています。その一覧がListSubItemsコレクションで左から順にIndexでデータを取得することができます。

・データを取得できるようになった実行GIF画像を貼っておきます。

ListView のデータをソートできるようにします

表形式のListViewコントロールで、列見出しをクリックするとデータがソートされるような感じがしますが、何も起きないんですよね(-_-;)

でも実は、ListViewコントロールには、ソートするためのプロパティは用意されているんです。
ソートする機能はあるということなんですが、そのままでは自動的にソートはしてくれません

列をソートするために用意されているプロパティは次の3つです

名前説明選択項目
Sorted並び替え(アルファベット順に)可否True/False(既定値)
SortKeyソートの基準の列番号
SortOrder並び替え方法(Sorted=True)lvwAscending(昇順)/
lvwDescending(降順)

SortKey に、ソート列番号を指定して、SortOrder で、並び替え方法(昇順/降順)を指定したうえで、
Sorted に、Trueを設定すれば良さそうですね。

VBAコードを書いて検証してみましょう

・列見出しのクリック時に発生するイベントにListViewをソートするコードを書きます。
ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
・引数を見ると、クリックされたColumnHeaderオブジェクトが格納されることがわかります。
・クリックされた列(ColumnHeaderオブジェクト)のIndex値が SortKey に使えそうです。
SortKeyプロパティに指定する列は左端を「0」から順に数えます
 一方、ColumnHeaderオブジェクトのIndex値は「1」からスタートしています
 ということは、Index値 -1 SortKey に指定すればOKということですね。

'ListViewのカラムクリック時にクリック列基準でソートする
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
    With ListView1
        .SortKey = ColumnHeader.Index - 1
        .SortOrder = .SortOrder Xor lvwDescending
        .Sorted = True
    End With
End Sub

SortOrderプロパティに = .SortOrder Xor lvwDescending(降順)と設定しています。
 Xor 演算子 を使うことで、lvwAscending(昇順) と lvwDescending(降順)を交互に切り替えられるようにしています。 そして最後に、
Sorted プロパティを True に設定します。これで Sort が実行されます。
・これだけのコードでうまく動作しています。実行GIF画像を見てください(^^♪

ListViewデータ取得と表示データのソートがうまくいったので、今回はここで終了とします!

スポンサーリンク

まとめ(おわりに)

・いかがでしたでしょうか?
・今回も、記事内で使用したコードのサンプルファイルを登録していますのでご利用ください。
今までの記事のサンプルも登録していますのでよろしければお使いください(^^)

まとめと感想など

くるみこ
くるみこ

ListView」からデータを取得する方法とデータをソートする方法について解説・勉強しました! 今回の感想はいかがですか?

ListView」のデータ取得では全部のデータをチェックしていくのかと思いましたが、直接選択データをチェックすることは最初思いつきませんでした(^^;
ソートが結構簡単なコードで実現できたのは意外でした(^^♪  前にも使ったことがある Xor 演算子 がまた出てきましたが、これって便利ですね!

くるみこ
くるみこ

ListView」の活用方法について次回、もう少し検証してみたいと思います!
次回も楽しみにしていてね(^^)/

【今回わかったことは】
・「ListView」に表示しているデータを取得して利用する方法がわかりました
・「ListView」のデータをソートする方法がわかりました

今後の記事について

今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
「汎用でだれでも使えて活用できるように考えてVBAを使う」というポリシーで、記事を継続して書いていきたいと思っています。どうぞよろしくお願いしますm(_ _)m

【検討中の今後の記事内容は・・・・・】
・実務に役立つものを提供できるよう常に検討しています(^^ゞ
・その他雑記的に「プチネタなど」もいろいろ考えていきたいと思います・・・・・
・今後の記事にもご期待ください(^^)/

記事のサンプルファイルをダウンロードできます

今回の記事のサンプルをダウンロードできるようにしています
過去の記事で使用したサンプルファイルがダウンロードできるページを設置しています
こちら(このリンク先)からご利用ください