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

ListView Controllo Drag-Drop Ordina eventi

Riorganizzazione delle righe di dati nel controllo ListView.

Nell'episodio precedente di questo tutorial, abbiamo imparato come riorganizzare le colonne abilitando questa funzione:AllowColumnReorder opzione nella scheda delle proprietà. Tuttavia, il trasferimento di una riga viene eseguito trascinandola e posizionandola su un'altra riga. Per riorganizzare le righe di controllo ListView, l'azione Trascina e rilascia ListItem richiede l'abilitazione di questa funzionalità nella finestra delle proprietà. Ma questo da solo non funzionerà, ha bisogno del codice VBA per riorganizzare l'articolo nell'ordine richiesto.

Creiamo un modulo di accesso di esempio con controlli e codice VBA nel nostro database per questo esercizio. L'immagine di esempio del modulo con i controlli ListBox e ListView è riportata di seguito.

Abbiamo creato un elenco di tabelle e query (non query di azione) nella casella di riepilogo. Selezionando una delle voci dell'elenco, i record verranno visualizzati istantaneamente sul controllo ListView, così come li vediamo nella vista Foglio dati.

Il compito di progettazione.

  1. Crea una nuova tabella con un unico campo di testo, con il nome del campo DataList .

  2. Salva la tabella con il nome lvTables (lv sta per ListView).

  3. Apri la tabella in visualizzazione Foglio dati.

  4. Aggiungi alcuni nomi di tabelle e seleziona i nomi delle query dal tuo database nella tabella. Ho importato le tabelle dal database di esempio Northwind per il mio elenco.

    Nota: L'allegato Il campo non è valido nel controllo ListView. Crea query di selezione per tabelle con campo allegato e seleziona tutti i campi tranne il campo allegato.

  5. Crea e apri un nuovo modulo in Visualizzazione struttura.

  6. Inserire un controllo ListBox nel form, visualizzare la finestra delle proprietà e cambiarne il Nome valore della proprietà su List0 .

  7. Modifica l'etichetta figlio Didascalia valore a Tabelle .

  8. Visualizza la finestra delle proprietà del controllo ListBox e imposta l'Origine riga valore della proprietà in lvTables nome.

  9. Controlla se il Tipo di origine riga è impostato come Tabella/Query e il valore della proprietà Colonna associata è 1. Se diverso, cambia.

  10. Inserire un controllo ListView dall'elenco dei controlli ActiveX e modificarne il valore della proprietà Name in ListView1 .

  11. Ridimensiona entrambi i controlli come mostrato nell'immagine del modulo demo fornita sopra.

  12. Inserisci un'etichetta sopra i controlli e cambia i suoi valori di proprietà di nome e didascalia in Intestazione. Il valore della didascalia verrà modificato dal codice vba quando viene selezionata una tabella o una query da ListBox.

  13. Crea un pulsante di comando sotto i controlli e modificane il valore della proprietà Name in cmdClose e il valore della proprietà Caption su Chiudi .

  14. Fare clic con il pulsante destro del mouse sul controllo ListView, evidenziare l'Oggetto ListViewCtrl opzione e seleziona Proprietà .

  15. Modifica le impostazioni della proprietà in modo che corrispondano alle impostazioni in Generale Immagine della scheda fornita di seguito.

  16. Immagine della scheda delle proprietà del controllo ListView - Di seguito è riportata la visualizzazione della scheda Generale:

    Alcune di queste opzioni le abbiamo già impostate nelle sessioni precedenti. Qui abbiamo bisogno delle seguenti opzioni per la nostra azione Drag Drop:

    • OLEDragAutomatico - 1

    • Manuale OLEDrop - 1

    • FullRowSelect - Vero

    • HotTracking - Vero

Assicurati che le impostazioni di cui sopra corrispondano alla tua scheda delle proprietà, quindi salva il modulo.

Visualizza il modulo VBA del modulo.

Il codice VBA del modulo modulo.

Copia e incolla il seguente codice VBA nel modulo, sovrascrivendo le righe di codice esistenti, se presenti:

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

