sql >> Database teknologi >  >> RDS >> Access

ListView Kontrol Træk-Drop Sorter begivenheder

Omarrangering af datarækker i ListView Control.

I den tidligere episode af denne vejledning har vi lært, hvordan man omarrangerer kolonnerne ved at aktivere denne funktion:AllowColumnReorder mulighed på ejendomsarket. Men flytning af en række udføres ved at trække og placere den på en anden række. For at omarrangere ListView-kontrolrækkerne kræver ListItem Drag and Drop-handlingen, at denne funktion aktiveres på egenskabsarket. Men dette alene vil ikke fungere, kræver VBA-kode for at omarrangere varen til dens påkrævede rækkefølge.

Lad os oprette en prøveadgangsformular med kontroller og VBA-kode i vores database til denne øvelse. Eksempelbilledet af formularen med ListBox og ListView Controls er givet nedenfor.

Vi har oprettet en liste over tabeller og forespørgsler (ikke handlingsforespørgsler) i listeboksen. Hvis du vælger et af listeelementerne, vises registreringerne øjeblikkeligt på ListView-kontrollen, som vi ser dem i dataarkvisningen.

Designopgaven.

  1. Opret en ny tabel med et enkelt tekstfelt med feltnavnet DataList .

  2. Gem tabellen med navnet lvTables (lv står for ListView).

  3. Åbn tabellen i dataarkvisning.

  4. Tilføj et par tabelnavne, og vælg forespørgselsnavne fra din database til tabellen. Jeg har importeret tabeller fra Northwind-eksempeldatabasen til min liste.

    Bemærk: Den vedhæftede fil Feltet er ikke gyldigt i ListView Control. Opret Select Queries for tabeller med vedhæftede felter, og vælg alle felter undtagen Vedhæftet felt.

  5. Opret og åbn en ny formular i designvisning.

  6. Indsæt en ListBox-kontrol på formularen, vis egenskabsarket og skift dets navn egenskabsværdi til Liste0 .

  7. Skift dens underordnede etiket Billedtekst værdi til tabeller .

  8. Vis egenskabsarket for ListBox-kontrol, og indstil Rækkekilde egenskabsværdi til lvTables navn.

  9. Kontroller, om rækkekildetypen er indstillet som tabel/forespørgsel, og værdien for bundet kolonneegenskab er 1. Skift, hvis det er anderledes.

  10. Indsæt en ListView-kontrol fra ActiveX-kontrollisten, og skift dens navnegenskabsværdi til ListView1 .

  11. Tilpas størrelsen på begge kontroller som vist på demoformularbilledet ovenfor.

  12. Indsæt en etiket over kontrolelementerne og skift dens navn og billedtekstegenskabsværdier til Overskrift. Billedtekstværdien vil blive ændret fra vba-kode, når en tabel eller forespørgsel er valgt fra ListBox.

  13. Opret en kommandoknap under kontrolelementerne, og skift dens navnegenskabsværdi til cmdClose og billedtekstegenskabsværdien for at Luk .

  14. Højreklik på ListView Control, fremhæv ListViewCtrl-objektet og vælg Egenskaber .

  15. Skift egenskabsindstillingerne, så de stemmer overens med indstillingerne i Generelt Fanebillede vist nedenfor.

  16. ListView Kontrolejendomsarkbillede - Generel fanevisning er vist nedenfor:

    Nogle af disse muligheder har vi allerede sat i de tidligere sessioner. Her har vi brug for følgende muligheder for vores Drag Drop-handling:

    • OLEDragAutomatic - 1

    • OLEDropManual - 1

    • FullRowSelect - Sand

    • HotTracking - Sandt

Sørg for, at ovenstående indstillinger stemmer overens med dit ejendomsark, og gem derefter formularen.

Vis formularens VBA-modul.

Formmodulets VBA-kode.

Kopiér og indsæt følgende VBA-kode i modulet, og overskriv de eksisterende kodelinjer, hvis nogen:

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

Du er bekendt med ovenstående VBA-kode undtagen de nyligt tilføjede underrutiner:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), og ListView1_ColumnClik() procedurer. De første to procedurer hjælper os med at trække et element (række) og slippe det over et andet element for at indsætte det på en ny placering. Procedurerne Form_Unload() og ListView1_ColumnClick() vil sortere elementerne.

Følgende billeder viser træk og slip-handlingen i rækkefølge af dens udførelse

Det første billede nedenfor viser træk og slip handlingssekvensen. ListItem, med EmployeeID 7, trækkes op af brugeren og falder over ListItem med ID 3.

Det andet billede viser flytningen af ​​ListItem i omvendt rækkefølge.

Når musemarkøren bevæger sig hen over en række med det slæbte element, mellem kilde- og målrækkerne, fremhæves den ene efter den anden på vej op.

Træk og slip-handlingen i billeder.

Rækken med medarbejder-id 7 er slettet på elementet med medarbejder-id 3 ovenfor.

VBA-koden segmentmæssig analyse.

Et elementvalg fra ListBox, List0_Click() hændelsesproceduren kører og indlæser posterne i ListView Control.

Private Sub List0_Click()
Dim strTable As String

strTable = List0.Value

  Call LoadListView(strTable)

End Sub

Det valgte tabel-/forespørgselsnavn gemmes i strTabel strengvariabel. LoadListView() subrutine kører med strTable-variablen som parameter. Vi har gennemgået denne kode mere end én gang i tidligere sessioner, og du kan besøge disse sider ved at bruge linkene nederst på denne side for detaljer. Du kan finde et par mindre ændringer, jeg har foretaget i denne kode.

Vi har ikke brugt ImageList Control i denne episode Icon, SmallIcon Parameterværdier i ListItems.Add()-metoden og ReportIcon, TooltipText parameterværdier i ListSubItems.Add()-metoden bruges heller ikke.

Lad os se på, hvad der sker i ListView1_OLEDragOver() og ListView1_OLEDragDrop() VBA-kodesegmenter.

ListView1_OLEDragOver()-proceduren.

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 

Denne procedure udføres automatisk, når du forsøger at klikke og holde på en række, begynder at trække og flytte over andre rækker på vej mod målrækken. Trækhandlingen flytter over en anden række, den bliver fremhævet.

ListView1.HitTest(x, y) funktionen læser x, y koordinaterne, der bestemmer rækkepositionen på ListView Control og fremhæver denne række. Denne proces fortsætter, når du er over andre rækker, indtil du slipper den på målrækken ved at slippe museknappen. Drop-handlingen udløser ListView1_OLEDragDrop() procedure og udfører kilderækkens ændringsprocedurer.

ListView1_OLEDragDrop-proceduren.

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

Lad os gennemgå denne procedure del for del og forstå, hvad der sker der. Følgende kodesegment erklærer de nødvendige objektvariabler til at håndtere træk og slip-handlingen:

'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

De første tre ListItem midlertidige objekter erklærer med forskellige navne.

lvwDrag ListItem-objektet vil indeholde kopien af ​​den række, vi vælger at trække til en ny placering.

lvwDrop ListItem Object vil gemme referencen for rækken, hvor vi slipper det trukket listeelement.

Under ændringen af ​​ListItems-handlingen sletter vi kildeelementet fra dets oprindelige placering og opretter det derefter på målplaceringen med kildelistens indeksnummer. Referencerne til dette nye ListItem gemmer i lvwTarget ListItem objektvariabel.

lvwSub Variabel erklæret som en sekventeringsobjektvariabel i For . . .Næste Løkke. Denne looping kræver sekvens gennem ListSubItems, (2. kolonne og fremefter) én efter én, fra lvwDrag-objektet. Selvom vi har slettet det originale ListItem, har vi gemt en kopi af det i lvwDrag ListItem-objektet.

lvwDrop ListItem Index-nummeret er gemt i intTgtIndex Variabel.

lvwList.HitTest(x, y) Funktionen læser x, y koordinaterne for ListView Control og identificerer mål ListItem, hvor vi har droppet kilden ListItem og laver en kopi af det i lvwDrop Object.

Vi vælger først et listeelement, før vi trækker det til den nye position.

