Avatar billede leasing Nybegynder
14. januar 2008 - 08:39 Der 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.
Avatar billede tjacob Juniormester
14. januar 2008 - 11:32 #1
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
Avatar billede tjacob Juniormester
14. januar 2008 - 11:39 #2
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"
Avatar billede leasing Nybegynder
14. januar 2008 - 12:29 #3
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.
Avatar billede tjacob Juniormester
14. januar 2008 - 15:42 #4
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"?
Avatar billede leasing Nybegynder
14. januar 2008 - 18:06 #5
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.

Håber det er til at forstå.
Avatar billede leasing Nybegynder
14. januar 2008 - 21:36 #6
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.
Avatar billede tjacob Juniormester
15. januar 2008 - 12:07 #7
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.
Avatar billede leasing Nybegynder
18. januar 2008 - 11:47 #8
Undskyld jeg ikke svare før nu.
Det virker jo perfekt...tusind tak.
Gider du svare så du kan få point.
Avatar billede tjacob Juniormester
19. januar 2008 - 10:01 #9
OK -svar ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester