sql >> Database >  >> RDS >> Access

ListView-besturing Drag-Drop Gebeurtenissen sorteren

Rijken met gegevens herschikken in ListView Control.

In de eerdere aflevering van deze zelfstudie hebben we geleerd hoe u de kolommen opnieuw kunt rangschikken door deze functie in te schakelen:AllowColumnReorder optie op het eigenschappenblad. Maar het verplaatsen van een rij doe je door deze te slepen en op een andere rij te plaatsen. Voor het herschikken van de ListView-controlerijen, vereist de actie ListItem Drag and Drop het inschakelen van deze functie op het eigenschappenblad. Maar dit alleen werkt niet, er is VBA-code nodig om het item in de gewenste volgorde te plaatsen.

Laten we voor deze oefening een voorbeeldtoegangsformulier maken met besturingselementen en VBA-code in onze database. De voorbeeldafbeelding van het formulier met ListBox en ListView-besturingselementen wordt hieronder gegeven.

We hebben een lijst met tabellen en query's (geen actiequery's) gemaakt in de keuzelijst. Als u een van de lijstitems selecteert, worden de records onmiddellijk weergegeven in het ListView-besturingselement, zoals we ze zien in de DataSheet-weergave.

De ontwerptaak.

  1. Maak een nieuwe tabel met een enkel tekstveld, met de veldnaam DataList .

  2. Sla de tabel op met de naam lvTables (lv staat voor ListView).

  3. Open de tabel in de gegevensbladweergave.

  4. Voeg een paar tabelnamen toe en selecteer Query-namen uit uw database in de tabel. Ik heb tabellen geïmporteerd uit de Northwind-voorbeelddatabase voor mijn lijst.

    Opmerking: De Bijlage Veld is niet geldig in ListView-besturingselement. Maak selectiequery's voor tabellen met een bijlageveld en selecteer alle velden behalve het bijlageveld.

  5. Maak en open een nieuw formulier in de ontwerpweergave.

  6. Voeg een ListBox-besturingselement in op het formulier, geef het eigenschappenblad weer en wijzig de Naam eigenschapswaarde naar Lijst0 .

  7. Wijzig het onderliggende label Bijschrift waarde voor Tafels .

  8. Geef het eigenschappenblad van het ListBox-besturingselement weer en stel de Rijbron . in eigenschapswaarde naar de lvTables naam.

  9. Controleer of het rijbrontype is ingesteld als tabel/query en of de waarde van de eigenschap Gebonden kolom 1 is. Indien anders, wijzig dan.

  10. Voeg een ListView-besturingselement in vanuit de lijst met ActiveX-besturingselementen en wijzig de waarde van de eigenschap Name in ListView1 .

  11. Pas het formaat van beide bedieningselementen aan zoals getoond op de demo-formulierafbeelding hierboven.

  12. Voeg een label in boven de bedieningselementen en wijzig de naam en eigenschapswaarden voor bijschrift in Kop. De waarde van het bijschrift wordt gewijzigd van vba-code wanneer een tabel of query wordt geselecteerd in de ListBox.

  13. Maak een opdrachtknop onder de bedieningselementen en wijzig de waarde van de eigenschap Naam in cmdClose en de waarde van de eigenschap Caption op Sluiten .

  14. Klik met de rechtermuisknop op het ListView-besturingselement, markeer het ListViewCtrl-object en selecteer Eigenschappen .

  15. Wijzig de eigenschapsinstellingen zodat ze overeenkomen met de instellingen in de Algemeen Tabafbeelding hieronder weergegeven.

  16. Afbeelding van ListView-besturingseigenschappenblad - Algemeen tabblad wordt hieronder weergegeven:

    Sommige van deze opties hebben we al ingesteld in de eerdere sessies. Hier hebben we de volgende opties nodig voor onze Drag Drop-actie:

    • OLEDragAutomatic - 1

    • OLEDropManual - 1

    • FullRowSelect - True

    • HotTracking - Waar

Zorg ervoor dat de bovenstaande instellingen overeenkomen met uw eigenschappenblad en sla het formulier vervolgens op.

Geef de VBA-module van het formulier weer.

De VBA-code van de formuliermodule.

Kopieer en plak de volgende VBA-code in de module en overschrijf de bestaande coderegels, indien aanwezig:

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

U bent bekend met de bovenstaande VBA-code, behalve de nieuw toegevoegde subroutines:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), en de ListView1_ColumnClik() procedures. Met de eerste twee procedures kunnen we een item (rij) slepen en over een ander item laten vallen om het op een nieuwe locatie in te voegen. De procedures Form_Unload() en ListView1_ColumnClick() sorteren de items.

De volgende afbeeldingen tonen de actie Slepen en neerzetten in volgorde van uitvoering

De eerste afbeelding hieronder toont de actiereeks met slepen en neerzetten. Het ListItem, met EmployeeID 7, wordt door de gebruiker omhoog gesleept en valt over het ListItem met ID 3.

De tweede afbeelding toont de verplaatsing van ListItem in omgekeerde volgorde.

Wanneer de muisaanwijzer over een rij beweegt met het gesleepte item, tussen de bron- en doelrij, wordt de ene na de andere gemarkeerd op de weg naar boven.

De slepen-en-neerzetten-actie in afbeeldingen.

De rij met werknemer-ID 7 wordt neergezet op het item met werknemer-ID 3 hierboven.

De VBA-code segmentgewijze analyse.

Een itemselectie uit de ListBox, de gebeurtenisprocedure List0_Click() wordt uitgevoerd en laadt de records in het ListView-besturingselement.

Private Sub List0_Click()
Dim strTable As String

strTable = List0.Value

  Call LoadListView(strTable)

End Sub

De geselecteerde tabel-/querynaam wordt opgeslagen in de strTable string variabele. De LoadListView() subroutine wordt uitgevoerd met de variabele strTable als parameter. We hebben deze code in eerdere sessies meer dan eens doorgenomen en u kunt die pagina's bezoeken met behulp van de links onderaan deze pagina voor details. Mogelijk vindt u een paar kleine wijzigingen die ik in deze code heb aangebracht.

We hebben het ImageList-besturingselement in deze aflevering niet gebruikt, het Icon, SmallIcon Parameterwaarden in de methode ListItems.Add() en ReportIcon, TooltipText parameterwaarden in de methode ListSubItems.Add() worden ook niet gebruikt.

Laten we eens kijken naar wat er gebeurt in de ListView1_OLEDragOver() en ListView1_OLEDragDrop() VBA-codesegmenten.

De ListView1_OLEDragOver()-procedure.

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 

Deze procedure wordt automatisch uitgevoerd wanneer u probeert op een rij te klikken en vast te houden, begint te slepen en over andere rijen beweegt op weg naar de doelrij. De sleepactie beweegt over een andere rij, deze wordt gemarkeerd.

De ListView1.HitTest(x, y) functie leest de x, y-coördinaten die de rijpositie op het ListView-besturingselement bepalen en markeert die rij. Dit proces gaat door wanneer u zich boven andere rijen bevindt totdat u het op de doelrij laat vallen door de muisknop los te laten. De drop-actie activeert de ListView1_OLEDragDrop() procedure en voert de wijzigingsprocedures van de bronrij uit.

De ListView1_OLEDragDrop-procedure.

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

Laten we deze procedure deel voor deel bekijken en begrijpen wat daar gebeurt. Het volgende codesegment verklaart de benodigde objectvariabelen om de actie slepen en neerzetten af ​​te handelen:

'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 eerste drie ListItem tijdelijke objecten declareren met verschillende namen.

De lvwDrag ListItem-object bevat de kopie van de rij die we kiezen om naar een nieuwe locatie te slepen.

De lvwDrop ListItem Object slaat de referentie op van de rij waarop we het gesleepte lijstitem neerzetten.

Tijdens de omschakeling van de ListItems-actie, zullen we het Source-item van de oorspronkelijke locatie verwijderen en het vervolgens op de doellocatie maken, met het bron ListItem Index-nummer. De referenties van dit nieuwe ListItem worden opgeslagen in de lvwTarget Objectvariabele ListItem.

De lvwSub Variabele gedeclareerd als een sequencing-objectvariabele in de For . . .Volgende Lus. Voor deze lus moeten de ListSubItems, (2e kolom en verder) één voor één worden doorlopen vanuit het lvwDrag-object. Hoewel we het originele ListItem hebben verwijderd, hebben we er een kopie van bewaard in het lvwDrag ListItem-object.

Het lvwDrop ListItem Index-nummer wordt opgeslagen in de intTgtIndex Variabel.

De lvwList.HitTest(x, y) Functie leest de x, y-coördinaten van het ListView-besturingselement en identificeert het doel ListItem waar we de bron ListItem hebben neergezet en maakt er een kopie van in lvwDrop Object.

We zullen eerst een ListItem selecteren voordat we het naar de nieuwe positie slepen.