lvwList.SelectedItem Egenskaben vil blive angivet som Sand. Ved hjælp af denne ejendomsstatus laver vi en kopi af det valgte ListItem til lvwDrag ListItem Objekt. Det næste kodesegment validerer både Kilde- og Target ListItem-objekter.

Valideringstjek på træk-slip-handlingen.

'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

Ovenstående kodesegment validerer træk og slip-handlingen. Hvis disse handlinger ikke startede eller sluttede på et gyldigt element, vil lvwDrop- eller lvwDrag-objekterne eller begge være tomme. Eller et andet ugyldigt træk kan ske, når brugeren flytter en række op eller ned, men kan ændre mening og slippe den tilbage på den samme række. Detektering af denne slags forkerte træk vil afslutte programmet.

Hvis ovenstående test viser sig at være gyldig, vil programmet fortsætte med at udføre den næste procedure for at omarrangere rækkerne.

'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

Ovenstående ni linjer med eksekverbar kode (andre linjer er kommentarer) er noget ligetil.

intTgtIndex =lvwDrop.Index sætningen gemmer mållisteelementets indeksnummer i intTgtIndex Variabel.

Da vi allerede har gemt Source Row listItem i det midlertidige Object lvwDrag, er næste trin at fjerne kilden ListItem fra ListView Control. ListItems.Remove()-proceduren kaldes med sætningen lvwList.ListItems.Remove lvwDrag.Index .

Kort sagt går Drag Drop-handlingen ud på at slette en ListItem fra dens oprindelige placering og oprette den igen på målplaceringen med målrækkens indeksnummer.

Udsagnet Set lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) opretter det nye ListItem med dets målplaceringsindeksnummer intTgtIndex og Tekst værdi af kildelisteelement gemt i lvwDrag-objektet tidligere.

Da vi oprettede ListItem for første gang, har vi kun brugt disse to værdier, indekset og Tekst parameterværdier. Vi har ikke brugt de andre parameterindstillinger Nøgle, ikon, og SmallIcon ellers skal vi inkludere disse parameterværdier også fra lvwDrag-objektet.

I henhold til vores Drag Drop-eksempelbilleder vist ovenfor har vi flyttet det 7. listeelement og droppet det på det 3. listeelement. Derefter har vi slettet det 7. element (eller kilde ListItem) fra ListView Control. Oprettet en ny ListItem med målindeksnummer 3.

Nu er der to elementer med det samme indeksnummer 3, det eksisterende med indeksnummer 3 og det nye, vi har oprettet med indeksnummer 3. Al anden information er taget fra lvwDrag-objektet (eller det 7. ListItem gemt i lvwDrag Objekt tidligere).

Systemet inkrementerer automatisk det eksisterende ListItem 3 og frem til de næste sekvensnumre 3,4,5. . . til 4,5,6. . . og flytter dem fremad for at give plads til, at den indgående vare kan indsættes imellem.

Konsekvensen af ​​at slette en række og oprette den et andet sted.

Antag, at vi foretager det træk i omvendt rækkefølge, som at trække ListItem nummer 3 fra oven og slippe det på punkt nummer 7, hvad sker der så?

Vi sletter naturligvis den 3. vare og vil forsøge at oprette en ny vare med indeksnummer 7 på den nye placering. Når varenummer 3 slettes, vil varenummer 4 og fremefter skifte op, eller 4,5,6,7,8,9 bliver til 3,4,5,6,7,8 (for at gøre alle elementerne i rækkefølge) eller den tidligere vare med indeksnummer 7 bliver 6.

Når vi opretter den nye vare med indeksnummer 7, bliver den eksisterende 7,8 8,9 igen. Når vi ser bevægelsen af ​​rækker, mens rækkesletningen og oprettelsestidspunktet, vil det første eksempel flytte målrækken ned for at gøre plads til det indgående element. I det andet forklarede eksempel (flytter 3 til 7) flyttes destinationsrækken op.

Bemærk: Se tMedarbejder-id-værdien for dens placering som et fingerpeg om, at ListItem flytter sig ned eller rykker op, når vi omarrangerer ListItem.