Hai familiarità con il codice VBA sopra, ad eccezione delle subroutine appena aggiunte:ListView1_OLEDragOver(), ListView1_OLEDragDrop(), Form_Unload(), e ListView1_ColumnClik() procedure. Le prime due procedure ci aiuteranno a trascinare un elemento (riga) e rilasciarlo su un altro elemento per inserirlo in una nuova posizione. Le procedure Form_Unload() e ListView1_ColumnClick() ordineranno gli elementi.

Le seguenti immagini mostrano l'azione Trascina e rilascia nelle sequenze della sua esecuzione

La prima immagine seguente mostra la sequenza di azioni di trascinamento della selezione. L'oggetto ListItem, con EmployeeID 7, viene trascinato dall'utente verso l'alto e viene rilasciato sopra ListItem con ID 3.

La seconda immagine mostra lo spostamento di ListItem in ordine inverso.

Quando il puntatore del mouse si sposta su una riga con l'elemento trascinato, tra le righe di origine e di destinazione, verrà evidenziata una dopo l'altra durante la salita.

L'azione Trascina e rilascia nelle immagini.

La riga con ID dipendente 7 viene eliminata sull'articolo con ID dipendente 3 sopra.

L'analisi del segmento del codice VBA.

Una selezione di elementi da ListBox la procedura dell'evento List0_Click() esegue e carica i record nel controllo ListView.

Private Sub List0_Click()
Dim strTable As String

strTable = List0.Value

  Call LoadListView(strTable)

End Sub

Il nome della tabella/query selezionata viene salvato nella strTable variabile stringa. La LoadListView() la subroutine viene eseguita con la variabile strTable come parametro. Abbiamo esaminato questo Codice più di una volta nelle sessioni precedenti e puoi visitare quelle Pagine utilizzando i collegamenti forniti in fondo a questa pagina per i dettagli. Potresti trovare alcune modifiche minori che ho apportato a questo codice.

Non abbiamo utilizzato il controllo ImageList in questo episodio Icon, SmallIcon Valori dei parametri nel metodo ListItems.Add() e ReportIcon, TooltipText anche i valori dei parametri nel metodo ListSubItems.Add() non sono utilizzati.

Diamo un'occhiata a cosa sta succedendo in ListView1_OLEDragOver() e ListView1_OLEDragDrop() Segmenti di codice VBA.

La 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 

Questa procedura viene eseguita automaticamente quando si tenta di fare clic e tenere premuta una riga, iniziare a trascinare e spostarsi su altre righe lungo la strada verso la riga di destinazione. L'azione di trascinamento si sposta su un'altra riga che verrà evidenziata.

ListView1.HitTest(x, y) la funzione legge le coordinate x, y che determinano la posizione della riga sul controllo ListView ed evidenzia quella riga. Questo processo continua quando ti trovi su altre righe finché non la rilasci sulla riga di destinazione rilasciando il pulsante del mouse. L'azione di rilascio attiva ListView1_OLEDragDrop() procedura ed esegue le procedure di cambio della riga di origine.

La 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

Esaminiamo questa procedura parte per parte e capiamo cosa sta succedendo lì. Il seguente segmento di codice dichiara le variabili oggetto necessarie per gestire l'azione Trascina e rilascia:

'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

I primi tre oggetti temporanei ListItem dichiarano con nomi diversi.

Il lvwDrag L'oggetto ListItem conterrà la copia della riga che selezioniamo per trascinarla in una nuova posizione.

Il lvwDrop ListItem Object salverà il riferimento della riga su cui rilasciamo l'elemento dell'elenco trascinato.

Durante il cambio dell'azione ListItems, elimineremo l'elemento Source dalla sua posizione originale, quindi lo creeremo nella posizione di destinazione, con il numero di ListItem Index di origine. I riferimenti di questo nuovo ListItem vengono salvati in lvwTarget Variabile oggetto ListItem.

Il lvwSub Variabile dichiarata come una variabile oggetto di sequenziamento in For . . .Avanti Ciclo continuo. Questo ciclo richiede la sequenza attraverso ListSubItems, (dalla seconda colonna in poi) uno per uno, dall'oggetto lvwDrag. Anche se abbiamo eliminato il ListItem originale, ne abbiamo salvata una copia nell'oggetto lvwDrag ListItem.

Il numero di indice lvwDrop ListItem viene salvato in intTgtIndex Variabile.

lvwList.HitTest(x, y) La funzione legge le coordinate x, y del controllo ListView e identifica il ListItem di destinazione in cui è stato rilasciato il ListItem di origine e ne esegue una copia in lvwDrop Object.