De lvwList.SelectedItem Eigenschap wordt ingesteld op True. Met behulp van deze eigenschapsstatus maken we een kopie van het geselecteerde ListItem in de lvwDrag ListItem-object. Het volgende codesegment valideert zowel bron- als doellijstitemobjecten.

Validatiecontroles op de actie met slepen en neerzetten.

'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

Het bovenstaande codesegment valideert de actie met slepen en neerzetten. Als deze acties niet zijn begonnen of eindigen op een geldig item, dan zijn de lvwDrop- of lvwDrag-objecten of beide leeg. Of er kan een andere ongeldige zet plaatsvinden als de gebruiker een rij omhoog of omlaag beweegt, maar hij kan van gedachten veranderen en deze weer in dezelfde rij laten vallen. Detectie van dit soort verkeerde bewegingen zal het programma beëindigen.

Als de bovenstaande test geldig blijkt te zijn, zal het programma doorgaan met het uitvoeren van de volgende procedure om de rijen te herschikken.

'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

De bovenstaande negen regels uitvoerbare code (andere regels zijn opmerkingen) acties zijn enigszins eenvoudig.

De intTgtIndex =lvwDrop.Index instructie slaat het doel ListItem's Index nummer op in intTgtIndex Variabel.

Aangezien we de Source Row listItem al hebben opgeslagen in het tijdelijke Object lvwDrag, is de volgende stap het verwijderen van de source ListItem uit het ListView-besturingselement. De ListItems.Remove() procedure wordt aangeroepen, met de instructie lvwList.ListItems.Remove lvwDrag.Index .

Kortom, de actie Drag Drop is het verwijderen van een ListItem van de oorspronkelijke locatie en het opnieuw maken op de doellocatie met het indexnummer van de doelrij.

De instructie Set lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) maakt het nieuwe ListItem met zijn doellocatie-indexnummer intTgtIndex en de Text waarde van Source ListItem opgeslagen in het lvwDrag Object eerder.

Toen we ListItem voor de eerste keer maakten, hebben we alleen deze twee waarden gebruikt, de index en de Text parameterwaarden. We hebben de andere parameteropties Key, Icon, . niet gebruikt en SmallIcon anders moeten we die parameterwaarden ook van het lvwDrag-object opnemen.

Volgens onze Drag Drop-voorbeeldafbeeldingen die hierboven worden getoond, hebben we het 7e ListItem verplaatst en op het 3e ListItem neergezet. Daarna hebben we het 7e item (of bron ListItem) uit het ListView-besturingselement verwijderd. Een nieuw ListItem gemaakt met het doelindexnummer 3.

Nu zijn er twee items met hetzelfde indexnummer 3, de bestaande met indexnummer 3 en de nieuwe die we hebben gemaakt met indexnummer 3. Alle andere informatie is afkomstig van het lvwDrag-object (of het 7e ListItem opgeslagen in lvwDrag Eerder bezwaar).

Het systeem verhoogt automatisch de bestaande ListItem 3 naar de volgende volgnummers 3,4,5 . . . tot 4,5,6 . . . en verplaatst ze naar voren om ruimte te maken voor het binnenkomende item om ertussen te plaatsen.

De impact van het verwijderen van een rij en het ergens anders maken.

Stel dat we die beweging in omgekeerde volgorde maken, zoals ListItem nummer 3 van bovenaf slepen en neerzetten op item nummer 7, wat gebeurt er dan?

Uiteraard zullen we het 3e item verwijderen en zullen we proberen een nieuw item te maken met indexnummer 7 op de nieuwe locatie. Wanneer item nummer 3 wordt verwijderd, zal item nummer 4 hoger worden of 4,5,6,7,8,9 wordt 3,4,5,6,7,8 (om alle items in volgorde te maken) of eerder item met indexnummer 7 wordt 6.

Wanneer we het nieuwe item met indexnummer 7 maken, wordt de bestaande 7,8 weer 8,9. Wanneer we de beweging van rijen bekijken terwijl rijen worden verwijderd en gemaakt, zal het eerste voorbeeld de doelrij naar beneden verplaatsen om plaats te maken voor het binnenkomende item. In het tweede voorbeeld dat wordt uitgelegd (verplaatst 3 naar 7) zal de bestemmingsrij omhoog gaan.

Opmerking: Kijk tde werknemers-ID-waarde voor zijn plaatsing als aanwijzing voor het naar beneden of naar boven verplaatsen van ListItem wanneer we ListItem herschikken.

