はじめに。
先週のActiveXListViewコントロールチュートリアル-01からの続き。
チュートリアルのこのセッションでは、特定の行と列の値を検索して見つけ、フォームのラベルコントロールに表示する方法を学習します。これは、ListViewコントロールに大量のデータがある場合に非常に便利です。また、いくつかのListViewプロパティ設定の使用法についても学習します。
まず、Accessデータセットビューの場合と同様に、ListViewコントロールでの列の再配置がいかに簡単であるかを確認します。検索パラメーターの選択と検索結果の表示を容易にするために、いくつかのTextBox、ComboBox、Command Buttons、およびLabelを追加しました。
先週のデモデータにいくつか変更を加えました。 Northwind.accdbサンプルデータベースの従業員テーブルから取得した最初の列の値。キーとして使用されるフィールド名StudentおよびEmployeeID(X01、X02 ...)を使用してLastName値とFirstName値を結合するクエリを作成しました。
検索操作に進む前に、ドラッグアンドドロップ方式で列を再配置する方法を確認します。
注: 以前のチュートリアルページをまだ読んでおらず、このセッションを続行したい場合は、ListView Control Tutorial-01ページに移動し、そのページの下部からデモデータベースをダウンロードしてください。
ファイルを解凍し、データベースを開きます。デモフォームは通常表示になります。
-
最後のセッションのデモフォーム、または作成したフォームを使用してデータベースを開き、通常のビューで開きます。
次に、リストの中央から列(たとえば、Weight列)をドラッグアンド移動して、 Ageにドロップします。 列と何が起こるかを確認してください。予想されることは、Age列が右にシフトし、その場所に入力列を挿入することです。
-
Weight、という名前の列ヘッダーにマウスポインタを移動します マウスの左ボタンをクリックして押したままにします。マウスの左ボタンを押すと、列ヘッダーが少し下に移動します。
-
次に、列を左にドラッグして、列 Ageにドロップしてみます。 。
プロパティシートでこの機能を有効にしておらず、これが唯一の設定であるため、何も起こりません。この機能を機能させるには、変更する必要があります。
-
デザインビューでフォームを変更します。
-
ListViewコントロールを右クリックして、オプションListViewCtrlオブジェクトを強調表示します。 [プロパティ]を選択します。
-
オプション'AllowColumnReorder があります '右側にあります。チェックマークを付けて選択し、適用をクリックします ボタンに続いてOK ボタンをクリックしてプロパティビューを閉じます。
-
ここで、上記の手順2と3を繰り返して、何が起こるかを確認してください。
これが、ListViewコントロールでこの機能を有効にするために必要な唯一の設定です。おそらくあなたは考えているかもしれませんが、行を再配置するのはどうですか?。
その関数は、TreeViewコントロールのドラッグドロップイベントで以前に行ったように、いくつかのイベントプロシージャをプログラミングする必要があります。その部分はしばらくしてから行います。
-
最初の列も含めて、任意の列を試して好きな場所に移動できます。
注: ソース列をドロップする前に、ドロップを試みる前に、ターゲット列が入力列フレームで覆われていることを確認してください。そうしないと、入力列が右側の次の列位置に移動する可能性があります。
次に、大量のデータが含まれていると仮定して、ListViewからいくつかの情報をすばやく見つける方法を学習します。
Tutorial-01モジュールにサブルーチンを追加して、列ヘッダー名をフォームの赤い背景色のコンボボックスにロードします。列名は、生徒の列の値(年齢、身長、体重、またはクラス)を見つけるために使用されます。
フォームクラスモジュールに追加された新しいVBAコード。
次の新しいVBAプロシージャが、先週のチュートリアルフォームのクラスモジュールに追加されました。
txtColCombo ComboBoxに列ヘッダーラベル(フィールド名)のリストを作成します。生徒の年齢、身長、体重の詳細の1つ またはクラス 検索と検索操作の一部として、学生の名前と一緒に見つけることができます。
Private Sub txtColCombo() 'Column Header List Combo Dim lvwColHead As MSComctlLib.ColumnHeader Dim cboName As ComboBox Set cboName = Me.txtCol cboName.RowSourceType = "Value List" For Each lvwColHead In lvwList.ColumnHeaders If lvwColHead.Index = 1 Then 'Nothing Else cboName.AddItem lvwColHead.Text End If Next 'cboName.DefaultValue = "=txtCol.Column(0, 0)" Set lvwColHead = Nothing Set cboName = Nothing End Sub
コンボボックスには、デフォルト値の列ヘッダー名はロードされません。選択すると、学生のその列の値が学生名の下の大きなラベルに表示されます。空白のままにすると、検索操作で生徒の名前のみが検索されます。
検索操作方法は非常に柔軟で迅速です。レコードを見つけるには2つの方法があります。
検索テキストを提供してレコードを検索します。検索テキストは、左から数文字の全文または一部のテキストのいずれかの列から取得できます。 ListViewコントロールには2つのカテゴリのオブジェクトメンバーが連続しているため、 ListItem -最初の列と他の列はListSubItemsです。 これらのオブジェクトに対するテキスト検索操作は、個別に実行されます。
2つのチェックボックスを含むオプショングループが、フォームの検索テキスト入力テキストボックスの横に表示され、検索と検索のオプションを選択します。デフォルトでは最初のオプションが選択されており、検索は最初の列( ListItem )で実行されます。 )指定されたテキストを検索します。
2番目のオプションを選択して、 ListSubItem内のテキストを検索します 列。
注: 列を再配置してもオブジェクトは変更されませんが、表示位置のみが変更されます。 ListSubItemをドラッグする 列を最初の列に入れると変更されません ListItemに入れます オブジェクト。
特定の列から不明な値を取得する場合は、フォームの最初のテキストボックスの下にあるComboBoxから検索テキストの列名を選択します。たとえば、生徒の身長の測定値がわからず、調べたい場合は、列名身長を選択します。 ComboBoxから。
上記の値を設定したら、アイテムの検索をクリックします 検索操作に移動するコマンドボタン。検索が成功すると、結果はコマンドボタンの下の大きなラベルコントロールに表示されます。
[アイテムの検索]コマンドボタンをクリックします。
SearchAndFind()を呼び出します 手順。
Private Sub SearchAndFind() 'Find by Student Name Dim lstItem As MSComctlLib.ListItem Dim strFind As String Dim strColName As String Dim strColVal As String Dim j As Integer Dim intOpt As Integer Dim msgText As String Me.Refresh intOpt = Me.Opts strFind = Nz(Me![txtFind], "") strColName = Nz(Me![txtCol], "") Select Case intOpt Case 1 Set lstItem = lvwList.FindItem(strFind, , , lvwPartial) If Not lstItem Is Nothing Then j = lstItem.Index 'format the display text msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf Else MsgBox "Text '" & strFind & "' Not Found!", vbOKOnly + vbCritical, "cmdFind_Click()" Exit Sub End If Case 2 Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial) If Not lstItem Is Nothing Then 'format the display text j = lstItem.Index msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf Else MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()" Exit Sub End If End Select If Len(strColName) = 0 Then 'If column name is not selected GoTo nextStep Else 'Get the column value strColVal = GetColVal(lstItem, strColName) msgText = msgText & String(8 - (Len(strColName)), " ") & _ strColName & ": " & Nz(strColVal, "") End If nextStep: If Len(msgText) > 0 Then 'assign to form label lvwList.ListItems.Item(j).Selected = True lblMsg.caption = msgText End If End Sub
プログラムの開始時に、両方の学生名 および列名( 0ptional )、 TextBoxから変数strFindにコピーされます およびstrColName それぞれ検証チェック後。
注: 列名ComboBoxのNot-in-ListプロパティがYesに設定されています。リストから有効な値を選択するか、入力するか、コンボボックスを空白のままにすることができます。リストにない別の値を入力すると、その値は受け入れられません。
選択した検索オプション(1-ListItemまたは2-ListSubItem)に基づいて、スキャンメソッドは指定されたオブジェクトに送信されます。
これらの検索メソッドのいずれかを使用すると、ListItemオブジェクトが見つかります または行 検索テキストが含まれています。 ListItemのインデックス値は変数Jに保存されます 後でプログラムで使用するため。
注: ListViewコントロール項目が入力されると、システムはインデックスの自動番号を自動的に作成します。
ListItem.Text 値が取得されます。この情報は、最初のColumnHeaderと結合されます。テキスト(Student:Robert Kingなど)をMsgtext文字列に追加して、フォームのラベルコントロールに表示します。
ComboBoxで[ヘッダー名]列が選択されている場合は、 GetColVal() 関数は、ListItemオブジェクトと列ヘッダーテキスト値をパラメーターとして使用して呼び出されます。このオプションは、学生の身長など、学生に関する不明な情報をレコードから取得するのに適しています。
GetColVal()関数のVBAコード。
Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String Dim i As Integer Dim strVal As String 'first column is student name 'check for column value from 2nd column onwards For i = 2 To lvwList.ColumnHeaders.Count If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value Exit For 'No further scanning required End If Next GetColVal = strVal 'return the retrieved the value End Function
上記の関数は2つのパラメーターを要求します。最初のパラメータはListItemで、ここに学生の名前があります。 2番目のパラメーターは列名です。選択した生徒の年齢、身長、体重、階級 値はListItem.ListSubItemsに保存されます オブジェクト。関数はlvwList.ColumnHeaderを調べます 一致する列名を見つけるための値。列インデックス番号がListSubItemsオブジェクトから列値を取得するために使用され、その値が呼び出し元のプログラムに返されることがわかった場合。
[キーで検索]コマンドボタンクリックイベント手順。
ListItemの一意キー値を使用して生徒の名前を検索する別のメソッドが追加されました ListItemリストの作成中に使用した場合。オプションですが、無視するのではなく、一意のキー文字列値(アルファベット文字で始まる必要があります)を追加することをお勧めします。
たとえば、社会保障番号、国民身分証明書番号、パスポート番号、運転免許証番号などの識別番号で誰かの情報を検索する必要がある場合、この情報の1つをListItemのキー値として使用できます。この一意の値を持つレコードを見つけることは、上記のテキストによる検索方法よりも非常に簡単で迅速です。
cmdKey_Click()イベントプロシージャ。
Calls FindByKey() Subroutine.
Private Sub FindByKey() Dim colHeader As MSComctlLib.ColumnHeader Dim lvItem As MSComctlLib.ListItem Dim lvKeyVal As String Dim lvColName As String Dim txt As String Dim msgText As String Dim varcolVal As Variant lvKeyVal = UCase(Nz(Me!txtKey, "")) lvColName = Nz(Me!txtCol, "") If len(lvKeyVal) > 0 then On Error Resume Next Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key If Err > 0 Then Err.Clear MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()" On Error GoTo 0 Exit Sub End If Else MsgBox "Please Provide a Valid Key-Value!",vbOKOnly + vbCritical, "cmdKey_Click()" Exit Sub End If txt = lvItem.Text 'get the student name 'format message text msgText = lvwList.ColumnHeaders.Item(1).Text & " : " msgText = msgText & txt & vbCr & vbCrLf If Len(lvColName) > 0 Then 'if column name is given varcolVal = GetColVal(lvItem, lvColName) 'get column val of student msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display End If lvItem.Selected = True 'highlight the item on form Me.lblMsg.caption = msgText 'assign details to form Label End Sub
上記のサブルーチンでわかるように、 ListItemを直接見つけることができます。 ここで、生徒の名前は、キー値、を使用しています。 単一のステートメントで: Set lvItem =lvwList.ListItems.Item(xKeyVal)。
次の行は、ListItemテキスト(または学生の名前)を変数 txtに読み込みます。 。次の2行は、msgText文字列変数に学生の名前を含むメッセージテキストを作成します。
次のもし。 。 。次に ステートメントは、列名の値がコンボボックスコントロールに入力されているかどうかを確認します。見つかった場合は、 GetColVal()を呼び出します。 列の値を見つけてvarColValで取得するために必要なパラメーターを使用して、関数を実行します。 変数であり、呼び出し元のプログラムに戻ります。取得した列名とその値がmsgText文字列変数に追加され、フォームのラベルコントロールに表示されます。
次のステートメントは、検索されたアイテムが行にあることを視覚的に示すものとして、レコードRow oftheStudentを強調表示しています。 msgText値は、フォームのラベルのキャプションプロパティに表示されます。
フォームモジュールの完全なVBAコード。
Option Compare Database Option Explicit Dim lvwList As MSComctlLib.ListView 'ListView Control Dim lvwItem As MSComctlLib.ListItem ' Dim ObjImgList As MSComctlLib.ImageList Const prfx As String = "K" Private Sub Form_Load() Call LoadListView Call txtColCombo End Sub Private Function LoadListView() 'Populate the ListView control with Student Details Dim db As DAO.Database Dim rst As DAO.Recordset Dim intCounter As Integer Dim strKey As String 'Assign ListView Control on Form to lvwList Object Set lvwList = Me.ListView1.Object With lvwList .AllowColumnReorder = True .Enabled = True .Font = "Verdana" .Font.Bold = True .Font.Size = 9 .ForeColor = vbBlack .BackColor = vbWhite End With 'Create Column Headers for ListView With lvwList .ColumnHeaders.Clear 'initialize header area 'Syntax: .ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon .ColumnHeaders.Add , , "Student", 2500 .ColumnHeaders.Add , , "Age", 1200 .ColumnHeaders.Add , , "Height", 1200 .ColumnHeaders.Add , , "weight", 1200 .ColumnHeaders.Add , , "Class", 1200 End With 'Initialize ListView Control While lvwList.ListItems.Count > 0 lvwList.ListItems.Remove (1) Wend 'Student Names and Ids are taken from Employees Table 'through the StudentQ Query. Set db = CurrentDb Set rst = db.OpenRecordset("StudentQ", dbOpenDynaset) With lvwList Do While Not rst.EOF And Not rst.BOF intCounter = rst![EmployeeID] strKey = "X" & Format(intCounter, "00") 'Key Value sample: X01 'Syntax: .ListItems.Add(Index, Key, Text, Icon, SmallIcon) Set lvwItem = .ListItems.Add(, strKey, rst![Student]) With lvwItem 'Syntax: .Add Index,Key,Text,Report Icon,TooltipText .ListSubItems.Add , strKey & CStr(intCounter), CStr(5 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 1), CStr(135 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 2), CStr(40 + intCounter) .ListSubItems.Add , strKey & CStr(intCounter + 3), ("Class:" & Format(intCounter, "00")) End With rst.MoveNext Loop rst.Close Set rst = Nothing Set db = Nothing Set lvwItem = Nothing End With lvwList.Refresh End Function Private Sub cmdClose_Click() DoCmd.Close acForm, Me.Name End Sub Private Sub cmdFind_Click() Call SearchAndFind End Sub Private Sub cmdKey_Click() Call FindByKey End Sub Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String Dim i As Integer Dim strVal As String 'first column is student name 'check for column value from 2nd column onwards For i = 2 To lvwList.ColumnHeaders.Count If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value Exit For 'No further scanning required End If Next GetColVal = strVal 'return the retrieved the value End Function Private Sub txtColCombo() 'Column Header List Combo Dim lvwColHead As MSComctlLib.ColumnHeader Dim cboName As ComboBox Set cboName = Me.txtCol cboName.RowSourceType = "Value List" For Each lvwColHead In lvwList.ColumnHeaders If lvwColHead.Index = 1 Then 'Nothing Else cboName.AddItem lvwColHead.Text End If Next 'cboName.DefaultValue = "=txtCol.Column(0, 0)" Set lvwColHead = Nothing Set cboName = Nothing End Sub Public Sub SearchAndFind() 'Find by Student Name Dim lstItem As MSComctlLib.ListItem Dim strFind As String Dim strColName As String Dim strColVal As String Dim j As Integer Dim intOpt As Integer Dim msgText As String Me.Refresh intOpt = Me.Opts strFind = Nz(Me![txtFind], "") strColName = Nz(Me![txtCol], "") Select Case intOpt Case 1 Set lstItem = lvwList.FindItem(strFind, , , lvwPartial) If Not lstItem Is Nothing Then j = lstItem.Index 'format the display text msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf Else MsgBox "Text '" & strFind & "' Not Found in the List!", vbOKOnly + vbCritical, "cmdFind_Click()" Exit Sub End If Case 2 Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial) If Not lstItem Is Nothing Then 'format the display text j = lstItem.Index msgText = lvwList.ColumnHeaders.Item(1).Text msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf Else MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()" Exit Sub End If End Select If Len(strColName) = 0 Then 'If column name is not selected GoTo nextStep Else 'Get the column value strColVal = GetColVal(lstItem, strColName) msgText = msgText & String(8 - (Len(strColName)), " ") & _ strColName & ": " & Nz(strColVal, "") End If nextStep: If Len(msgText) > 0 Then 'assign to form label lblMsg.caption = msgText lvwList.ListItems.Item(j).Selected = True End If End Sub Public Sub FindByKey() Dim colHeader As MSComctlLib.ColumnHeader Dim lvItem As MSComctlLib.ListItem Dim lvKeyVal As String Dim lvColName As String Dim txt As String Dim msgText As String Dim varcolVal As Variant lvKeyVal = UCase(Nz(Me!txtKey, "")) lvColName = Nz(Me!txtCol, "") On Error Resume Next If Len(lvKeyVal) > 0 Then Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key If Err > 0 Then Err.Clear MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()" On Error GoTo 0 Exit Sub End If Else MsgBox "Please Provide a Valid Key-Value!", vbOKOnly + vbCritical, "cmdKey_Click()" Exit Sub End If txt = lvItem.Text 'get the student name 'format message text msgText = lvwList.ColumnHeaders.Item(1).Text & " : " msgText = msgText & txt & vbCr & vbCrLf If Len(lvColName) > 0 Then 'if column name is given varcolVal = GetColVal(lvItem, lvColName) 'get column val of student msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display End If lvItem.Selected = True 'highlight the item on form Me.lblMsg.caption = msgText 'assign details to form Label End Sub
次のリンクからデモデータベースをダウンロードします:
- MicrosoftTreeViewControlチュートリアル
- TreeViewコントロールを使用したアクセスメニューの作成
- TreeViewノードへの画像の割り当て
- TreeViewノードへの画像の割り当て-2
- TreeViewコントロールチェックマーク追加削除
- TreeViewImageComboドロップダウンアクセス
- ドラッグアンドドロップでTreeViewノードを再配置
- MS-AccessTreeViewを使用したListViewコントロール
- ListViewコントロールのドラッグドロップイベント
- サブフォームを使用したTreeViewコントロール