Selezioneremo un ListItem prima di trascinarlo nella nuova posizione.

Il lvwList.SelectedItem La proprietà verrà impostata su True. Con l'aiuto di questo stato della proprietà, facciamo una copia del ListItem selezionato nel lvwDrag Oggetto ListItem. Il segmento di codice successivo convalida sia gli oggetti ListItem di origine che quelli di destinazione.

Verifiche di convalida sull'azione di trascinamento della selezione.

'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

Il segmento di codice sopra convalida l'azione di trascinamento della selezione. Se queste azioni non sono iniziate o terminate su un elemento valido, gli oggetti lvwDrop o lvwDrag o entrambi saranno vuoti. Oppure può verificarsi un'altra mossa non valida quando l'utente sposta una riga in alto o in basso, ma può cambiare idea e riportarla sulla stessa riga. Il rilevamento di questo tipo di mosse sbagliate interromperà il programma.

Se il test di cui sopra si rivela valido, il programma continuerà a eseguire la procedura successiva per riorganizzare le righe.

'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

Le precedenti nove righe di azioni del codice eseguibile (le altre righe sono commenti) sono piuttosto semplici.

L'intTgtIndex =lvwDrop.Index salva il numero di indice di ListItem di destinazione in intTgtIndex Variabile.

Poiché abbiamo già salvato la riga di origine listItem nell'oggetto temporaneo lvwDrag, il passaggio successivo consiste nel rimuovere la ListItem di origine dal controllo ListView. La procedura ListItems.Remove() viene chiamato, con l'istruzione lvwList.ListItems.Remove lvwDrag.Index .

In breve, l'azione Drag Drop consiste nell'eliminare un ListItem dalla sua posizione originale e crearlo di nuovo nella posizione di destinazione con il numero di indice della riga di destinazione.

L'istruzione Imposta lvwTarget =lvwList.ListItems.Add(intTgtIndex, , lvwDrag.Text) crea il nuovo ListItem con il numero di indice della posizione di destinazione intTgtIndex e il Testo valore di Source ListItem salvato in precedenza nell'oggetto lvwDrag.

Durante la creazione di ListItem per la prima volta, abbiamo utilizzato solo questi due valori, l'indice e il Testo valori dei parametri. Non abbiamo utilizzato le altre opzioni dei parametri Chiave, Icona e SmallIcon altrimenti dobbiamo includere quei valori di parametro anche dall'oggetto lvwDrag.

Come per il nostro esempio di Drag Drop Immagini mostrate sopra, abbiamo spostato il 7° ListItem e lo abbiamo rilasciato sul 3° ListItem. Successivamente, abbiamo eliminato il settimo elemento (o ListItem di origine) dal controllo ListView. Creato un nuovo ListItem con il numero di indice di destinazione 3.

Ora, ci sono due elementi con lo stesso numero di indice 3, quello esistente con il numero di indice 3 e quello nuovo che abbiamo creato con il numero di indice 3. Tutte le altre informazioni sono prese dall'oggetto lvwDrag (o dal 7° ListItem salvato in lvwDrag Oggetto prima).

Il sistema incrementa automaticamente il ListItem 3 esistente in avanti fino ai numeri di sequenza successivi 3,4,5. . . a 4,5,6. . . e li sposta in avanti per dare spazio all'elemento in entrata da inserire nel mezzo.

L'impatto di eliminare una riga e crearla altrove.

Supponiamo di fare quella mossa nell'ordine inverso, come trascinare ListItem numero 3 dall'alto e rilasciarlo sull'elemento numero 7, quindi cosa succede?

Naturalmente, elimineremo il 3° articolo e cercheremo di creare un nuovo articolo con il numero di indice 7 nella nuova posizione. Quando l'articolo numero 3 viene eliminato, l'articolo numero 4 in poi si sposterà verso l'alto o 4,5,6,7,8,9 diventerà 3,4,5,6,7,8 (per creare tutti gli articoli in sequenza) o il precedente l'elemento con il numero di indice 7 diventerà 6.

