Ponowne rozmieszczenie wierszy danych w kontrolce ListView.
W poprzednim odcinku tego samouczka dowiedzieliśmy się, jak zmienić kolejność kolumn, włączając tę funkcję:AllowColumnReorder opcja w arkuszu właściwości. Ale przenoszenie wiersza odbywa się przez przeciągnięcie i umieszczenie go w innym wierszu. Aby zmienić kolejność wierszy kontrolnych ListView, akcja przeciągania i upuszczania ListItem wymaga włączenia tej funkcji w arkuszu właściwości. Ale to samo nie zadziała, potrzebuje kodu VBA, aby zmienić pozycję elementu w wymaganej kolejności.
Stwórzmy przykładowy formularz dostępu z kontrolkami i kodem VBA w naszej bazie danych do tego ćwiczenia. Przykładowy obraz formularza z kontrolkami ListBox i ListView znajduje się poniżej.
Stworzyliśmy listę tabel i zapytań (nie zapytań akcji) w polu listy. Wybranie jednego z elementów listy spowoduje natychmiastowe wyświetlenie rekordów w kontrolce ListView, tak jak widzimy je w widoku DataSheet.
Zadanie projektowe.
-
Utwórz nową tabelę z pojedynczym polem tekstowym o nazwie DataList .
-
Zapisz tabelę pod nazwą lvTables (lv oznacza ListView).
-
Otwórz tabelę w widoku arkusza danych.
-
Dodaj do tabeli kilka nazw tabel i wybierz nazwy zapytań z bazy danych. Zaimportowałem tabele z przykładowej bazy danych Northwind do mojej listy.
Uwaga: Załącznik Pole jest nieprawidłowe w kontrolce ListView. Utwórz Wybierz zapytania dla tabel z polem załącznika i wybierz wszystkie pola z wyjątkiem pola załącznika.
-
Utwórz i otwórz nowy formularz w widoku projektu.
-
Wstaw kontrolkę ListBox do formularza, wyświetl arkusz właściwości i zmień jego Nazwę wartość właściwości na List0 .
-
Zmień jego etykietę podrzędną Podpis wartość do Tabel .
-
Wyświetl arkusz właściwości kontrolki ListBox i ustaw Źródło wiersza wartość właściwości do lvTables imię.
-
Sprawdź, czy typ źródła wierszy jest ustawiony jako tabela/zapytanie, a wartość właściwości kolumny powiązanej wynosi 1. Jeśli jest inna, zmień.
-
Wstaw kontrolkę ListView z listy formantów ActiveX i zmień jej wartość właściwości Name na ListView1 .
-
Zmień rozmiar obu kontrolek, jak pokazano na powyższym obrazie formularza demonstracyjnego.
-
Wstaw etykietę nad kontrolkami i zmień jej wartości właściwości Nazwa i Podpis na Nagłówek. Wartość podpisu zostanie zmieniona z kodu vba po wybraniu tabeli lub zapytania z ListBox.
-
Utwórz przycisk polecenia pod kontrolkami i zmień jego wartość właściwości Nazwa na cmdClose a wartość właściwości Caption na Zamknij .
-
Kliknij prawym przyciskiem myszy kontrolkę ListView, podświetl Obiekt ListViewCtrl opcję i wybierz Właściwości .
-
Zmień ustawienia usługi, aby odpowiadały ustawieniom w Ogólnym Obraz karty podany poniżej.
-
Obraz arkusza właściwości kontrolki ListView — widok zakładki Ogólne jest podany poniżej:
Niektóre z tych opcji ustaliliśmy już we wcześniejszych sesjach. Tutaj potrzebujemy następujących opcji dla naszej akcji Drag Drop:
-
OLEDragAutomatic - 1
-
OLEDropPodręcznik - 1
-
FullRowSelect — prawda
-
HotTracking — prawda
-
Upewnij się, że powyższe ustawienia są zgodne z arkuszem właściwości, a następnie zapisz formularz.
Wyświetl moduł VBA formularza.
Kod VBA modułu formularza.
Skopiuj i wklej następujący kod VBA do modułu, zastępując istniejące linie kodu, jeśli takie istnieją:
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
Znasz powyższy kod VBA z wyjątkiem nowo dodanych podprogramów:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), i ListView1_ColumnClik() procedury. Pierwsze dwie procedury pomogą nam przeciągnąć element (wiersz) i upuścić go na inny element, aby wstawić go w nowe miejsce. Procedury Form_Unload() i ListView1_ColumnClick() będą sortować elementy.
Poniższe obrazy przedstawiają akcję „przeciągnij i upuść” w sekwencjach jej wykonywania
Pierwszy obraz poniżej przedstawia sekwencję czynności przeciągnij i upuść. Element ListItem o identyfikatorze EmployeeID 7 jest przeciągany przez użytkownika i upuszczany na element ListItem o identyfikatorze 3.
Drugi obraz przedstawia ruch elementu ListItem w odwrotnej kolejności.
Gdy wskaźnik myszy przesunie się nad wiersz z przeciągniętym elementem, między wierszami źródłowym i docelowym, podświetli się jeden po drugim w drodze w górę.
Akcja „przeciągnij i upuść” na zdjęciach.
Wiersz z identyfikatorem pracownika 7 jest upuszczany na element o powyższym identyfikatorze pracownika 3.Analiza segmentowa kodu VBA.
Po wybraniu elementu z ListBox procedura zdarzenia List0_Click() uruchamia się i ładuje rekordy do kontrolki ListView.
Private Sub List0_Click() Dim strTable As String strTable = List0.Value Call LoadListView(strTable) End Sub
Wybrana nazwa tabeli/zapytania jest zapisywana w strTable zmienna łańcuchowa. LoadListView() podprogram działa ze zmienną strTable jako parametrem. Przejrzeliśmy ten Kodeks więcej niż raz we wcześniejszych sesjach i możesz odwiedzić te Strony, korzystając z łączy podanych na dole tej strony, aby uzyskać szczegółowe informacje. Możesz znaleźć kilka drobnych zmian, które wprowadziłem w tym Kodeksie.
Nie używaliśmy kontrolki ImageList w tym odcinku Icon, SmallIcon Wartości parametrów w metodzie ListItems.Add() i ReportIcon, TooltipText wartości parametrów w metodzie ListSubItems.Add() również nie są używane.
Przyjrzyjmy się, co dzieje się w ListView1_OLEDragOver() i ListView1_OLEDragDrop() Segmenty kodu 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
Ta procedura jest wykonywana automatycznie, gdy próbujesz kliknąć i przytrzymać wiersz, zacząć przeciągać i przesuwać inne wiersze w drodze do wiersza docelowego. Akcja przeciągania przesuwa się po innym wierszu, który zostanie podświetlony.
ListView1.HitTest(x, y) funkcja odczytuje współrzędne x, y, które określają pozycję wiersza w kontrolce ListView i podświetla ten wiersz. Ten proces jest kontynuowany, gdy jesteś nad innymi rzędami, dopóki nie upuścisz go w wierszu docelowym, zwalniając przycisk myszy. Akcja upuszczania uruchamia ListView1_OLEDragDrop() procedura i wykonuje zmiany w wierszu źródłowym przez procedury.
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
Przyjrzyjmy się tej procedurze krok po kroku i zrozum, co się tam dzieje. Poniższy segment kodu deklaruje niezbędne zmienne obiektowe do obsługi akcji przeciągnij i upuść:
'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
Pierwsze trzy tymczasowe obiekty ListItem deklarują różne nazwy.
lvwDrag Obiekt ListItem będzie przechowywać kopię wiersza, który wybieramy do przeciągnięcia do nowej lokalizacji.
lvwDrop Obiekt ListItem zapisze odniesienie do wiersza, na który upuszczamy przeciągnięty element listy.
Podczas zmiany akcji ListItems usuniemy element Source z jego oryginalnej lokalizacji, a następnie utworzymy go w lokalizacji docelowej, z numerem indeksu elementu ListItem. Referencje tego nowego elementu ListItem są zapisywane w lvwTarget Zmienna obiektu ListItem.
lvwSub Zmienna zadeklarowana jako zmienna obiektu sekwencjonowania w For . . .Dalej Pętla. Ta pętla wymaga przechodzenia kolejno przez ListSubItems (od drugiej kolumny) jeden po drugim, z obiektu lvwDrag. Mimo że usunęliśmy oryginalny ListItem, zapisaliśmy jego kopię w obiekcie lvwDrag ListItem.
Numer indeksu lvwDrop ListItem jest zapisywany w intTgtIndex Zmienna.
lvwList.HitTest(x, y) Funkcja odczytuje współrzędne x, y kontrolki ListView i identyfikuje docelowy element ListItem, w którym upuściłem element źródłowy ListItem i tworzy jego kopię w obiekcie lvwDrop.
Najpierw wybierzemy element ListItem, zanim przeciągniemy go do nowej pozycji.
lvwList.SelectedItem Właściwość zostanie ustawiona jako True. Za pomocą tego statusu właściwości tworzymy kopię wybranego elementu ListItem w lvwDrag Obiekt ListItem. Następny segment kodu sprawdza poprawność zarówno obiektów źródłowych, jak i docelowych obiektów ListItem.
Kontrole walidacji w akcji „przeciągnij i upuść”.
'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
Powyższy segment kodu sprawdza poprawność działania przeciągania i upuszczania. Jeśli te działania nie rozpoczęły się lub nie zakończyły na prawidłowym elemencie, obiekty lvwDrop lub lvwDrag lub oba z nich będą puste. Lub inny nieprawidłowy ruch może się zdarzyć, gdy użytkownik przesuwa wiersz w górę lub w dół, ale może zmienić zdanie i upuścić go z powrotem w tym samym wierszu. Wykrycie tego rodzaju błędnych ruchów spowoduje zakończenie programu.
Jeśli powyższy test okaże się prawidłowy, program będzie kontynuował wykonywanie następnej procedury, aby zmienić kolejność wierszy.
'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
Powyższe dziewięć linii kodu wykonywalnego (inne linie to komentarze) są dość proste.
intTgtIndex =lvwDrop.Index instrukcja zapisuje numer indeksu docelowego ListItem w intTgtIndex Zmienna.
Ponieważ już zapisaliśmy Source Row listItem w tymczasowym obiekcie lvwDrag, następnym krokiem jest usunięcie źródłowego ListItem z kontrolki ListView. Procedura ListItems.Remove() jest wywoływana z instrukcją lvwList.ListItems.Remove lvwDrag.Index .
W skrócie, działanie Drag Drop polega na usunięciu elementu ListItem z jego oryginalnej lokalizacji i ponownemu utworzeniu go w lokalizacji docelowej z docelowym numerem indeksu wiersza.
Instrukcja Set lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) tworzy nowy ListItem z numerem indeksu lokalizacji docelowej intTgtIndex i Tekst wartość elementu Source ListItem zapisanego wcześniej w obiekcie lvwDrag.
Tworząc ListItem po raz pierwszy, użyliśmy tylko tych dwóch wartości, indeksu i Tekst wartości parametrów. Nie używaliśmy innych opcji parametrów Klucz, Ikona i SmallIcon w przeciwnym razie musimy uwzględnić te wartości parametrów również z obiektu lvwDrag.
Zgodnie z naszym przykładem Przeciągnij i upuść Obrazy pokazane powyżej przenieśliśmy 7. ListItem i upuśćmy go na 3. ListItem. Następnie usunęliśmy 7. element (lub źródłowy element ListItem) z kontrolki ListView. Utworzono nowy element ListItem z docelowym numerem indeksu 3.
Teraz sądwa elementy o tym samym numerze indeksu 3, istniejący już o numerze indeksu 3 i nowy, który stworzyliśmy z numerem indeksu 3. Wszystkie inne informacje są pobierane z obiektu lvwDrag (lub 7. ListItem zapisanego w lvwDrag Obiekt wcześniej).
System automatycznie zwiększa istniejącą ListItem 3 do kolejnych numerów sekwencji 3,4,5 . . . do 4,5,6 . . . i przesuwa je do przodu, aby zrobić miejsce na przychodzący element do wstawienia pomiędzy.
Wpływ usunięcia wiersza i utworzenia go w innym miejscu.
Załóżmy, że wykonujemy ten ruch w odwrotnej kolejności, na przykład przeciągnij ListItem numer 3 z góry i upuść go na element numer 7, co się stanie?
Oczywiście usuniemy trzecią pozycję i spróbujemy utworzyć nową pozycję z indeksem 7 w nowej lokalizacji. Po usunięciu pozycji numer 3 pozycja numer 4 w górę zostanie przesunięta w górę lub 4,5,6,7,8,9 zmieni się w 3,4,5,6,7,8 (aby ułożyć wszystkie pozycje w kolejności) lub wcześniej pozycja z indeksem 7 zmieni się na 6.
Kiedy utworzymy nowy element o indeksie 7, dotychczasowe 7,8 zmieni się ponownie na 8,9. Kiedy obserwujemy ruch wierszy podczas usuwania wiersza i czasu tworzenia, pierwszy przykład przesunie wiersz docelowy w dół, aby zrobić miejsce dla przychodzącego elementu. W drugim wyjaśnionym przykładzie (przesuwając się od 3 do 7) wiersz docelowy przesunie się w górę.
Uwaga: Obejrzyj twartość identyfikatora pracownika do umieszczenia go jako wskazówki do przesuwania elementu ListItem w dół lub w górę, gdy zmieniamy kolejność elementu ListItem.
Wspomniałem o ListItem wszędzie w operacjach przeciągania i upuszczania. ListItem odwołuje się tylko do pierwszej kolumny wiersza ListView. Inne wartości kolumn to ListSubItems lub elementy podrzędne elementu ListItem. Oznacza to, że będziesz mógł przeciągać i upuszczać tylko pierwszą kolumnę. Inne kolumny lub ListSubItems zostaną przeniesione pod ListItem z kodem VBA.
Dzieje się tak, jeśli nie włączono FullRowSelection w arkuszu właściwości kontrolki ListView w sekcji Ogólne Tab.
Jeśli ta opcja jest włączona, możesz wybrać dowolną kolumnę, ale system odnosi się do indeksu ListItem w celu zmiany kolejności wierszy. Porównaj powyższe dwa obrazy z innym zestawem dwóch przykładowych obrazów, trzecim i czwartym obrazem u góry tej strony.
Akcja przeciągania i upuszczania nie będzie działać, jeśli następujące dwie wartości właściwości nie są ustawione w arkuszu właściwości kontrolki ListView w sekcji Ogólne Tab.:
- ccOLEDragAutomatic =1
- ccOLEDropPodręcznik =1
Następne pięć stwierdzeń przeniesie ListSubItems, jeśli istnieje, do nowo utworzonego elementu ListItem w nowej lokalizacji.
Następnie nowo utworzony element ListItem jest podświetlony.
Następnie wszystkie utworzone obiekty tymczasowe są usuwane z pamięci.
Uwaga: Innym ważnym punktem, na który należy zwrócić uwagę, jest to, że ten układ jest tymczasowy i jest tracony po zamknięciu formularza lub załadowaniu innej tabeli/zapytania w kontrolce ListView.
Jeśli chcemy, aby zmieniona kolejność ListItems pozostała stała lub do czasu następnej zmiany kolejności, musimy mieć możliwość zaktualizowania bieżącego numeru indeksowanego zamówienia w samej tabeli. Dodaliśmy nowe pole Integer z identyfikatorem nazwy pola w tabeli Pracownicy.
Przykładowy ekran z danymi pracowników uporządkowanymi w kolejności alfabetycznej znajduje się poniżej:
Ponieważ pole Identyfikator pracownika jest polem Autonumerowanie i jest połączone z innymi powiązanymi tabelami, dodaliśmy nowe pole liczbowe z identyfikatorem nazwy pola. Ta wartość pola jest początkowo ustawiana ręcznie za pomocą tych samych numerów sekwencyjnych z identyfikatora pracownika. Ta wartość pola będzie początkowo w tej kolejności. Jednak dane wierszy ListView mogą zmienić swoją kolejność, gdy zmienisz rozmieszczenie danych w kontrolce ListView z powodu działania przeciągnij i upuść.
Spójrz na Pracownicy Zapytanie SQL podane poniżej:
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;
Powyższe zapytanie jest używane jako źródło danych dla kontrolki ListView i są one sortowane według pola ID. Pole ID jest aktualizowane ze zmienioną kolejnością numerów indeksów w kontrolce ListView. Proces aktualizacji jest uruchamiany z Form_Unload() Procedura zdarzenia po zamknięciu formularza. Ta metoda zapewnia, że przy następnym otwarciu kontrolki ListView dane będą w kolejności, w jakiej zmieniono kolejność ostatnim razem.
Form_Unload() Kod VBA procedury zdarzenia.
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
Sprawdź Nazwa pracownika Wartość pola na powyższym obrazku. Są one ułożone w porządku alfabetycznym. Nowa wartość pola identyfikatora w tabeli Pracownicy zostanie zaktualizowana o aktualną sekwencję numerów indeksu ListView Control ListItem.
Jeśli zwrócisz uwagę na następujące punkty, możesz łatwo zrozumieć, co robimy z powyższym kodem:
-
Tekst elementu ListItem (pierwsza kolumna) wartość parametru to nazwisko pracownika i ułożone w kolejności alfabetycznej.
-
Element ListItem w kontrolce ListView ma numery indeksu od 1 do 9 w kolejności, w jakiej jest wyświetlany na ekranie, tj. numer indeksu pierwszego elementu to 1, a ostatni to 9. Oryginalne dane w wartości pola Identyfikator tabeli pracowników nie są w tej kolejności.
-
Bierzemy Tekst Wartość (nazwisko pracownika) pierwszego elementu ListItem i wyszukaj nazwę w tabeli.
-
Po znalezieniu rekordu bieżący numer indeksu elementu ListItem jest aktualizowany (zamieniany) w polu identyfikatora w tabeli.
-
Ten proces został powtórzony dla wszystkich pozostałych rekordów w tabeli.
Przejdźmy przez kod VBA. Na początku sprawdzamy, czy tabela/kwerenda danych źródłowych została załadowana do kontrolki ListView, czy nie?
Jeśli strTable Zmienna nie jest inicjowana nazwą zapytania, wtedy kontrolka ListView jest pusta. W takim przypadku użytkownik otworzył formularz i zamknął go bez wybierania nazwy zapytania, aby załadować dane do kontrolki ListView. Form_Unload Procedura zdarzenia jest przerywana w tym momencie i zamyka formularz.
Jeśli kontrolka ListView zawiera dane, wykonywany jest następny krok i otwierane jest zapytanie o dane źródłowe EmployeesQ do aktualizacji.
Następnym krokiem jest przejrzenie każdego elementu listy i zaktualizowanie numeru indeksu w polu identyfikatora rekordu pracowników.
Najpierw bieżący numer indeksu wiersza jest zapisywany w tmp Zmienna.
Pierwsza nazwa lvwList.ColumnHeader EmployeeName oraz imię i nazwisko pracownika pochodzi z ListItem.Text na wyrażenie w Kryteriach zmienna łańcuchowa, np. EmployeeName ="Andrew Fuller".
Kryteria pierwsze.FindFirst polecenie przeszukuje tabelę danych źródłowych w celu znalezienia rekordu o podanej nazwie. Po znalezieniu rekordu aktualny numer indeksu elementu ListItem jest aktualizowany w polu identyfikatora.
Ten proces jest powtarzany dla wszystkich wierszy w kontrolce ListView, a po zakończeniu formularz jest zamykany.
Następnym razem, gdy załadujesz rekordy z tego zapytania do kontrolki ListView, zostaną one wyświetlone w tej samej kolejności, w jakiej ostatnio zamykałeś formularz.
Uwaga: Zapytanie stało się tutaj konieczne do posortowania danych w polu ID i wyświetlenia ich w zmienionej kolejności w kontrolce ListView.
Cała ta praca polegała na zapisaniu danych w ostatniej kolejności sortowania, aby następnym razem, gdy otworzysz formularz, dane w kontrolce ListView będą w tej kolejności.
Eksplorator Windows jak metoda sortowania.
W Eksploratorze Windows można posortować wyświetlaną listę w kolejności rosnącej lub malejącej, klikając dowolny nagłówek kolumny. Nagłówek kolumny będzie działał jak przycisk przełączania. Powtarzające się kliknięcia nagłówka kolumny posortują dane kolumny w kolejności rosnącej/malejącej według następującej ListView1_ColumnClick() Procedura wydarzenia:
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
Uwaga: Sortowanie wszystkich danych odbywa się tylko w trybie porównywania tekstu. ListItems i ListSubItems Dodaj() trzeci parametr metody, wyświetlane informacje w kontrolce ListView to Tekst rodzaj. Data i wartości liczbowe są traktowane jako tylko tekst.
Eksplorator Windows zapisuje ostatnią posortowaną kolejność elementów w folderze. Gdy ponownie otworzymy ten folder, lista zostanie wyświetlona we wcześniej posortowanej kolejności.
Za pomocą Form_Unload() Procedura zdarzenia ta funkcja Eksploratora Windows staje się dostępna w tabeli pracowników. Po zamknięciu Formularza po posortowaniu według dowolnej kolumny, zindeksowana kolejność zleceń zostanie zapisana w tabeli Pracownicy w polu ID. Zapytanie EmployeesQ zawsze sortuje dane w polu ID po otwarciu.
Baza danych Demo jest dołączona do pobrania. W Bazie danych znajdują się dwa formularze demonstracyjne. Pierwszy formularz demonstruje otwieranie tabel i zapytań w kontrolce ListView, aby wyświetlić dane w widoku arkusza danych. Drugi formularz używa tylko Pracowników Samo zapytanie do przeciągania, upuszczania, sortowania i zapisywania danych w ostatniej kolejności sortowania do wykorzystania w przyszłości.
- Samouczek 01 kontroli ActiveX ListView.
- Samouczek sterowania ListView-02.
- Przypisywanie obrazów do elementów ListView.
- Kontrola ListView sortowania zdarzeń przeciągania i upuszczania
- Kontrola ListView z MS-Access TreeView
- TreeView/ListView steruje zdarzeniami przeciągania i upuszczania