14. januar 2008 - 08:39Der er
8 kommentarer og 1 løsning
Søgning i Listview
Jeg har behov for at søge i 2 kolonner i en Listview1. Kolonnerne hedder Navn, Mobilnr. Jeg har et tekstfelt hvor jeg laver søgningen. Hvis der findes noget skal det fundne lægges over i en Listview2 med samme kolonnenavne Navn, Mobilnr. Håber der er nogen der kan hjælpe.
Hvis vi går ud fra at 1. kolonne (Navn) er selve item i ListView1, og at 2. kolonne (mobilnr) er 1. SubItem, kan det laves sådan (koden lægges f.eks. i en knap):
Dim sFind As String Dim i As Integer Dim Col1 As String, Col2 As String
sFind = Me.Text1.Text Col1 = "" For i = 1 To Me.ListView1.ListItems.Count 'søg i alle items If Me.ListView1.ListItems(i).Text = sFind Or _ 'søger både i Navn og Mobilnr Me.ListView1.ListItems(i).SubItems(1) = sFind Then Col1 = Me.ListView1.ListItems(i).Text Col2 = Me.ListView1.ListItems(i).SubItems(1) Exit For 'stop loop End If Next i If Col1 = "" Then MsgBox "Ingen poster fundet" Else Me.ListView2.ListItems.Add (Me.ListView2.ListItems.Count + 1), , Col1 Me.ListView2.ListItems(Me.ListView2.ListItems.Count).SubItems(1) = Col2 End If
Ovenstående fylder meget for forståelsens skyld. En komprimeret udgave:
Dim i As Integer For i = 1 To Me.ListView1.ListItems.Count If Me.ListView1.ListItems(i).Text = Me.Text1.Text Or _ Me.ListView1.ListItems(i).SubItems(1) = Me.Text1.Text Then Me.ListView2.ListItems.Add (Me.ListView2.ListItems.Count + 1), , Me.ListView1.ListItems(i).Text Me.ListView2.ListItems(Me.ListView2.ListItems.Count).SubItems(1) = Me.ListView1.ListItems(i).SubItems(1) Exit For End If Next i If i = Me.ListView1.ListItems.Count + 1 Then MsgBox "Ingen poster fundet"
Det virker godt nok med mobilnr., men nu vil den ikke finde navne. Det skulle meget gerne virke sådan at hvis jeg har en kontaktperson som hedder Hans Jensen og der søges på "Hans" eller "hans" så skal den finde Hans Hansen og indsætte ham i Listview2. Den kode som jeg har brugt er følgende, men virker ikke med mobilnr. ----------- Dim itm As ListItem Dim itmX As ListItem
With ListView1 Set itm = .FindItem(mobilnr.Text, lvwText, , lvwPartial) If Not itm Is Nothing Then .ListItems(itm.Index).Selected = True Set itmX = ListView2.ListItems.Add(, , ListView1.SelectedItem.Text) itmX.SubItems(1) = ListView1.SelectedItem.SubItems(1) Else Set itmX = ListView2.ListItems.Add(, , "(Ukendt mobilnr.)") itmX.SubItems(1) = mobilnr.Text End If End With
Set itm = Nothing Set itmX = Nothing -------------- der er sikkert noget kode der kan fjernes.
Grunden til at den fejler med mobilnr, er fordi den søger i ListItems, men mobilnr er i SubItems.
i .FindItem(mobilnr.Text, lvwText, , lvwPartial) angiver lvwText at der skal søges i ListItems. Den skal i stedet være lvwSubitem.
Jeg forstår ikke helt hvorfor du tilføjer et mobilnr der ikke findes i forvejen?
Men før jeg kommer med kodeforslag kunne jeg godt tænke mig at få præciseret hvad du egentlig vil:
Jeg kan forstå at du har to textboxe: en til Navn, og en til Mobilnr, hvor søgekriterium angives.
Når der søges:
1. Skal der søges på begge dele samtidig? Hvad hvis der findes 2 forskellige match?
2. Hvis der skal søges på delvis Navn, er det så kun fra starten af strengen? Så "Hans" giver match på "Hans Jensen" men ikke på "Jens Hansen"?
3. Skal der kun findes en match? Hvad hvis du både har "Hans Jensen" og "Hans Pedersen"? Eller hvis der søges på "Tom": "Tom Jensen" og "Tommy Jensen"?
Jeg har en Textbox1 hvor jeg skriver søgestrengen. Listview1 (navn, mobilnr) fyldes fra Outlook2003 kontaktpersoner. Listview2 (navn, mobilnr) fyldes med de mobilnr. som der skal sendes en SMS til. Når der trykkes på OK-knap skal der søges i Listview1 og findes det skal det fundne overføres til Listview2. Hvis der findes flere der matcher havde jeg forestillet mig at der skulle åbnes en ny Form som indeholder en Listview3 (navn, mobilnr) - her skulle man så vælge den kontaktperson som man vil have ført over i Listview2. Søges der på et mobilnr. som ikke findes i Listview1 skal mobilnr. overføres til Listview2 samt navn="(Ukendt mobilnr)". Søges der på et navn der ikke findes skal der ikke ske noget andet end Textbox1 bliver tom samt Setfocus. Man kan kun søge på 1 ting af gangen.
Jeg vil lige knytte et par kommentarer mere til dine spørgsmål. 1. Der skal søges på begge dele samtidig. 2. Det skal ikke være fra starten af strengen. Hvis man søger på "hans" så skal den finde den kontaktperson hvori "hans" indgår altså "Hans Jensen" "Søren Hansen" osv. Det er selvfølgelig ligemeget med store og små bogstaver. 3. Hvis der findes mere end 1 der matcher vil det være som beskrevet kl. 18:06:52.
Når der skal søges på delstrenge (ikke kun fra starten), så kan FindItem ikke bruges, da den kun søger fra starten af strengen. Derfor skal søgningen bygges op som min kommentar 14/01-2008 11:32:54. Der skal desuden skelnes mellem om det er et navn eller et mobilnr der er skrevet i søgeboksen.
Hvis vi indlægger søgning på delstreng, samt flere match der skal kunne vælges imellem, så kan det laves sådan:
Private Sub Command1_Click()
Dim sFind As String Dim i As Integer, j As Integer, k As Integer Dim iMatchName() As Integer Dim iMatchMobilnr() As Integer Dim iMatchTotal() As Integer Dim bExist As Boolean
ReDim iMatchName(0) ReDim iMatchMobilnr(0) sFind = LCase(Me.Text1.Text) 'konverteres til små bogstaver for at ensrette For i = 1 To Me.ListView1.ListItems.Count 'søg i alle items If InStr(1, LCase(Me.ListView1.ListItems(i).Text), sFind, vbTextCompare) > 0 Then j = j + 1 ReDim Preserve iMatchName(j) iMatchName(j) = i End If If InStr(1, LCase(Me.ListView1.ListItems(i).SubItems(1)), sFind, vbTextCompare) > 0 Then k = k + 1 ReDim Preserve iMatchMobilnr(k) iMatchMobilnr(k) = i End If Next i 'Vi har nu to lister over index der matcher i ListView1: 'først speciel tilfælde med mobilnr uden match: If IsNumeric(sFind) Then 'hvis det var et nummer der blev søgt på If UBound(iMatchMobilnr) = 0 Then 'og der ikke var nogen match Me.ListView2.ListItems.Add Me.ListView2.ListItems.Count + 1, , "Ukendt Mobilnr" Me.ListView2.ListItems(Me.ListView2.ListItems.Count).SubItems(1) = sFind End If End If 'De to lister lægges sammen (uden gengangere): ReDim iMatchTotal(0) If UBound(iMatchName) > 0 Then ReDim iMatchTotal(UBound(iMatchName)) For i = 1 To UBound(iMatchName) iMatchTotal(i) = iMatchName(i) Next i End If If UBound(iMatchMobilnr) > 0 Then If UBound(iMatchTotal) > 0 Then For i = 1 To UBound(iMatchMobilnr) bExist = False For j = 1 To UBound(iMatchTotal) If iMatchMobilnr(i) = iMatchTotal(j) Then bExist = True Exit For End If Next j If Not bExist Then ReDim Preserve iMatchTotal(UBound(iMatchTotal) + 1) iMatchTotal(UBound(iMatchTotal)) = iMatchMobilnr(i) End If Next i Else ReDim iMatchTotal(UBound(iMatchMobilnr)) For i = 1 To UBound(iMatchMobilnr) iMatchTotal(i) = iMatchMobilnr(i) Next i End If End If If UBound(iMatchTotal) = 0 Then Exit Sub 'matches skrives til ListView2: If UBound(iMatchTotal) = 1 Then '1 match: Me.ListView2.ListItems.Add Me.ListView2.ListItems.Count + 1, , Me.ListView1.ListItems(iMatchTotal(1)).Text Me.ListView2.ListItems(Me.ListView2.ListItems.Count).SubItems(1) = _ Me.ListView1.ListItems(iMatchTotal(1)).SubItems(1) Else 'hvis flere matches så indlæs posterne i ListView3 på Form2: For i = 1 To UBound(iMatchTotal) Form2.ListView3.ListItems.Add i, , Me.ListView1.ListItems(iMatchTotal(i)).Text Form2.Refresh Form2.ListView3.ListItems(i).SubItems(1) = CStr(Me.ListView1.ListItems(iMatchTotal(i)).SubItems(1)) Next i Form2.Show vbModal End If
End Sub
Udover dette skal der laves noget kode i Form2, der vælger den rette post og tilføjer den til ListView2 i Form1, og derefter lukker Form2. Derudover kan du også sortere diverse ListViews.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.