Quando creiamo il nuovo Articolo con il numero di indice 7, il 7,8 esistente diventerà di nuovo 8,9. Quando osserviamo il movimento delle righe durante l'eliminazione delle righe e il tempo di creazione, il primo esempio sposterà la riga di destinazione verso il basso per far posto all'elemento in arrivo. Nel secondo esempio spiegato (spostando da 3 a 7) la riga di destinazione si sposterà in alto.

Nota: Guarda til valore dell'ID dipendente per la sua collocazione come indizio per ListItem che si sposta verso il basso o verso l'alto quando riorganizziamo ListItem.

Ho menzionato ListItem ovunque nelle operazioni di trascinamento della selezione. ListItem fa riferimento solo alla prima colonna della riga ListView. Altri valori di colonna sono ListSubItems o gli elementi figlio di ListItem. Ciò significa che sarai in grado di trascinare e rilasciare solo la prima colonna. Altre colonne o ListSubItems verranno spostate sotto ListItem con codice VBA.

Questo è vero se non hai abilitato la FullRowSelection nel foglio delle proprietà del controllo ListView in Generale Tab.

Se abilitato è possibile selezionare qualsiasi colonna, ma il sistema fa riferimento all'indice ListItem per scopi di riordino delle righe. Confronta le due immagini sopra con un altro set di due immagini campione, la terza e la quarta immagine dalla parte superiore di questa pagina.

L'azione Trascina e rilascia non funzionerà se i seguenti due valori di proprietà non sono impostati nel foglio delle proprietà del controllo ListView in Generale Tab.:

  • ccOLEDragAutomatic =1
  • ccOLEDropManual =1

Le cinque istruzioni successive sposteranno ListSubItems se presente, al ListItem appena creato nella nuova posizione.

Successivamente, il ListItem appena creato viene evidenziato.

Successivamente, tutti gli oggetti temporanei creati vengono cancellati dalla memoria.

Nota: Un altro punto importante da notare qui è che questa disposizione è temporanea e viene persa quando si chiude il modulo o si carica un'altra tabella/interrogazione sul controllo ListView.

Se vogliamo che l'ordine modificato di ListItems rimanga permanente, o fino a quando l'ordine non viene modificato la volta successiva, dobbiamo essere in grado di aggiornare il numero dell'ordine indicizzato corrente sulla tabella stessa. Abbiamo aggiunto un nuovo campo Intero con l'ID nome campo nella tabella Impiegati.

Di seguito è riportata la schermata di esempio con i dati dei dipendenti riordinati in ordine alfabetico:

Poiché il campo ID dipendenti è un campo Contatore e collegato ad altre tabelle correlate, abbiamo aggiunto un nuovo campo numero con l'ID nome campo. Questo valore di campo viene inizialmente impostato manualmente con gli stessi numeri di sequenza dall'ID dipendenti. Questo valore di campo sarà inizialmente in questo ordine. Tuttavia, i dati di ListView Rows possono cambiare il loro ordine quando si riorganizzano i dati sul controllo ListView a causa dell'azione di trascinamento della selezione.

Guarda ImpiegatiQ Interroga SQL indicato di seguito:

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;

La query precedente viene utilizzata come origine dati per il controllo ListView e vengono ordinate in base al campo ID. Il campo ID viene aggiornato con l'ordine modificato dei numeri indice nel controllo ListView. Il processo di aggiornamento viene eseguito da Form_Unload() Evento Procedura alla chiusura del modulo. Questo metodo garantisce che la prossima volta che apri ListView Control i dati saranno nell'ordine che hai riordinato l'ultima volta.

Il Form_Unload() Codice VBA della procedura dell'evento.

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

Controlla il EmployeeName Valore del campo nell'immagine sopra. Sono disposti in ordine alfabetico. Il nuovo valore del campo ID nella tabella Impiegati verrà aggiornato con la sequenza numerica dell'indice ListItem di controllo ListView corrente.

Se prendi nota dei seguenti punti puoi facilmente capire cosa facciamo con il codice sopra:

  1. Il Testo di ListItem (prima colonna). il valore del parametro è il nome del dipendente ed è organizzato in ordine alfabetico.

  2. ListItems sul controllo ListView ha numeri di indice da 1 a 9 nell'ordine in cui è mostrato sullo schermo, ovvero il numero di indice del primo elemento è 1 e l'ultimo è 9. I dati originali sul valore del campo ID tabella dipendenti non sono in questo ordine.

  3. Prendiamo il Testo Valore (Employee Name) del primo ListItem e cerca il nome sulla tabella.

  4. Quando il record viene trovato, il numero di indice di ListItem corrente viene aggiornato (sostituito) nel campo ID della tabella.

  5. Questo processo è stato ripetuto per tutti i record rimanenti sulla tabella.