Ik heb ListItem overal genoemd in bewerkingen met slepen en neerzetten. Het ListItem verwijst alleen naar de eerste kolom van de ListView-rij. Andere kolomwaarden zijn ListSubItems of de onderliggende items van ListItem. Dat betekent dat u alleen de eerste kolom kunt slepen en neerzetten. Andere kolommen of ListSubItems worden verplaatst onder het ListItem met VBA-code.

Dit is het geval als u de FullRowSelection . niet hebt ingeschakeld op het ListView Control-eigenschappenblad op de Algemeen Tab.

Indien ingeschakeld, kunt u elke kolom selecteren, maar het systeem verwijst naar de ListItem Index voor het opnieuw ordenen van rijen. Vergelijk de bovenstaande twee afbeeldingen met een andere set van twee voorbeeldafbeeldingen, de derde en vierde afbeelding vanaf de bovenkant van deze pagina.

De actie Slepen en neerzetten werkt niet als de volgende twee eigenschapswaarden niet zijn ingesteld op het eigenschappenblad ListView Control op de Algemeen Tab.:

  • ccOLEDragAutomatic =1
  • ccOLEDropManual =1

De volgende vijf instructies verplaatsen de ListSubItems, indien van toepassing, naar het ListItem dat nieuw is gemaakt op de nieuwe locatie.

Vervolgens wordt het nieuw gemaakte ListItem gemarkeerd.

Vervolgens worden alle aangemaakte tijdelijke objecten uit het geheugen gewist.

Opmerking: Een ander belangrijk punt om op te merken is dat deze regeling een tijdelijke is en verloren gaat wanneer u het formulier sluit of een andere tabel/query laadt in het ListView-besturingselement.

Als we willen dat de gewijzigde volgorde van ListItems permanent blijft, of totdat de volgorde de volgende keer wordt gewijzigd, dan moeten we het huidige geïndexeerde bestelnummer op de tafel zelf kunnen bijwerken. We hebben een nieuw Integer-veld toegevoegd met de veldnaam-ID in de werknemerstabel.

Het voorbeeldscherm met de gegevens van de werknemers in alfabetische volgorde is hieronder weergegeven:

Aangezien het veld Werknemers-ID een AutoNummering-veld is en gekoppeld is aan andere gerelateerde tabellen, hebben we een nieuw Nummerveld toegevoegd met de veldnaam-ID. Deze veldwaarde wordt in eerste instantie handmatig ingesteld met dezelfde volgnummers uit de Werknemers-ID. Deze veldwaarde staat aanvankelijk in deze volgorde. Maar de ListView Rows-gegevens kunnen van volgorde veranderen wanneer u de gegevens op het ListView-besturingselement opnieuw rangschikt vanwege slepen en neerzetten.

Bekijk de EmployeesQ Query SQL hieronder gegeven:

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;

De bovenstaande query wordt gebruikt als gegevensbron voor het ListView-besturingselement en ze worden gesorteerd op het ID-veld. Het ID-veld wordt bijgewerkt met de gewijzigde volgorde van indexnummers op het ListView-besturingselement. Het updateproces wordt uitgevoerd vanaf de Form_Unload() Gebeurtenis Procedure wanneer u het formulier sluit. Deze methode zorgt ervoor dat wanneer u de ListView Control de volgende keer opent, de gegevens in de volgorde staan ​​waarin u de vorige keer opnieuw hebt geordend.

De Form_Unload() Gebeurtenisprocedure VBA-code.

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

Controleer de EmployeeName Veldwaarde in de bovenstaande afbeelding. Ze zijn gerangschikt in alfabetische volgorde. De nieuwe ID-veldwaarde op de werknemerstabel wordt bijgewerkt met hun huidige ListView Control ListItem-indexnummerreeks.

Als u de volgende punten opmerkt, kunt u gemakkelijk begrijpen wat we met de bovenstaande code doen:

  1. De ListItem's (eerste kolom) Tekst parameterwaarde is de naam van de werknemer en gerangschikt in alfabetische volgorde.

  2. De ListItems op het ListView-besturingselement hebben indexnummers van 1 tot 9 in de volgorde waarin het op het scherm wordt weergegeven, d.w.z. het indexnummer van het eerste item is 1 en het laatste is 9. De oorspronkelijke gegevens in de veldwaarde van de ID-veld van de werknemerstabel zijn niet in deze volgorde.

  3. We nemen de Tekst Waarde (Employee Name) van het eerste ListItem en zoek naar de naam op de tafel.

  4. Wanneer het record wordt gevonden, wordt het huidige Indexnummer van ListItem bijgewerkt (vervangen) in het ID-veld op de tafel.

  5. Dit proces werd herhaald voor alle resterende records op de tafel.

