ListViewControlでのデータの行の再配置。
このチュートリアルの前のエピソードでは、次の機能を有効にして列を再配置する方法を学びました: AllowColumnReorder プロパティシートのオプション。ただし、行の再配置は、ドラッグして別の行に配置することで実行されます。 ListViewコントロール行を再配置するには、ListItemのドラッグアンドドロップアクションで、プロパティシートでこの機能を有効にする必要があります。ただし、これだけでは機能しません。アイテムを必要な順序に並べ替えるには、VBAコードが必要です。
この演習では、データベースにコントロールとVBAコードを含むサンプルアクセスフォームを作成しましょう。 ListBoxおよびListViewコントロールを備えたフォームのサンプル画像を以下に示します。
リストボックスにテーブルとクエリ(アクションクエリではない)のリストを作成しました。リストアイテムの1つを選択すると、DataSheetビューに表示されるように、レコードがListViewコントロールに即座に表示されます。
設計タスク。
-
DataListというフィールド名で単一のテキストフィールドを持つ新しいテーブルを作成します 。
-
lvTablesという名前でテーブルを保存します (lvはListViewを表します)。
-
データセットビューでテーブルを開きます。
-
いくつかのテーブル名を追加し、データベースからテーブルにクエリ名を選択します。リストのNorthwindサンプルデータベースからテーブルをインポートしました。
注: 添付ファイル ListViewControlのフィールドが無効です。添付ファイルフィールドのあるテーブルの選択クエリを作成し、添付ファイルフィールドを除くすべてのフィールドを選択します。
-
デザインビューで新しいフォームを作成して開きます。
-
フォームにリストボックスコントロールを挿入し、プロパティシートを表示して、その名前を変更します。 List0へのプロパティ値 。
-
子ラベルを変更するキャプション テーブルの値 。
-
ListBoxコントロールのプロパティシートを表示し、行ソースを設定します lvTablesへのプロパティ値 名前。
-
行ソースタイプがテーブル/クエリとして設定されており、バインドされた列のプロパティ値が1であるかどうかを確認します。異なる場合は変更します。
-
ActiveXコントロールリストからListViewコントロールを挿入し、そのNameプロパティ値を ListView1に変更します。 。
-
上記のデモフォームの画像に示されているように、両方のコントロールのサイズを変更します。
-
コントロールの上にラベルを挿入し、その名前とキャプションのプロパティ値を見出しに変更します。 リストボックスからテーブルまたはクエリを選択すると、キャプション値がvbaコードから変更されます。
-
コントロールの下にコマンドボタンを作成し、そのNameプロパティ値を cmdCloseに変更します。 Captionプロパティ値を閉じる 。
-
ListViewコントロールを右クリックし、ListViewCtrlオブジェクトを強調表示します オプションを選択し、プロパティを選択します 。
-
一般の設定と一致するようにプロパティ設定を変更します 以下のタブ画像。
-
ListViewコントロールのプロパティシートの画像-一般的なタブビューを以下に示します:
これらのオプションのいくつかは、以前のセッションですでに設定しています。ここでは、ドラッグドロップアクションに次のオプションが必要です。
-
OLEDragAutomatic-1
-
OLEDropManual-1
-
FullRowSelect-True
-
HotTracking-True
-
上記の設定がプロパティシートと一致していることを確認してから、フォームを保存してください。
フォームのVBAモジュールを表示します。
フォームモジュールのVBAコード。
次のVBAコードをコピーしてモジュールに貼り付け、既存のコード行がある場合は上書きします。
Option Compare Database Option Explicit Dim lvwList As MSComctlLib.ListView Dim strTable As String Dim db As DAO.Database Dim rst As DAO.Recordset Private Sub Form_Load() Set lvwList = Me.ListView1.Object End Sub Private Sub Form_Unload(Cancel As Integer) On Error GoTo Form_Unload_Err Dim lvItem As ListItem Dim tmp As Long Dim criteria As String Dim strfield As String Dim flag As Boolean Dim fld As String If strTable = "" Then Set lvwList = Nothing Exit Sub End If Set db = CurrentDb Set rst = db.OpenRecordset(strTable, dbOpenDynaset) flag = False For Each lvItem In lvwList.ListItems tmp = lvItem.Index strfield = lvwList.ColumnHeaders(1).Text criteria = strfield & " = " & Chr(34) & lvItem.Text & Chr(34) rst.FindFirst criteria If Not rst.NoMatch Then If (rst.Fields(strfield).Value = lvItem.Text) _ And (rst.Fields(1).Value = tmp) Then 'GoTo nextitem Else rst.Edit rst.Fields(1).Value = tmp rst.Update End If Else MsgBox "Item: " & tmp & " Not Found!" End If Next rst.Close Set lvwList = Nothing Set lvItem = Nothing Set rst = Nothing Set db = Nothing Form_Unload_Exit: Exit Sub Form_Unload_Err: MsgBox Err & " : " & Err.Description, , "Form_Unload()" Resume Form_Unload_Exit End Sub Private Sub ListView1_ColumnClick(ByVal ColumnHeader As Object) ' When a ColumnHeader object is clicked, the ListView control ' sorts the data of that column. On the first Click on the Column 'will sort in Ascending Order, second Click will sort in Descending With Me.ListView1 ' Set the SortKey to the Index of the ColumnHeader - 1 .SortKey = ColumnHeader.Index - 1 ' Set Sorted to True to sort the list. If .SortOrder = lvwAscending Then .SortOrder = lvwDescending Else .SortOrder = lvwAscending End If .Sorted = True End With End Sub Private Sub List0_Click() strTable = List0.Value Call LoadListView(strTable) End Sub Private Sub LoadListView(ByVal s_Datasource As String) On Error GoTo LoadListView_Err Dim j As Integer Dim tmpLItem As MSComctlLib.ListItem Dim strHeading As String strHeading = UCase(s_Datasource) With Me.Heading .caption = strHeading .FontName = "Courier New" .FontSize = 20 .FontItalic = True .FontBold = True End With 'Initialize ListView Control lvwList.ColumnHeaders.Clear lvwList.ListItems.Clear Set db = CurrentDb Set rst = db.OpenRecordset(s_Datasource, dbOpenSnapshot) 'Initialize ListView & Column Headers Property Values With lvwList .Font.Size = 10 .Font.Name = "Verdana" .Font.Bold = False .GridLines = True End With With lvwList 'Syntax: .ColumnHeaders.Add Index, Key, Text, Width in Pixels, Alignment, Icon For j = 0 To rst.Fields.Count - 1 .ColumnHeaders.Add , , rst.Fields(j).Name, IIf(j = 0, 3000, 1400), 0 Next End With Dim I As Long rst.MoveFirst Do While Not rst.BOF And Not rst.EOF 'Syntax: lvwList.ListItems.Add Index, Key, Text, Icon, SmallIcon Set tmpLItem = lvwList.ListItems.Add(, , rst.Fields(0).Value) 'Name column 'Syntax: tmpLItem.ListSubItems.Add Index, Key, Text, ReportIcon, ToolTipText With tmpLItem For j = 1 To rst.Fields.Count - 1 .ListSubItems.Add , , Nz(rst.Fields(j).Value, "") Next End With rst.MoveNext Loop rst.Close With lvwList If .ListItems.Count > 0 Then .ListItems(1).Selected = True End If End With Set db = Nothing Set rst = Nothing LoadListView_Exit: Exit Sub LoadListView_Err: MsgBox Err & " : " & Err.Description, , "LoadListView()" Resume LoadListView_Exit End Sub Private Sub ListView1_OLEDragOver(data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer) 'Highlight the item when draged over it Set ListView1.DropHighlight = ListView1.HitTest(x, y) End Sub Private Sub ListView1_OLEDragDrop(data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single) 'Item being dropped Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Item being readded to the list Dim lvwTarget As ListItem 'Subitem reference in dropped item Dim lvwSub As ListSubItem 'Drop position Dim intTgtIndex As Integer Dim j As Integer Set lvwDrop = lvwList.HitTest(x, y) Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item 'Ignore overlapping drag or drop Item actions If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If 'Save the droped position Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'For j = intTgtIndex To ListItems.Count 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True 'Destroy all objects Set lvwTarget = Nothing Set lvwDrag = Nothing Set lvwDrop = Nothing Set lvwList.DropHighlight = Nothing End Sub Private Sub cmdClose_Click() DoCmd.Close acForm, Me.Name End Sub
新しく追加されたサブルーチンListView1_OLEDragOver()、ListView1_OLEDragDrop()、Form_Unload()、を除いて、上記のVBAコードに精通しています。 およびListView1_ColumnClik() 手順。最初の2つの手順は、アイテム(行)をドラッグして別のアイテムの上にドロップし、新しい場所に挿入するのに役立ちます。プロシージャForm_Unload()およびListView1_ColumnClick()は、アイテムを並べ替えます。
次の画像は、実行シーケンスでのドラッグアンドドロップアクションを示しています
以下の最初の画像は、ドラッグアンドドロップアクションシーケンスを示しています。 EmployeeID 7のListItemはユーザーによって上にドラッグされ、ID3のListItemの上にドロップされます。
2番目の画像は、ListItemの逆順の移動を示しています。
マウスポインタがドラッグされたアイテムのある行の上を移動すると、ソース行とターゲット行の間で、上に行く途中で次々にハイライト表示されます。
写真のドラッグアンドドロップアクション。
従業員ID7の行は、上記の従業員ID3のアイテムにドロップされます。VBAコードのセグメントごとの分析。
ListBoxからのアイテム選択List0_Click()イベントプロシージャが実行され、レコードがListViewコントロールにロードされます。
Private Sub List0_Click() Dim strTable As String strTable = List0.Value Call LoadListView(strTable) End Sub
選択したテーブル/クエリ名がstrTableに保存されます 文字列変数。 LoadListView() サブルーチンは、パラメーターとしてstrTable変数を使用して実行されます。以前のセッションでこのコードを複数回確認しました。詳細については、このページの下部にあるリンクを使用してこれらのページにアクセスしてください。このコードで私が行ったいくつかの小さな変更が見つかるかもしれません。
このエピソードでは、ImageListコントロールを使用していません。 Icon、SmallIcon ListItems.Add()メソッドおよび ReportIcon、TooltipTextのパラメーター値 ListSubItems.Add()メソッドのパラメーター値も使用されません。
ListView1_OLEDragOver()で何が起こっているかを見てみましょう およびListView1_OLEDragDrop() VBAコードセグメント。
ListView1_OLEDragOver()プロシージャ。
Private Sub ListView1_OLEDragOver(Data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer) 'Highlight the item when draged over it Set ListView1.DropHighlight = ListView1.HitTest(x, y) End Sub
この手順は、行をクリックして押したまま、ターゲット行に向かう途中で他の行をドラッグして移動しようとすると、自動的に実行されます。ドラッグアクションは、強調表示される別の行に移動します。
ListView1.HitTest(x、y) 関数は、ListViewコントロール上の行の位置を決定するx、y座標を読み取り、その行を強調表示します。このプロセスは、他の行の上にあるときに、マウスボタンを離してターゲット行にドロップするまで続きます。ドロップアクションは、 ListView1_OLEDragDrop()をトリガーします プロシージャを実行し、ソース行の切り替えプロシージャを実行します。
ListView1_OLEDragDropプロシージャ。
Private Sub ListView1_OLEDragDrop(Data As Object, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single) 'Item being dragged Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Item being added to the list Dim lvwTarget As ListItem 'Subitem reference used in For . . .Next loop
Dim lvwSub As ListSubItem 'Drop position index Dim intTgtIndex As Integer Set lvwDrop = lvwList.HitTest(x, y) 'save the source item Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item 'Ignore overlapping drag or drop Item actions If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If 'Save the droped position Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True 'Destroy all objects Set lvwTarget = Nothing Set lvwDrag = Nothing Set lvwDrop = Nothing Set lvwList.DropHighlight = Nothing End Sub
この手順を部分的に確認し、そこで何が起こっているのかを理解しましょう。次のコードセグメントは、ドラッグアンドドロップアクションを処理するために必要なオブジェクト変数を宣言しています。
'Item being dragged Dim lvwDrag As ListItem 'Item being dropped on Dim lvwDrop As ListItem 'Reference of the Item being added to the list Dim lvwTarget As ListItem 'Subitem reference used in For . . .Next loop Dim lvwSub As ListSubItem 'Drop position index Dim intTgtIndex As Integer Set lvwDrop = lvwList.HitTest(x, y) Set lvwDrag = lvwList.SelectedItem 'save a copy of draged item
最初の3つのListItem一時オブジェクトは異なる名前で宣言します。
lvwDrag ListItemオブジェクトは、新しい場所にドラッグするために選択した行のコピーを保持します。
lvwDrop ListItemオブジェクトは、ドラッグされたリストアイテムをドロップした行の参照を保存します。
ListItemsアクションの切り替え中に、元の場所からソースアイテムを削除してから、ソースのListItemインデックス番号を使用してターゲットの場所に作成します。この新しいListItemの参照は、 lvwTargetに保存されます ListItemオブジェクト変数。
lvwSub Forでシーケンスオブジェクト変数として宣言された変数。 。 。次へ ループ。このループでは、lvwDragオブジェクトからListSubItems(2列目以降)を1つずつ順番に並べる必要があります。元のListItemを削除しましたが、そのコピーをlvwDragListItemオブジェクトに保存しました。
lvwDropListItemインデックス番号はintTgtIndexに保存されます 可変。
lvwList.HitTest(x、y) 関数は、ListViewコントロールのx、y座標を読み取り、ソースListItemをドロップしたターゲットListItemを識別し、lvwDropオブジェクトにそのコピーを作成します。
新しい位置にドラッグする前に、まずListItemを選択します。
lvwList.SelectedItem プロパティはTrueに設定されます。このプロパティステータスを使用して、選択したListItemのコピーを lvwDragに作成します。 ListItemオブジェクト。次のコードセグメントは、ソースとターゲットの両方のListItemオブジェクトを検証します。
ドラッグアンドドロップアクションの検証チェック。
'Ignore overlapping drag or drop Item actions, 'OR drag and drop happens on the same ListItem. If (lvwDrop Is Nothing) Or (lvwDrag Is Nothing) Or (lvwDrop = lvwDrag) Then Set lvwList.DropHighlight = Nothing Set lvwDrop = Nothing Set lvwDrag = Nothing Exit Sub End If
上記のコードセグメントは、ドラッグアンドドロップアクションを検証します。これらのアクションが有効なアイテムで開始または終了しなかった場合、lvwDropまたはlvwDragオブジェクト、あるいはその両方が空になります。または、ユーザーが行を上下に移動するときに別の無効な移動が発生する可能性がありますが、気が変わって同じ行にドロップする可能性があります。このような間違った動きを検出すると、プログラムは終了します。
上記のテストが有効であることが証明された場合、プログラムは行を再配置するために次の手順を実行し続けます。
'Save the dropped position ListItem Index Number intTgtIndex = lvwDrop.Index 'Remove Dragged Item from its old position lvwList.ListItems.Remove lvwDrag.Index 'Creates a new Item in the Target Item position 'with the Dropped Item Index Number and Dragged Item.Text. 'Saves the new Item reference in lvwTarget Item. '* The original Droped-on Target) Item will be moved down '* by incrementing its original Index Number Set lvwTarget = lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) 'Copy the original Draged Item's subitems to the new item If lvwDrag.ListSubItems.Count > 0 Then For Each lvwSub In lvwDrag.ListSubItems lvwTarget.ListSubItems.Add , lvwSub.Key, lvwSub.Text Next End If 'Highlight the draged item in its new position lvwTarget.Selected = True
上記の9行の実行可能コード(他の行はコメントです)のアクションはやや簡単です。
intTgtIndex =lvwDrop.Index ステートメントは、ターゲットListItemのインデックス番号を intTgtIndexに保存します 可変。
ソース行listItemは一時オブジェクトlvwDragにすでに保存されているので、次のステップは、ListViewコントロールからソースListItemを削除することです。 ListItems.Remove()プロシージャ ステートメントlvwList.ListItems.RemovelvwDrag.Index を使用して、が呼び出されます。 。
つまり、ドラッグアンドドロップアクションは、ListItemを元の場所から削除し、ターゲット行のインデックス番号を使用してターゲットの場所に再度作成することです。
ステートメントSetlvwTarget =lvwList.ListItems.Add(intTgtIndex、、lvwDrag.Text) ターゲットロケーションインデックス番号intTgtIndexとTextを使用して新しいListItemを作成します 以前にlvwDragオブジェクトに保存されたSourceListItemの値。
ListItemを初めて作成するときは、インデックスとテキストの2つの値のみを使用しました。 パラメータ値。他のパラメータオプションキー、アイコンは使用していません およびSmallIcon それ以外の場合は、lvwDragオブジェクトからもこれらのパラメータ値を含める必要があります。
上記のドラッグドロップの例の画像に従って、7番目のListItemを移動し、3番目のListItemにドロップしました。その後、ListViewコントロールから7番目のアイテム(またはソースListItem)を削除しました。ターゲットインデックス番号3の新しいListItemを作成しました。
これで、同じインデックス番号3の2つのアイテムがあり、既存のアイテムはインデックス番号3で、新しいアイテムはインデックス番号3で作成しました。他のすべての情報はlvwDragオブジェクト(またはlvwDragに保存された7番目のListItem)から取得されます。以前のオブジェクト)。
システムは、既存のListItem3以降を次のシーケンス番号3,4,5に自動的にインクリメントします。 。 。 4,5,6に。 。 。前方に移動して、入ってくるアイテムを間に挿入するためのスペースを確保します。
行を削除して別の場所に作成した場合の影響。
ListItem番号3を上からドラッグしてアイテム番号7にドロップするなど、逆の順序で移動するとします。
当然、3番目のアイテムを削除し、新しい場所にインデックス番号7の新しいアイテムを作成しようとします。アイテム番号3が削除されると、アイテム番号4以降が上にシフトするか、4,5,6,7,8,9が3,4,5,6,7,8(すべてのアイテムを順番に作成するため)またはそれ以前になります。インデックス番号7のアイテムは6になります。
インデックス番号7の新しいアイテムを作成すると、既存の7,8は再び8,9になります。行の削除と作成時に行の移動を監視する場合、最初の例では、ターゲット行を下に移動して、着信アイテムに道を譲ります。説明した2番目の例(3から7に移動)では、宛先行が上に移動します。
注: 見る ListItemを再配置するときにListItemが下に移動したり上に移動したりするための手がかりとして配置するための従業員ID値。
ドラッグドロップ操作の至る所でListItemについて言及しました。 ListItemは、ListView行の最初の列のみを参照します。他の列の値は、ListSubItemsまたはListItemの子アイテムです。つまり、最初の列のみをドラッグアンドドロップできます。他の列またはListSubItemsは、VBAコード付きのListItemの下に移動されます。
これは、 FullRowSelectionを有効にしていない場合に当てはまります。 一般のListViewコントロールプロパティシート タブ。
有効にすると、任意の列を選択できますが、システムは行の並べ替えの目的でListItemインデックスを参照します。上記の2つの画像を、このページの上部にある3番目と4番目の画像の2つのサンプル画像の別のセットと比較します。
一般のListViewコントロールプロパティシートで次の2つのプロパティ値が設定されていない場合、ドラッグアンドドロップアクションは機能しません。 タブ:
- ccOLEDragAutomatic =1
- ccOLEDropManual =1
次の5つのステートメントは、 ListSubItemsを移動します もしあれば、新しい場所に新しく作成されたListItemに。
次に、新しく作成されたListItemが強調表示されます。
次に、作成されたすべての一時オブジェクトがメモリからクリアされます。
注: ここで注意すべきもう1つの重要な点は、この配置は一時的なものであり、フォームを閉じるか、ListViewコントロールに別のテーブル/クエリをロードすると失われることです。
ListItemsの変更された順序を永続的にしたい場合、または次に順序が変更されるまで、テーブル自体の現在のインデックス付き注文番号を更新できる必要があります。 Employeesテーブルにフィールド名IDを持つ新しい整数フィールドを追加しました。
従業員データをアルファベット順に並べ替えたサンプル画面を以下に示します。
従業員IDフィールドは自動番号フィールドであり、他の関連テーブルとリンクされているため、フィールド名IDを持つ新しい番号フィールドを追加しました。このフィールド値は、最初は従業員IDと同じシーケンス番号で手動で設定されます。このフィールド値は、最初はこの順序になります。ただし、ドラッグアンドドロップアクションにより、ListViewコントロールでデータを再配置すると、ListView行のデータの順序が変わる場合があります。
EmployeesQを見てください 以下に示すSQLのクエリ:
SELECT [FirstName] & " " & [LastName] AS EmployeeName, Employees.ID, Employees.EmployeeID, Employees.TitleOfCourtesy, Employees.Title, Employees.Address, Employees.City, Employees.Region, Employees.PostalCode, Employees.Country, Employees.HomePhone, Employees.Extension, Employees.Notes FROM Employees ORDER BY Employees.ID;
上記のクエリは、ListViewコントロールのデータソースとして使用され、IDフィールドで並べ替えられます。 IDフィールドは、ListViewコントロールのインデックス番号の変更された順序で更新されます。更新プロセスはForm_Unload()から実行されます フォームを閉じるときのイベント手順。この方法により、次回ListViewコントロールを開いたときに、データが前回並べ替えた順序になります。
Form_Unload() イベントプロシージャVBAコード。
Private Sub Form_Unload(Cancel As Integer) Dim lvItem As ListItem Dim tmp As Long Dim criteria As String Dim strfield As String Dim fld As String If strTable = "" Then Set lvwList = Nothing Exit Sub End If Set db = CurrentDb Set rst = db.OpenRecordset(strTable, dbOpenDynaset) For Each lvItem In lvwList.ListItems tmp = lvItem.Index strfield = lvwList.ColumnHeaders(1).Text 'EmployeeName criteria = strfield & " = " & Chr(34) & lvItem.Text & Chr(34) rst.FindFirst criteria If Not rst.NoMatch Then If (rst.Fields(strfield).Value = lvItem.Text) And (rst.Fields(1).Value = tmp) Then 'GoTo nextitem Else rst.Edit rst.Fields(1).Value = tmp 'replace ID number rst.Update End If Else MsgBox "Item: " & tmp & " Not Found!" End If Next rst.Close Set lvwList = Nothing Set lvItem = Nothing Set rst = Nothing Set db = Nothing End Sub
従業員名を確認してください 上の画像のフィールド値。それらはアルファベット順に並べられています。 Employeesテーブルの新しいIDフィールド値は、現在のListViewControlListItemインデックス番号シーケンスで更新されます。
次の点に注意すると、上記のコードで何が行われるかを簡単に理解できます。
-
ListItemの(最初の列)テキスト パラメータ値は従業員名であり、アルファベット順に並べられています。
-
ListViewコントロールのListItemには、画面に表示される順序で1から9までのインデックス番号があります。つまり、最初のアイテムのインデックス番号は1で、最後のアイテムのインデックス番号は9です。EmployeesTableIDフィールド値の元のデータはこの順序で。
-
テキストを取得します 最初のListItemの値(従業員名)を入力し、テーブルで名前を検索します。
-
レコードが見つかると、現在のListItemのインデックス番号がテーブルのIDフィールドで更新(置換)されます。
-
このプロセスは、テーブルの残りのすべてのレコードに対して繰り返されました。
VBAコードを見てみましょう。最初に、ソースデータテーブル/クエリがListViewコントロールにロードされたかどうかを確認しますか?
strTableの場合 変数がクエリ名で初期化されていない場合、ListViewコントロールは空です。この場合、ユーザーはフォームを開いて、クエリ名を選択せずにフォームを閉じて、データをListViewコントロールにロードします。 Form_Unload イベントプロシージャはこの時点で中止され、フォームを閉じます。
ListViewコントロールにデータがある場合、次のステップが実行され、ソースデータクエリEmployeesQを開いて更新します。
次のステップは、各ListItemを調べて、EmployeesレコードのIDフィールドのインデックス番号を更新することです。
まず、現在の行インデックス番号が tmpに保存されます 可変。
最初のlvwList.ColumnHeader名EmployeeName と従業員の名前 ListItem.Textから取得されます 基準の式に EmployeeName ="AndrewFuller"のような文字列変数。
rst.FindFirst Criteria コマンドは、ソースデータテーブルを検索して、指定された名前のレコードを見つけます。レコードが見つかると、現在のListItemインデックス番号がIDフィールドで更新されます。
このプロセスは、ListViewコントロールのすべての行に対して繰り返され、終了するとフォームが閉じられます。
次回、このクエリからListViewコントロールにレコードをロードすると、前回フォームを閉じたときと同じ順序でレコードが表示されます。
注: IDフィールドのデータを並べ替えて、ListViewコントロールに変更された順序で表示するには、ここでクエリが必要になりました。
この作業はすべて、最後に並べ替えられた順序でデータを保存するためのものでした。これにより、次にフォームを開いたときに、ListViewコントロールのデータがその順序になります。
Windowsエクスプローラーのような並べ替え方法。
Windowsエクスプローラーでは、任意の列見出しをクリックして、表示されたリストを昇順または降順で並べ替えることができます。列ヘッダーは、トグルボタンのように機能します。列ヘッダーを繰り返しクリックすると、列データが次の ListView1_ColumnClick()で昇順/降順で並べ替えられます。 イベント手順:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As Object) ' When a ColumnHeader object is clicked, the ListView control is ' sorted by the subitems of that column. With Me.ListView1 ' Set the SortKey to the Index of the ColumnHeader - 1 .SortKey = ColumnHeader.Index - 1 If .SortOrder = lvwAscending Then .SortOrder = lvwDescending Else .SortOrder = lvwAscending End If ' Set Sorted to True to sort the list. .Sorted = True End With End Sub
注: すべてのデータの並べ替えは、テキスト比較モードのみです。 ListItems およびListSubItems Add() メソッドの3番目のパラメーターであるListViewコントロールに表示される情報はテキストです。 タイプ。日付と数値はすべてテキストのみとして扱われます。
Windowsエクスプローラーは、最後に並べ替えられたアイテムの順序をフォルダーに保存します。そのフォルダを再度開くと、リストは以前にソートされた順序で表示されます。
Form_Unload()を使用 イベント手順Windowsエクスプローラーのこの機能は、従業員テーブルで可能になります。列を並べ替えた後でフォームを閉じると、インデックス付けされた順序シーケンスが従業員テーブルのIDフィールドに保存されます。 EmployeesQクエリは、開いたときに常にIDフィールドのデータを並べ替えます。
デモデータベースはダウンロード用に添付されています。データベースには2つのデモフォームがあります。最初のフォームは、データセットビューでデータを表示するためにListViewコントロールでテーブルとクエリを開く方法を示しています。 2番目のフォームは、 EmployeesQのみを使用します ドラッグ、ドロップ、並べ替え、および将来の使用のためにデータの最後の並べ替え順序を保存するために、単独でクエリを実行します。
- ActiveX ListViewControlTutorial-01。
- ListViewコントロールチュートリアル-02。
- ListViewアイテムへの画像の割り当て。
- ListViewコントロールのドラッグドロップソートイベント
- MS-AccessTreeViewを使用したListViewコントロール
- TreeView/ListViewはドラッグドロップイベントを制御します