Access
 sql >> Baza danych >  >> RDS >> Access

ListView Control Przeciągnij i upuść zdarzenia sortowania

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.

  1. Utwórz nową tabelę z pojedynczym polem tekstowym o nazwie DataList .

  2. Zapisz tabelę pod nazwą lvTables (lv oznacza ListView).

  3. Otwórz tabelę w widoku arkusza danych.

  4. 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.

  5. Utwórz i otwórz nowy formularz w widoku projektu.

  6. Wstaw kontrolkę ListBox do formularza, wyświetl arkusz właściwości i zmień jego Nazwę wartość właściwości na List0 .

  7. Zmień jego etykietę podrzędną Podpis wartość do Tabel .

  8. Wyświetl arkusz właściwości kontrolki ListBox i ustaw Źródło wiersza wartość właściwości do lvTables imię.

  9. 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ń.

  10. Wstaw kontrolkę ListView z listy formantów ActiveX i zmień jej wartość właściwości Name na ListView1 .

  11. Zmień rozmiar obu kontrolek, jak pokazano na powyższym obrazie formularza demonstracyjnego.

  12. 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.

  13. 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 .

  14. Kliknij prawym przyciskiem myszy kontrolkę ListView, podświetl Obiekt ListViewCtrl opcję i wybierz Właściwości .

  15. Zmień ustawienia usługi, aby odpowiadały ustawieniom w Ogólnym Obraz karty podany poniżej.

  16. 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:

  1. Tekst elementu ListItem (pierwsza kolumna) wartość parametru to nazwisko pracownika i ułożone w kolejności alfabetycznej.

  2. 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.

  3. Bierzemy Tekst Wartość (nazwisko pracownika) pierwszego elementu ListItem i wyszukaj nazwę w tabeli.

  4. Po znalezieniu rekordu bieżący numer indeksu elementu ListItem jest aktualizowany (zamieniany) w polu identyfikatora w tabeli.

  5. 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.



  1. Samouczek 01 kontroli ActiveX ListView.
  2. Samouczek sterowania ListView-02.
  3. Przypisywanie obrazów do elementów ListView.
  4. Kontrola ListView sortowania zdarzeń przeciągania i upuszczania
  5. Kontrola ListView z MS-Access TreeView
  6. TreeView/ListView steruje zdarzeniami przeciągania i upuszczania

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dostęp 2021 dla manekinów Ściągawka

  2. Projektowanie wyzwalacza Microsoft T-SQL

  3. Tworzenie menu dostępu z kontrolą widoku drzewa

  4. 5 rzeczy, które należy wiedzieć o „Windows 10 S”

  5. Jak ustanowić indeksy tabel w bazach danych