Laten we de VBA-code doornemen. In het begin controleren we of de brongegevenstabel/query in het ListView-besturingselement is geladen of niet?

Als de strTable Variabele is niet geïnitialiseerd met de naam van de query, dan is het ListView-besturingselement leeg. Als dit het geval is, heeft de gebruiker het formulier geopend en gesloten zonder de naam van de query te selecteren om de gegevens in het ListView-besturingselement te laden. De Form_Unload Gebeurtenisprocedure wordt op dit punt afgebroken en sluit het formulier.

Als het ListView-besturingselement gegevens heeft, wordt de volgende stap uitgevoerd en wordt de brongegevensquery EmployeesQ geopend om bij te werken.

De volgende stap is om elk ListItem te doorlopen en het indexnummer in het ID-veld van het Employees-record bij te werken.

Eerst wordt het huidige rij-indexnummer opgeslagen in de tmp Variabel.

De eerste lvwList.ColumnHeader naam EmployeeName en de naam . van de werknemer is overgenomen uit de ListItem.Text in een uitdrukking in de Criteria stringvariabele, zoals EmployeeName ="Andrew Fuller".

De eerste.FindFirst-criteria commando zoekt in de brongegevenstabel om het record met de opgegeven naam te vinden. Wanneer het record is gevonden, wordt het huidige ListItem Index-nummer bijgewerkt in het ID-veld.

Dit proces wordt herhaald voor alle rijen in het ListView-besturingselement en wanneer het klaar is, wordt het formulier gesloten.

De volgende keer dat u de records van deze query in het ListView-besturingselement laadt, worden ze in dezelfde volgorde weergegeven als de vorige keer dat u het formulier sloot.

Opmerking:De Query werd hier nodig om de gegevens in het ID-veld te sorteren en ze in de gewijzigde volgorde weer te geven op het ListView-besturingselement.

Al dit werk was om de gegevens in de laatst gesorteerde volgorde op te slaan, zodat de volgende keer dat u het formulier opent, de gegevens op het ListView-besturingselement in die volgorde staan.

Windows Explorer-achtige sorteermethode.

In Windows Verkenner kunt u de weergegeven lijst sorteren in oplopende of aflopende volgorde door op een kolomkop te klikken. De kolomkop werkt als een wisselknop. Herhaald klikken op de kolomkop zal de kolomgegevens in oplopende/aflopende volgorde sorteren op de volgende ListView1_ColumnClick() Evenementprocedure:

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

Opmerking: Het sorteren van alle gegevens is alleen in de modus voor het vergelijken van tekst. De ListItems en ListSubItems Toevoegen() methode's derde parameter, de weergegeven informatie op het ListView-besturingselement is Text type. Datum en numerieke waarden worden allemaal behandeld als alleen tekst.

Windows Verkenner bewaart de laatst gesorteerde volgorde van items in de map. Wanneer we die map opnieuw openen, wordt de lijst weergegeven in de eerder gesorteerde volgorde.

Met de Form_Unload() Gebeurtenis Procedure deze functie van Windows Verkenner wordt mogelijk op de Werknemerstafel. Wanneer u het formulier sluit na het sorteren op een kolom, wordt die geïndexeerde volgorde opgeslagen in de werknemerstabel in het ID-veld. De EmployeesQ Query sorteert altijd de gegevens op het ID-veld wanneer het wordt geopend.

De demo-database is bijgevoegd om te downloaden. Er zijn twee demoformulieren in de Database. Het eerste formulier demonstreert het openen van tabellen en query's in het ListView-besturingselement om de gegevens in de gegevensbladweergave te bekijken. Het tweede formulier gebruikt alleen de EmployeesQ Query alleen voor slepen, neerzetten, sorteren en opslaan van de laatste sorteervolgorde van gegevens voor toekomstig gebruik.



  1. ActiveX ListView Control Tutorial-01.
  2. ListView Control Tutorial-02.
  3. Afbeeldingen toewijzen aan ListView-items.
  4. ListView Control Drag-Drop Sorteer gebeurtenissen
  5. ListView-besturing met MS-Access TreeView
  6. TreeView/ListView-besturingselementen Drag-Drop-gebeurtenissen

  1. KNIME

  2. Hoe Cosh() werkt in PostgreSQL

  3. Kan offset-naïeve en offset-bewuste datetimes niet aftrekken

  4. Wat is de standaardprecisie en schaal voor een getal in Oracle?