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.
-
Crea una nuova tabella con un unico campo di testo, con il nome del campo DataList .
-
Salva la tabella con il nome lvTables (lv sta per ListView).
-
Apri la tabella in visualizzazione Foglio dati.
-
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.
-
Crea e apri un nuovo modulo in Visualizzazione struttura.
-
Inserire un controllo ListBox nel form, visualizzare la finestra delle proprietà e cambiarne il Nome valore della proprietà su List0 .
-
Modifica l'etichetta figlio Didascalia valore a Tabelle .
-
Visualizza la finestra delle proprietà del controllo ListBox e imposta l'Origine riga valore della proprietà in lvTables nome.
-
Controlla se il Tipo di origine riga è impostato come Tabella/Query e il valore della proprietà Colonna associata è 1. Se diverso, cambia.
-
Inserire un controllo ListView dall'elenco dei controlli ActiveX e modificarne il valore della proprietà Name in ListView1 .
-
Ridimensiona entrambi i controlli come mostrato nell'immagine del modulo demo fornita sopra.
-
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.
-
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 .
-
Fare clic con il pulsante destro del mouse sul controllo ListView, evidenziare l'Oggetto ListViewCtrl opzione e seleziona Proprietà .
-
Modifica le impostazioni della proprietà in modo che corrispondano alle impostazioni in Generale Immagine della scheda fornita di seguito.
-
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:
-
Il Testo di ListItem (prima colonna). il valore del parametro è il nome del dipendente ed è organizzato in ordine alfabetico.
-
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.
-
Prendiamo il Testo Valore (Employee Name) del primo ListItem e cerca il nome sulla tabella.
-
Quando il record viene trovato, il numero di indice di ListItem corrente viene aggiornato (sostituito) nel campo ID della tabella.
-
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.
- Esercitazione sul controllo di ActiveX ListView-01.
- Esercitazione sul controllo ListView-02.
- Assegnazione di immagini agli elementi ListView.
- Controllo ListView, trascina e ordina gli eventi
- Controllo ListView con TreeView di MS-Access
- TreeView/ListView controlla gli eventi Drag-Drop