Christina4485
asked on
Searching through a ListBox for a specific value
Hi there,
I'm trying to figure out a way to search through items in a listbox for a specific word or phrase. I've found a way to do it by using.........
Const LB_FINDSTRING = &H18F
Private Declare Function SendMessageByNum Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, ByVal _
wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
.......but that only works if the user enters exactly what is on the entire line in the listbox.
My listbox contains a concatenation of about 10 different fields from the table, so a few sample lines might look something like this...
34651 - 03/25/2004 - 27 MAIN ROAD - EASTGATE SUBDIVISION - WALTER GOSSE - JANE GOSSE
14387 - 01/15/2004 - 145 SPRUCE STREET - OAK SUBDIVISION - JACK JONES - JUDY JONES
39843 - 09/18/2003 - 8 TOPSAIL ROAD - WOODLANDS SUBDIVISION - JOHN SMITH - BEV SMITH
26349 - 02/13/2004 - 88 CHURCH ROAD - GRANVILLE SUBDIVISION - JIM TATE - MARY WHITE
I want the user to be able to type in a search phrase, for example, JOHN, and have it make the line with the word JOHN in it the selected record.
It will work if JOHN is at the beginning of the line, but not in the middle somewhere.
Do you know if there is a way to do this?
Thanks!
Christy
:-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ps. The way the function works is, that in case there are more than one "John" in the list, it will bring all "John" to the result box.
S
S
I have not tried this but I think it should work.....
Option Explicit
Private Declare Function SendMessagebyString Lib _
"user32" Alias "SendMessageA" (ByVal hWND As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As String) As Long
Private Const LB_FINDSTRINGEXACT = &H1A2
Private Const CB_FINDSTRINGEXACT = &H158
Public Function FindStringinListControl(Li stControl As Object, _
ByVal SearchText As String) As Long
'Input:
'ListControl: List or ComboBox Object
'SearchText: String to Search For
'Returns: ListIndex of Item if found
'or -1 if not found
Dim lHwnd As Long
Dim lMsg As Long
On Error Resume Next
lHwnd = ListControl.hWND
If TypeOf ListControl Is ListBox Then
lMsg = LB_FINDSTRINGEXACT
ElseIf TypeOf ListControl Is ComboBox Then
lMsg = CB_FINDSTRINGEXACT
Else
FindStringinListControl = -1
Exit Function
End If
FindStringinListControl = SendMessagebyString _
(lHwnd, lMsg, -1, SearchText)
End Function
Option Explicit
Private Declare Function SendMessagebyString Lib _
"user32" Alias "SendMessageA" (ByVal hWND As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As String) As Long
Private Const LB_FINDSTRINGEXACT = &H1A2
Private Const CB_FINDSTRINGEXACT = &H158
Public Function FindStringinListControl(Li
ByVal SearchText As String) As Long
'Input:
'ListControl: List or ComboBox Object
'SearchText: String to Search For
'Returns: ListIndex of Item if found
'or -1 if not found
Dim lHwnd As Long
Dim lMsg As Long
On Error Resume Next
lHwnd = ListControl.hWND
If TypeOf ListControl Is ListBox Then
lMsg = LB_FINDSTRINGEXACT
ElseIf TypeOf ListControl Is ComboBox Then
lMsg = CB_FINDSTRINGEXACT
Else
FindStringinListControl = -1
Exit Function
End If
FindStringinListControl = SendMessagebyString _
(lHwnd, lMsg, -1, SearchText)
End Function
Another good property (though not related to your question) of ListBoxes from Codeguru
By changing the SendMessage Function's "ByVal wParam as Long" to "ByVal wParam as String", we change the search ability from first letter only, to "change-as-we-type" searching.
Here's some example code. Start a new Standard EXE project and add a ListBox (List1) and a TextBox (Text1), then paste in the following code :
option Explicit
'Start a new Standard-EXE project.
'Add a textbox and a listbox control to form 1
'Add the following code to form1:
private Declare Function SendMessage Lib "User32" _
Alias "SendMessageA" (byval _
hWnd as Long, _
byval wMsg as Integer, _
byval wParam as string, _
lParam as Any) as Long
Const LB_FINDSTRING = &H18F
private Sub Form_Load()
With List1
.Clear
.AddItem "RAM"
.AddItem "rams"
.AddItem "RAMBO"
.AddItem "ROM"
.AddItem "Roma"
.AddItem "Rome"
.AddItem "Rommel"
.AddItem "Cache"
.AddItem "Cash"
End With
End Sub
private Sub Text1_Change()
List1.ListIndex = SendMessage(List1.hWnd, LB_FINDSTRING, _
Text1, byval Text1.Text)
End Sub
By changing the SendMessage Function's "ByVal wParam as Long" to "ByVal wParam as String", we change the search ability from first letter only, to "change-as-we-type" searching.
Here's some example code. Start a new Standard EXE project and add a ListBox (List1) and a TextBox (Text1), then paste in the following code :
option Explicit
'Start a new Standard-EXE project.
'Add a textbox and a listbox control to form 1
'Add the following code to form1:
private Declare Function SendMessage Lib "User32" _
Alias "SendMessageA" (byval _
hWnd as Long, _
byval wMsg as Integer, _
byval wParam as string, _
lParam as Any) as Long
Const LB_FINDSTRING = &H18F
private Sub Form_Load()
With List1
.Clear
.AddItem "RAM"
.AddItem "rams"
.AddItem "RAMBO"
.AddItem "ROM"
.AddItem "Roma"
.AddItem "Rome"
.AddItem "Rommel"
.AddItem "Cache"
.AddItem "Cash"
End With
End Sub
private Sub Text1_Change()
List1.ListIndex = SendMessage(List1.hWnd, LB_FINDSTRING, _
Text1, byval Text1.Text)
End Sub
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Pi7 - that works pretty good, thanks!
Only problem is if the user clicks the "find" button again, I need it to go to the next instance of that string in the listbox.
Maybe I'll try changing the code a bit myself.
Any ideas?
Thanks!
Christy
ASKER
Ok, I ended up using ramesh12's answer, and modified it a bit to be able to find consecutive matches.
Pi7 - yours would have worked well to - I think both were equally correct!
Thanks everyone for your help!
Christy
:-)
Private Sub Command1_Click()
Call FindInList("John")
End Sub
Private Sub FindInList(ByVal fnWhat As String)
Dim c As Integer
Text1.Text = ""
For c = 0 To List1.ListCount - 1
If InStr(1, LCase(List1.List(c)), LCase(fnWhat)) > 0 Then
Text1.Text = Text1.Text & List1.List(c) & vbCrLf
End If
Next c
End Sub
S