Esaminiamo il codice VBA. All'inizio, controlliamo se la tabella/query dei dati di origine è stata caricata nel controllo ListView o no?

Se la strTable La variabile non è inizializzata con il nome della query, quindi il controllo ListView è vuoto. In questo caso, l'utente ha aperto il modulo e lo ha chiuso senza selezionare il nome della query per caricare i dati nel controllo ListView. Il Scarico_modulo La procedura dell'evento a questo punto viene interrotta e chiude il modulo.

Se il controllo ListView contiene dati, viene eseguito il passaggio successivo e viene aperta la query dei dati di origine EmployeesQ da aggiornare.

Il passaggio successivo consiste nell'esaminare ogni ListItem e aggiornare il numero di indice nel campo ID del record Impiegati.

Innanzitutto, il numero di indice della riga corrente viene salvato in tmp Variabile.

Il primo nome lvwList.ColumnHeader EmployeeName e il nome del dipendente è preso da ListItem.Text in un'espressione nei Criteri variabile stringa, come EmployeeName ="Andrew Fuller".

I criteri first.FindFirst Il comando cerca nella tabella dei dati di origine per trovare il record con il nome specificato. Quando il record viene trovato, il numero di indice ListItem corrente viene aggiornato nel campo ID.

Questo processo viene ripetuto per tutte le righe del controllo ListView e una volta terminato il modulo viene chiuso.

La prossima volta che carichi i record da questa query nel controllo ListView verranno visualizzati nello stesso ordine quando hai chiuso il modulo l'ultima volta.

Nota:La query è diventata necessaria qui per ordinare i dati nel campo ID e visualizzarli nell'ordine modificato sul controllo ListView.

Tutto questo lavoro è servito per salvare i dati nell'ultimo ordine ordinato in modo che la prossima volta che apri il modulo i dati sul controllo ListView saranno in quell'ordine.

Metodo di ordinamento simile a Esplora risorse di Windows.

In Esplora risorse, puoi ordinare l'elenco visualizzato in ordine crescente o decrescente facendo clic su qualsiasi intestazione di colonna. L'intestazione della colonna funzionerà come un pulsante di commutazione. I clic ripetuti sull'intestazione della colonna ordinano i dati della colonna in ordine crescente/decrescente in base al seguente ListView1_ColumnClick() Procedura dell'evento:

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

Nota: L'ordinamento di tutti i dati è solo in modalità confronto testo. Gli Elenco articoli e Elenco voci secondarie Aggiungi() terzo parametro del metodo, le informazioni visualizzate sul controllo ListView sono Testo genere. La data e i valori numerici sono tutti trattati come solo testo.

Esplora risorse salva l'ultimo ordine di elementi nella cartella. Quando apriamo di nuovo quella cartella, l'elenco verrà visualizzato nell'ordine precedente.

Con Form_Unload() Evento Procedura questa funzionalità di Esplora risorse diventa possibile nella tabella Impiegati. Quando si chiude il modulo dopo l'ordinamento su qualsiasi colonna, la sequenza di ordine indicizzata verrà salvata nella tabella dipendenti nel campo ID. La query EmployeesQ ordina sempre i dati nel campo ID quando viene aperta.

Il database Demo è allegato per il download. Ci sono due moduli demo nel database. Il primo modulo illustra l'apertura di tabelle e query nel controllo ListView per visualizzare i dati in visualizzazione foglio dati. Il secondo modulo utilizza solo EmployeesQ Interroga solo per trascinamento, rilascio, ordinamento e salvataggio dell'ultimo ordinamento dei dati per un uso futuro.



  1. Esercitazione sul controllo di ActiveX ListView-01.
  2. Esercitazione sul controllo ListView-02.
  3. Assegnazione di immagini agli elementi ListView.
  4. Controllo ListView, trascina e ordina gli eventi
  5. Controllo ListView con TreeView di MS-Access
  6. TreeView/ListView controlla gli eventi Drag-Drop