Jeg har nævnt ListItem overalt i træk-slip-operationer. ListItem henviser kun til den første kolonne i ListView-rækken. Andre kolonneværdier er ListSubItems eller underordnede elementer til ListItem. Det betyder, at du kun vil være i stand til at trække og slippe den første kolonne. Andre kolonner eller ListSubItems vil blive flyttet under ListItem med VBA-kode.

Dette er sandt, hvis du ikke har aktiveret FullRowSelection på ListView Control Property Sheet på Generelt Tab.

Hvis den er aktiveret, kan du vælge en hvilken som helst kolonne, men systemet henviser til ListItem Index for rækkers genbestillingsformål. Sammenlign de to ovenstående billeder med et andet sæt af to eksempelbilleder, det tredje og det fjerde billede fra toppen af ​​denne side.

Træk og slip-handlingen virker ikke, hvis følgende to egenskabsværdier ikke er angivet på ListView Control Property Sheet på Generelt Tab.:

  • ccOLEDragAutomatic =1
  • ccOLEDropManual =1

De næste fem udsagn flytter ListSubItems, hvis nogen, til det nyoprettede listeelement på den nye placering.

Dernæst fremhæves det nyoprettede ListItem.

Derefter ryddes alle oprettede midlertidige objekter fra hukommelsen.

Bemærk: Et andet vigtigt punkt at bemærke her er, at dette arrangement er midlertidigt og går tabt, når du lukker formularen eller indlæser en anden tabel/forespørgsel på ListView-kontrollen.

Hvis vi ønsker, at den ændrede rækkefølge af ListItems forbliver permanent, eller indtil rækkefølgen ændres næste gang, så skal vi kunne opdatere det aktuelle indekserede ordrenummer på selve bordet. Vi har tilføjet et nyt heltalsfelt med feltnavn-id'et på medarbejdertabellen.

Eksempelskærmbilledet med medarbejderdata omarrangeret i alfabetisk rækkefølge er vist nedenfor:

Da feltet Employees ID er et AutoNumber-felt og forbundet med andre relaterede tabeller, har vi tilføjet et nyt Number Field med feltnavnet ID. Denne feltværdi indstilles til at begynde med med de samme sekvensnumre fra medarbejder-id'et manuelt. Denne feltværdi vil i første omgang være i denne rækkefølge. Men ListView Rows-dataene kan ændre deres rækkefølge, når du omarrangerer dataene på ListView-kontrollen på grund af træk og slip-handling.

Se på MedarbejdereQ Forespørgsel SQL angivet nedenfor:

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;

Ovenstående forespørgsel bruges som datakilde for ListView-kontrollen, og de er sorteret i ID-feltet. ID-feltet opdateres med den ændrede rækkefølge af indeksnumre på ListView Control. Opdateringsprocessen kører fra Form_Unload() Begivenhedsprocedure, når du lukker formularen. Denne metode sikrer, at når du åbner ListView Control næste gang, vil dataene være i den rækkefølge, du genbestilte sidste gang.

Form_Unload() Hændelsesprocedure VBA-kode.

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

Tjek Medarbejdernavn Feltværdi i billedet ovenfor. De er arrangeret i alfabetisk rækkefølge. Den nye ID-feltværdi på medarbejdertabellen vil blive opdateret med deres aktuelle ListView Control ListItem indeksnummersekvens.

Hvis du noterer dig følgende punkter, kan du nemt forstå, hvad vi gør med ovenstående kode:

  1. Listeelementets (første kolonne) tekst parameterværdi er medarbejdernavnet og arrangeret i alfabetisk rækkefølge.

  2. ListItems på ListView Control har indeksnumre fra 1 til 9 i den rækkefølge, de vises på skærmen, dvs. den første vares indeksnummer er 1 og den sidste er 9. De originale data i feltet Medarbejdertabel ID er ikke i denne rækkefølge.

  3. Vi tager teksten Værdi (medarbejdernavn) for det første listeelement, og søg efter navnet på bordet.

  4. Når posten er fundet, opdateres (erstattes) den aktuelle ListItems indeksnummer i ID-feltet på tabellen.

  5. Denne proces blev gentaget for alle de resterende poster på bordet.

