Posted by webmaster Guido on July 22, 2008
In Reply to Searching in a ListBox posted by RussCAp12602 on
July 17, 2008
: I have an application that shows a series of input Edit fields, which are combined to form a retrieval key. These consist of LastName, FirstName and MiddleInitial. The key is formed as "LastName, FirstName MiddleInitial" as the fields are entered.
: There is also a ListBox which displays the retrieval keys from a file. What I want to do is search in the ListBox for the retrieval key as it is entered, and highlight the best match so far. The file is maintained in key order.
Let's analyse what the routine should do:
1. From the text of the 3 edit boxes, construct a search-string.
2. Remove the current highlighting from the listbox.
3. Compare the search-string with every item of the listbox. To make the comparison case-insensitive, convert everything to uppercase.
When a match is found, highlight that item and stop searching.
4. Optionally, at the end display a message indicating if a match was found or not.
The trick lies in the smart construction of your search-string, so that also partial matches are found.
For example: suppose that the first listbox item starting with an 'S' is Smith, John T
Then you expect to find this by entering Smith in in Edit1, John in Edit2 and T in Edit3. The search-string should be 'SMITH, JOHN T'
But when you leave Edit3 empty, the search-string should be 'SMITH, JOHN' i.e. without a space after 'JOHN'.
And when you also leave Edit2 empty, you don't want a comma after the text of Edit1. For example, when you enter 'Smi' in Edit1 and nothing in the other two boxes, you expect searching for 'SMI' but not for 'SMI,' because then no item starting with 'Smith' would be found.
A source code example:
procedure TForm1.btnSearchClick(Sender: TObject); var i: integer; SearchString, Item: string; begin // 1. Construct search-string SearchString := UpperCase(Trim(Edit1.Text)); if Length(Trim(Edit2.Text)) > 0 then begin SearchString := SearchString + ', ' + UpperCase(Trim(Edit2.Text)); if Length(Trim(Edit3.Text)) > 0 then SearchString := SearchString + ' ' + UpperCase(Trim(Edit3.Text)); end; // 2. Remove highlighting ListBox1.ItemIndex := -1; // // 3. Search in all ListBox items for i := 0 to ListBox1.Items.Count - 1 do begin Item := UpperCase(ListBox1.Items[i]); // Check if Item starts with SearchString if Pos(SearchString, Item) = 1 then begin ListBox1.ItemIndex := i; // highlight item ListBox1.SetFocus; // (optional) break; // found, so stop searching end; end; // 4. Optional: show a message with the result if ListBox1.ItemIndex >= 0 then Label1.Caption := 'Match found' else Label1.Caption := 'No match'; end;