Přeuspořádání řádků dat v ovládacím prvku ListView.
V dřívější epizodě tohoto kurzu jsme se naučili, jak změnit uspořádání sloupců povolením této funkce:AllowColumnReorder možnost na listu vlastností. Ale přemístění řádku se provádí přetažením a umístěním na jiný řádek. Chcete-li změnit uspořádání řídicích řádků ListView, akce Přetažení položky seznamu vyžaduje povolení této funkce na listu vlastností. Ale to samo o sobě nebude fungovat, potřebuje kód VBA k přeuspořádání položky do požadovaného pořadí.
Vytvořme vzorový přístupový formulář s ovládacími prvky a kódem VBA v naší databázi pro toto cvičení. Ukázkový obrázek formuláře s ovládacími prvky ListBox a ListView je uveden níže.
Vytvořili jsme seznam tabulek a dotazů (nikoli akční dotazy) v seznamu. Výběrem jedné z položek seznamu se záznamy okamžitě zobrazí v ovládacím prvku ListView, jak je vidíme v zobrazení DataSheet.
Úloha návrhu.
-
Vytvořte novou tabulku s jedním textovým polem s názvem pole DataList .
-
Uložte tabulku pod názvem lvTables (lv znamená ListView).
-
Otevřete tabulku v zobrazení datového listu.
-
Přidejte několik názvů tabulek a vyberte názvy dotazů z databáze do tabulky. Importoval jsem tabulky z ukázkové databáze Northwind pro svůj seznam.
Poznámka: Příloha Pole není platné v ovládacím prvku ListView. Vytvořte výběrové dotazy pro tabulky s polem přílohy a vyberte všechna pole kromě pole Příloha.
-
Vytvořte a otevřete nový formulář v návrhovém zobrazení.
-
Vložte do formuláře ovládací prvek ListBox, zobrazte list vlastností a změňte jeho Název hodnotu vlastnosti na Seznam0 .
-
Změňte podřízený štítek Titulek hodnotu do tabulek .
-
Zobrazte seznam vlastností ovládacího prvku ListBox a nastavte Zdroj řádku hodnotu vlastnosti do lvTables jméno.
-
Zkontrolujte, zda je Typ zdroje řádků nastaven jako Tabulka/Dotaz a hodnota vlastnosti Vázaný sloupec je 1. Pokud se liší, změňte je.
-
Vložte ovládací prvek ListView ze seznamu ovládacích prvků ActiveX a změňte jeho hodnotu vlastnosti Name na ListView1 .
-
Změňte velikost obou ovládacích prvků, jak je znázorněno na výše uvedeném ukázkovém obrázku formuláře.
-
Vložte popisek nad ovládací prvky a změňte jeho hodnoty vlastnosti Name a Caption na Nadpis. Hodnota Caption se změní z kódu vba, když je v seznamu vybrána tabulka nebo dotaz.
-
Vytvořte příkazové tlačítko pod ovládacími prvky a změňte hodnotu jeho vlastnosti Name na cmdClose a hodnotu vlastnosti Caption na Zavřít .
-
Klepněte pravým tlačítkem myši na ovládací prvek ListView a zvýrazněte Objekt ListViewCtrl a vyberte Vlastnosti .
-
Změňte nastavení vlastnosti tak, aby odpovídalo nastavení v Obecné Obrázek karty níže.
-
Obrázek listu vlastností ovládacího prvku ListView – zobrazení karty Obecné je uvedeno níže:
Některé z těchto možností jsme již nastavili v dřívějších relacích. Zde potřebujeme následující možnosti pro naši akci Drag Drop:
-
OLEDragAutomatic - 1
-
OLEDropManual – 1
-
FullRowSelect - True
-
HotTracking – pravda
-
Ujistěte se, že výše uvedená nastavení odpovídají vašemu listu vlastností, a poté formulář uložte.
Zobrazte modul VBA formuláře.
Kód VBA modulu formuláře.
Zkopírujte a vložte následující kód VBA do modulu a přepište existující řádky kódu, pokud existují:
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
Výše uvedený kód VBA znáte kromě nově přidaných podprogramů:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), a ListView1_ColumnClik() postupy. První dva postupy nám pomohou přetáhnout položku (řádek) a umístit ji na jinou položku a vložit ji na nové místo. Procedury Form_Unload() a ListView1_ColumnClick() seřadí položky.
Následující obrázky ukazují akci Drag and Drop v sekvencích jejího provádění
První obrázek níže ukazuje sekvenci akcí přetažení. Položka ListItem s EmployeeID 7 je uživatelem přetažena nahoru a puštěna přes ListItem s ID 3.
Druhý obrázek ukazuje přesun položky ListItem v opačném pořadí.
Když se ukazatel myši přesune přes řádek s přetaženou položkou, mezi zdrojovým a cílovým řádkem se na cestě nahoru jeden po druhém zvýrazní.
Akce přetažení v obrázcích.
Řádek s ID zaměstnance 7 je vynechán u položky s ID zaměstnance 3 výše.Analýza kódu VBA podle segmentů.
Spustí se výběr položky z ListBoxu, procedura události List0_Click() a načte záznamy do ovládacího prvku ListView.
Private Sub List0_Click() Dim strTable As String strTable = List0.Value Call LoadListView(strTable) End Sub
Vybraný název tabulky/dotazu se uloží do strTable řetězcová proměnná. LoadListView() podprogram běží s proměnnou strTable jako parametrem. Tento kodex jsme procházeli více než jednou v předchozích relacích a tyto stránky můžete navštívit pomocí odkazů uvedených v dolní části této stránky, kde najdete podrobnosti. V tomto kodexu můžete najít několik drobných změn, které jsem provedl.
V této epizodě jsme nepoužili ovládací prvek ImageList Icon, SmallIcon Hodnoty parametrů v metodě ListItems.Add() a ReportIcon, TooltipText hodnoty parametrů v metodě ListSubItems.Add() se také nepoužívají.
Podívejme se, co se děje v ListView1_OLEDragOver() a ListView1_OLEDragDrop() Segmenty kódu VBA.
Procedura 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
Tento postup se automaticky spustí, když se pokusíte kliknout a podržet na řádku, začnete přetahovat a přesouvat další řádky na cestě k cílovému řádku. Akce přetažení se přesune přes další řádek a zvýrazní se.
ListView1.HitTest(x, y) funkce čte souřadnice x, y, které určují pozici řádku v ovládacím prvku ListView, a zvýrazní tento řádek. Tento proces pokračuje, když jste přes další řádky, dokud jej neuvolníte na cílový řádek uvolněním tlačítka myši. Akce přetažení spustí ListView1_OLEDragDrop() proceduru a provede změnu procedury zdrojového řádku.
Procedura 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
Podívejme se na tento postup po částech a pochopíme, co se tam děje. Následující segment kódu deklaruje nezbytné proměnné objektu ke zpracování akce Drag and Drop:
'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
První tři ListItem dočasné objekty deklarují s různými názvy.
lvwDrag Objekt ListItem bude obsahovat kopii řádku, který jsme vybrali k přetažení do nového umístění.
lvwDrop ListItem Object uloží odkaz na řádek, na který jsme přetáhli položku seznamu.
Během změny akce ListItems odstraníme zdrojovou položku z jejího původního umístění a poté ji vytvoříme v cílovém umístění se zdrojovým číslem indexu položky seznamu. Reference tohoto nového ListItem se ukládají do lvwTarget Objektová proměnná ListItem.
lvwSub Proměnná deklarovaná jako sekvenční objektová proměnná v For . . .Další Smyčka. Toto opakování vyžaduje postupné postupné procházení ListSubItems (2. sloupec dále) jeden po druhém z objektu lvwDrag. I když jsme smazali původní ListItem, uložili jsme jeho kopii do objektu lvwDrag ListItem.
Indexové číslo lvwDrop ListItem je uloženo v intTgtIndex Proměnná.
lvwList.HitTest(x, y) Funkce čte souřadnice x, y ovládacího prvku ListView a identifikuje cílový ListItem, kam jsme upustili zdrojový ListItem, a vytvoří jeho kopii v lvwDrop Object.
Nejprve vybereme položku ListItem, než ji přetáhneme na novou pozici.
lvwList.SelectedItem Vlastnost bude nastavena jako True. S pomocí tohoto stavu vlastnosti vytvoříme kopii vybrané položky seznamu do lvwDrag Objekt ListItem. Další segment kódu ověřuje zdrojové i cílové objekty seznamu položek.
Ověřovací kontroly akce Drag-Drop.
'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
Výše uvedený segment kódu ověřuje akci přetažení. Pokud tyto akce nezačaly nebo neskončily na platné položce, objekty lvwDrop nebo lvwDrag nebo oba budou prázdné. Nebo může dojít k jinému neplatnému přesunu, když uživatel posune řádek nahoru nebo dolů, ale může změnit názor a pustit jej zpět na stejný řádek. Detekce těchto druhů chybných pohybů ukončí program.
Pokud se výše uvedený test ukáže jako platný, program bude pokračovat v provádění další procedury pro změnu uspořádání řádků.
'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
Výše uvedených devět řádků akcí spustitelného kódu (ostatní řádky jsou komentáře) je poněkud přímočarých.
intTgtIndex =lvwDrop.Index příkaz uloží indexové číslo cílové položky ListItem do intTgtIndex Proměnná.
Protože jsme již uložili položku Source Row listItem do dočasného objektu lvwDrag, dalším krokem je odstranit zdrojovou položku ListItem z ovládacího prvku ListView. Procedura ListItems.Remove() je voláno s příkazem lvwList.ListItems.Remove lvwDrag.Index .
Stručně řečeno, akcí Drag Drop je odstranit položku seznamu z jejího původního umístění a znovu ji vytvořit v cílovém umístění s indexovým číslem cílového řádku.
Příkaz Set lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) vytvoří nový ListItem s číslem indexu cílové lokality intTgtIndex a Text hodnotu položky Source ListItem uložené dříve v objektu lvwDrag.
Při prvním vytváření ListItem jsme použili pouze tyto dvě hodnoty, index a Text hodnoty parametrů. Nepoužili jsme ostatní možnosti parametru Klíč, ikona a SmallIcon jinak musíme tyto hodnoty parametrů zahrnout také z objektu lvwDrag.
Podle našeho příkladu Drag Drop obrázků uvedených výše jsme přesunuli 7. položku seznamu a umístili ji na 3. položku seznamu. Poté jsme odstranili 7. položku (nebo zdrojovou položku ListItem) z ovládacího prvku ListView. Vytvořil nový ListItem s cílovým indexem číslo 3.
Nyní existují dvě položky se stejným indexovým číslem 3, stávající s indexovým číslem 3 a nová, kterou jsme vytvořili s indexovým číslem 3. Všechny ostatní informace jsou převzaty z objektu lvwDrag (nebo 7. ListItem uloženého v lvwDrag Objekt dříve).
Systém automaticky inkrementuje existující ListItem 3 dále na další pořadová čísla 3,4,5. . . až 4,5,6. . . a posouvá je dopředu, aby poskytl prostor pro vložení příchozí položky.
Vliv smazání řádku a jeho vytvoření jinde.
Předpokládejme, že tento pohyb provedeme v opačném pořadí, například přetáhněte položku ListItem číslo 3 shora a pusťte ji na položku číslo 7, co se stane?
Přirozeně smažeme 3. položku a pokusíme se vytvořit novou položku s indexovým číslem 7 v novém umístění. Když je položka číslo 3 vymazána, položka číslo 4 a dále se posune nahoru nebo 4,5,6,7,8,9 se změní na 3,4,5,6,7,8 (aby byly všechny položky v pořadí) nebo dříve položka s indexovým číslem 7 se změní na 6.
Když vytvoříme novou položku s indexovým číslem 7, stávající 7,8 se opět změní na 8,9. Když sledujeme pohyb řádků při mazání a vytváření řádku, první příklad přesune cílový řádek dolů, aby uvolnil místo pro příchozí položku. Ve druhém vysvětleném příkladu (přesun 3 až 7) se cílový řádek posune nahoru.
Poznámka: Sledujte thodnota ID zaměstnanců pro její umístění jako vodítko pro posun položky ListItem dolů nebo nahoru, když změníme uspořádání položky ListItem.
Všude jsem zmínil ListItem v operacích drag-drop. ListItem odkazuje pouze na první sloupec řádku ListView. Další hodnoty sloupců jsou ListSubItems nebo podřízené položky ListItem. To znamená, že budete moci přetáhnout pouze první sloupec. Ostatní sloupce nebo ListSubItems budou přesunuty pod ListItem s kódem VBA.
To platí, pokud jste nepovolili FullRowSelection na listu vlastností ListView Control na Obecné Tab.
Je-li povoleno, můžete vybrat libovolný sloupec, ale pro účely změny pořadí řádků se systém odvolává na index ListItem. Porovnejte dva výše uvedené obrázky s další sadou dvou ukázkových obrázků, třetím a čtvrtým obrázkem z horní části této stránky.
Akce přetažení nebude fungovat, pokud následující dvě hodnoty vlastnosti nejsou nastaveny na listu vlastností ovládacího prvku ListView v Obecné Tab.:
- ccOLEDragAutomatic =1
- ccOLEDropManual =1
Následujících pět příkazů přesune ListSubItems pokud existuje, do ListItem nově vytvořeného v novém umístění.
Dále se zvýrazní nově vytvořená ListItem.
Dále jsou všechny vytvořené dočasné objekty vymazány z paměti.
Poznámka: Dalším důležitým bodem, který je třeba poznamenat, je, že toto uspořádání je dočasné a ztratí se, když zavřete formulář nebo načtete jinou tabulku/dotaz do ovládacího prvku ListView.
Pokud chceme, aby změněné pořadí ListItems zůstalo trvalé, nebo dokud se pořadí příště nezmění, musíme být schopni aktualizovat aktuální indexované číslo objednávky na samotné tabulce. Do tabulky Zaměstnanci jsme přidali nové pole Integer s ID názvu pole.
Ukázková obrazovka s údaji o zaměstnancích přeskupených v abecedním pořadí je uvedena níže:
Protože pole ID zaměstnance je polem AutoNumber a je propojeno s dalšími souvisejícími tabulkami, přidali jsme nové pole čísla s názvem pole ID. Tato hodnota pole je zpočátku nastavena se stejnými pořadovými čísly z ID zaměstnance ručně. Tato hodnota pole bude zpočátku v tomto pořadí. Data řádků ListView však mohou změnit své pořadí, když změníte uspořádání dat v ovládacím prvku ListView kvůli akci přetažení.
Podívejte se na EmployeesQ Dotaz SQL uvedený níže:
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;
Výše uvedený dotaz se používá jako zdroj dat pro ovládací prvek ListView a jsou seřazeny podle pole ID. Pole ID se aktualizuje se změněným pořadím indexových čísel v ovládacím prvku ListView. Proces aktualizace se spouští z Form_Unload() Událostní procedura při zavření formuláře. Tato metoda zajišťuje, že při příštím otevření ovládacího prvku ListView budou data v pořadí, v jakém jste si naposledy přeuspořádali.
Funkce Form_Unload() Kód VBA procedury události.
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
Zkontrolujte Jméno zaměstnance Hodnota pole na obrázku výše. Jsou uspořádány v abecedním pořadí. Nová hodnota pole ID v tabulce Zaměstnanci bude aktualizována jejich aktuální posloupností čísel indexu ListView Control ListItem.
Pokud si všimnete následujících bodů, snadno pochopíte, co děláme s výše uvedeným kódem:
-
Text položky ListItem (první sloupec). hodnota parametru je jméno zaměstnance a je uspořádáno v abecedním pořadí.
-
ListItems v ovládacím prvku ListView má indexová čísla od 1 do 9 v pořadí, v jakém jsou zobrazena na obrazovce, tj. indexové číslo první položky je 1 a poslední je 9. Původní údaje o hodnotě pole ID tabulky zaměstnanců nejsou v tomto pořadí.
-
Vezmeme Text Hodnota (Jméno zaměstnance) první položky seznamu a vyhledejte jméno v tabulce.
-
Když je záznam nalezen, aktuální indexové číslo ListItem je aktualizováno (nahrazeno) v poli ID v tabulce.
-
Tento proces se opakoval pro všechny zbývající záznamy v tabulce.
Pojďme si projít kód VBA. Na začátku zkontrolujeme, zda byla zdrojová datová tabulka/dotaz načtena do ovládacího prvku ListView nebo ne?
Pokud strTable Proměnná není inicializována názvem Query, pak je ovládací prvek ListView prázdný. Pokud se jedná o tento případ, uživatel otevřel formulář a zavřel jej, aniž by vybral název dotazu, aby načetl data do ovládacího prvku ListView. Form_Unload Procedura události je v tomto okamžiku přerušena a zavře formulář.
Pokud ovládací prvek ListView obsahuje data, provede se další krok a otevře se dotaz na zdrojová data EmployeesQ k aktualizaci.
Dalším krokem je projít každou položku ListItem a aktualizovat číslo indexu v poli ID v záznamu Zaměstnanci.
Nejprve se aktuální indexové číslo řádku uloží do tmp Proměnná.
První název lvwList.ColumnHeader EmployeeName a jméno zaměstnance je převzato z ListItem.Text do výrazu v Kritériu řetězcová proměnná, jako Jméno zaměstnance ="Andrew Fuller".
kritéria rst.FindFirst příkaz prohledá tabulku zdrojových dat, aby našel záznam s daným názvem. Když je záznam nalezen, aktuální indexové číslo ListItem se aktualizuje v poli ID.
Tento proces se opakuje pro všechny řádky v ovládacím prvku ListView a po dokončení se formulář zavře.
Až příště načtete záznamy z tohoto dotazu do ovládacího prvku ListView, zobrazí se ve stejném pořadí, v jakém jste formulář zavřeli naposledy.
Poznámka:Dotaz se zde stal nezbytným pro třídění dat v poli ID a jejich zobrazení ve změněném pořadí v ovládacím prvku ListView.
Celá tato práce spočívala v uložení dat v posledním seřazeném pořadí, takže při příštím otevření formuláře budou data v ovládacím prvku ListView v tomto pořadí.
Metoda řazení jako v Průzkumníku Windows.
V Průzkumníku Windows můžete seřadit zobrazený seznam ve vzestupném nebo sestupném pořadí kliknutím na záhlaví libovolného sloupce. Záhlaví sloupce bude fungovat jako přepínací tlačítko. Opakovaná kliknutí na záhlaví sloupce seřadí data sloupce ve vzestupném/sestupném pořadí podle následujícího ListView1_ColumnClick() Postup události:
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
Poznámka: Řazení všech dat je pouze v režimu porovnání textu. Položky seznamu a ListSubItems Přidat() třetí parametr metody, zobrazená informace v ovládacím prvku ListView je Text typ. Datum a číselné hodnoty jsou považovány pouze za text.
Průzkumník Windows uloží do složky poslední seřazené pořadí položek. Když tuto složku znovu otevřeme, seznam se zobrazí v dřívějším pořadí.
Pomocí Form_Unload() Událostní procedura Tato funkce Průzkumníka Windows bude možná v tabulce Zaměstnanci. Když zavřete formulář po seřazení podle libovolného sloupce, bude tato indexovaná pořadí objednávek uložena v tabulce Zaměstnanci v poli ID. Dotaz EmployeesQ vždy při otevření třídí data v poli ID.
Demo databáze je připojena ke stažení. V databázi jsou dva ukázkové formuláře. První formulář ukazuje otevření tabulek a dotazů v ovládacím prvku ListView pro zobrazení dat v zobrazení datového listu. Druhý formulář používá pouze EmployeesQ Pouze dotaz na přetažení, přetažení, řazení a uložení posledního pořadí řazení dat pro budoucí použití.
- Výukový program pro ovládání ActiveX ListView-01.
- ListView Control Tutorial-02.
- Přiřazení obrázků k položkám ListView.
- Události řazení přetažením ovládacího prvku ListView
- Ovládání ListView pomocí MS-Access TreeView
- TreeView/ListView ovládá události přetažení