Lad os gennemgå VBA-koden. I begyndelsen tjekker vi, om kildedatatabellen/forespørgslen blev indlæst i ListView-kontrollen eller ej?

Hvis strTable Variablen er ikke initialiseret med forespørgselsnavnet, så er ListView-kontrollen tom. Hvis dette er tilfældet, åbnede brugeren formularen og lukkede den uden at vælge forespørgselsnavnet for at indlæse dataene i ListView-kontrollen. Form_Unload Hændelsesproceduren afbrydes på dette tidspunkt og lukker formularen.

Hvis ListView-kontrollen har data, udføres det næste trin og åbner kildedataforespørgslen EmployeesQ for at opdatere.

Det næste trin er at gennemgå hvert listeelement og opdatere indeksnummeret i ID-feltet i medarbejderposten.

Først gemmes det aktuelle rækkeindeksnummer i tmp Variabel.

Det første lvwList.ColumnHeader navn EmployeeName og medarbejderens navn er taget fra ListItem.Text til et udtryk i Kriterier strengvariabel, såsom EmployeeName ="Andrew Fuller".

rst.FindFirst-kriterierne kommandoen søger i kildedatatabellen for at finde posten med det angivne navn. Når posten er fundet, opdateres det aktuelle ListItem Index nummer i ID-feltet.

Denne proces gentages for alle rækkerne på ListView Control, og når den er færdig, lukkes formularen.

Næste gang du indlæser posterne fra denne forespørgsel i ListView Control, vil de blive vist i samme rækkefølge, da du lukkede formularen sidste gang.

Bemærk:Forespørgslen blev nødvendig her for at sortere dataene i ID-feltet og vise dem i den ændrede rækkefølge på ListView Control.

Alt dette arbejde var for at gemme dataene i den sidst sorterede rækkefølge, så næste gang du åbner formularen, vil dataene på ListView Control være i den rækkefølge.

Windows Stifinder som sorteringsmetode.

I Windows Stifinder kan du sortere den viste liste i stigende eller faldende rækkefølge ved at klikke på en hvilken som helst kolonneoverskrift. Kolonneoverskriften fungerer som en skifteknap. Gentagne klik på kolonneoverskriften vil sortere kolonnedataene i stigende/faldende rækkefølge efter følgende ListView1_ColumnClick() Begivenhedsprocedure:

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

Bemærk: Sorteringen af ​​alle data er kun i tekstsammenligningstilstand. ListItems og ListSubItems Tilføj() metodes tredje parameter, den viste information på ListView Control er Tekst type. Dato og numeriske værdier behandles alle kun som tekst.

Windows Stifinder gemmer den sidst sorterede rækkefølge af elementer i mappen. Når vi åbner den mappe igen, vil listen blive vist i den tidligere sorterede rækkefølge.

Med Form_Unload() Hændelsesprocedure denne funktion i Windows Stifinder bliver mulig på medarbejdertabellen. Når du lukker formularen efter sortering i en hvilken som helst kolonne, vil den indekserede ordresekvens blive gemt i medarbejdertabellen i ID-feltet. EmployeesQ Query sorterer altid dataene i ID-feltet, når det åbnes.

Demodatabasen er vedhæftet til download. Der er to demoformularer i databasen. Den første formular demonstrerer åbningen af ​​tabeller og forespørgsler i ListView Control for at se dataene i dataarkvisning. Den anden formular bruger kun EmployeesQ Forespørg alene for at trække, slippe, sortere og gemme sidste sorteringsrækkefølge af data til fremtidig brug.



  1. ActiveX ListView Control Tutorial-01.
  2. ListView Control Tutorial-02.
  3. Tildeling af billeder til ListView-elementer.
  4. ListView Control Drag-Drop Sorter hændelser
  5. ListView-kontrol med MS-Access TreeView
  6. TreeView/ListView-kontroller Træk-slip hændelser

  1. Oracle Rows to Column Transformation

  2. MySQL-søgning i kommaliste

  3. mysql pivot-forespørgselsresultater med GROUP BY

  4. Sådan fungerer age() i PostgreSQL