INSTR function

Purpose:

INSTR searches through a string to locate a substring. If the substring is found, the function returns an integer indicating the position of the beginning of the substring. The search begins by default from the beginning of the string to be searched or, optionally, from a specified start position.

Syntax:

Position = INSTR(MainStr AS STRING, _
                   Match AS STRING  _
               [, Start AS INTEGER] _
     [, CaseSensitivity AS INTEGER])

Return Value:

  • Data type: INTEGER
    Position The location of Match in MainStr. If Match is not found, 0 is returned. If MainStr or Match string is zero length, 0 is returned.

Parameters:

  • Data type: STRING
    MainStr String to be searched for Match.
  • Data type: STRING
    Match Substring to be located in MainStr.
  • Data type: INTEGER
    Start [OPTIONAL] Position in MainStr where to begin search. Default is position one (1).
    INSTR(MainStr, Match)       ' Implicit position: 1   
    INSTR(MainStr, Match, 1)    ' Explicit position: 1  
    INSTR(MainStr, Match, 1, 1) ' Explicit position: 1
    
    👉 If the Start argument has a value of zero (0) then INSTR will return a Position value of zero (0).
  • Data type: INTEGER
    CaseSensitivity [OPTIONAL] Default is 0 which is case sensitive. Set to 1 for case insensitive search.

IINSTR function

Purpose:

IINSTR searches, case-insensitively, through a string to locate a substring. If the substring is found, the function returns an integer indicating the position of the beginning of the substring. The search begins by default from the beginning of the string to be searched or, optionally, from a specified start position.

Syntax:

Position = IINSTR(MainStr AS STRING, _
                    Match AS STRING  _
                [, Start AS INTEGER])

Return Value:

  • Data type: INTEGER
    Position The location of Match in MainStr. If Match is not found, 0 is returned. If MainStr or Match string is zero length, 0 is returned.

Parameters:

  • Data type: STRING
    MainStr String to be searched for Match.
  • Data type: STRING
    Match Substring to be located in MainStr.
  • Data type: INTEGER
    Start [OPTIONAL] Position in MainStr where to begin search. Default is position one (1).
    IINSTR(MainStr, Match)       ' Implicit position: 1   
    IINSTR(MainStr, Match, 1)    ' Explicit position: 1  
    IINSTR(MainStr, Match, 1, 1) ' Explicit position: 1
    
    👉 If the Start argument has a value of zero (0) then IINSTR will return a Position value of zero (0).

Example:

PRINT INSTR  ("ABCDEFGHIJ", "DEF")        ' Result = 4 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 0)     ' Result = 0 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 1)     ' Result = 4 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 2)     ' Result = 4 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 3)     ' Result = 4 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 4)     ' Result = 4 
PRINT INSTR  ("ABCDEFGHIJ", "DEF", 5)     ' Result = 0 
?
PRINT IINSTR  ("ABCDEFGHIJ", "DEF")       ' Result = 4 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 0)    ' Result = 0 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 1)    ' Result = 4 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 2)    ' Result = 4 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 3)    ' Result = 4 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 4)    ' Result = 4 
PRINT IINSTR  ("ABCDEFGHIJ", "DEF", 5)    ' Result = 0 
?
PRINT INSTR  ("abcdefg", ANY "fbc")     ' Result: 2   implicit position 1 
PRINT IINSTR ("ABCDEFG", ANY "fbc")     ' Result: 2   implicit position 1 
?
PRINT INSTR  ("abcdefg", ANY "fbc", 1)  ' Result: 2   explicit position 1 
PRINT IINSTR ("ABCDEFG", ANY "fbc", 1)  ' Result: 2   explicit position 1 
?
PRINT INSTR("ABCDE", "C")       ' Result: 3 -- Implicit Position 1  
PRINT INSTR("ABCDE", "C", 1)    ' Result: 3 -- Explicit Position 1 
PRINT INSTR("ABCDE", "C", 1, 1) ' Result: 3 -- Explicit Position 1, Case-Insensitive 
?
PRINT INSTR("ABCDE", "C", 0)    ' Result: 0 -- Explicit Position zero 
PRINT INSTR("ABCDE", "C", 0, 1) ' Result: 0 -- Explicit Position zero, Case-Insensitive 
?
PRINT INSTR ("ABCDeF", ANY "1234C5")       ' Result: 3 
PRINT INSTR ("ABCDeF", ANY "1234C5", 2)    ' Result: 3 
PRINT INSTR ("ABCDeF", ANY "1234C5", 3)    ' Result: 3 
PRINT INSTR ("ABCDeF", ANY "1234C5", 4)    ' Result: 0 
?
PRINT IINSTR ("abcDeF", ANY "1234C5")      ' Result: 3 
PRINT IINSTR ("abcDeF", ANY "1234C5", 2)   ' Result: 3 
PRINT IINSTR ("abcDeF", ANY "1234C5", 3)   ' Result: 3 
PRINT IINSTR ("abcDeF", ANY "1234C5", 4)   ' Result: 0 
?
PRINT INSTR ("ABCDeF", "C")                ' Result: 3 
PRINT INSTR ("ABCDeF", "C", 2)             ' Result: 3 
PRINT INSTR ("ABCDeF", "C", 3)             ' Result: 3 
PRINT INSTR ("ABCDeF", "C", 4)             ' Result: 0 
?
PRINT IINSTR ("abcDeF", "C")               ' Result: 3 
PRINT IINSTR ("abcDeF", "C", 2)            ' Result: 3 
PRINT IINSTR ("abcDeF", "C", 3)            ' Result: 3 
PRINT IINSTR ("abcDeF", "C", 4)            ' Result: 0 
 
PAUSE

Result:

4
0
4
4
4
4
0

4
0
4
4
4
4
0

2
2

2
2

3
3
3

0
0

3
3
3
0

3
3
3
0

3
3
3
0

3
3
3
0

Press any key to continue . . .

BCX Console Sample Programs using the INSTR function.


INSTRANY function

Purpose:

The INSTRANY function code copies the CharSet string, removes duplicates from and qsorts, in ascending order, that copy, and then searches through MainStr to locate the first instance of any character in the processed copy of CharSet. If a character is found, the function returns an integer indicating the position of the character. The search begins by default from the beginning of the string to be searched or, optionally, from a specified Start position.

Syntax:

Position = INSTRANY(MainStr AS STRING, _
                    CharSet AS STRING  _
                  [, Start AS INTEGER])

Return Value:

  • Data type: STRING
    Position If found, the position of the first of any character in CharSet. If no character is found, 0 is returned.

Parameters:

  • Data type: STRING
    MainStr String to be searched for any character in CharSet.
  • Data type: STRING
    CharSet String of characters, each of which is to be searched for in MainStr.
  • Data type: INTEGER
    Start [OPTIONAL] Position in MainStr where to begin search. Default is position zero.

IINSTRANY function

Purpose:

The IINSTRANY function code copies the CharSet string, removes duplicates from and qsorts, in ascending order, that copy, and then searches, case-insensitively, through MainStr to locate the first instance of any character in the processed copy of CharSet. If a character is found, the function returns an integer indicating the position of the character. The search begins by default from the beginning of the string to be searched or, optionally, from a specified Start position.

Syntax:

Position = IINSTRANY(MainStr AS STRING, _
                     CharSet AS STRING  _
                   [, Start AS INTEGER])

Return Value:

  • Data type: STRING
    Position If found, the position of the first of any character in CharSet. If no character is found, 0 is returned.

Parameters:

  • Data type: STRING
    MainStr String to be searched for any character in CharSet.
  • Data type: STRING
    CharSet String of characters, each of which is to be searched for in MainStr.
  • Data type: INTEGER
    Start [OPTIONAL] Position in MainStr where to begin search. Default is position zero.

Example:

PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 0)  ' Result = 0 
PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 1)  ' Result = 4 
PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 2)  ' Result = 4 
PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 3)  ' Result = 4 
PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 4)  ' Result = 4 
PRINT INSTRANY  ("ABCDEFGHIJ", "DEF", 5)  ' Result = 5 
?
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 0) ' Result = 0 
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 1) ' Result = 4 
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 2) ' Result = 4 
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 3) ' Result = 4 
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 4) ' Result = 4 
PRINT IINSTRANY  ("ABCDEFGHIJ", "DEF", 5) ' Result = 5 
?
PRINT INSTRANY ("ABCDeF", "1234C5")        ' Result: 3 
PRINT INSTRANY ("ABCDeF", "1234C5", 2)     ' Result: 3 
PRINT INSTRANY ("ABCDeF", "1234C5", 3)     ' Result: 3 
PRINT INSTRANY ("ABCDeF", "1234C5", 4)     ' Result: 0 
?
PRINT IINSTRANY ("abcDeF", "1234C5")       ' Result: 3 
PRINT IINSTRANY ("abcDeF", "1234C5", 2)    ' Result: 3 
PRINT IINSTRANY ("abcDeF", "1234C5", 3)    ' Result: 3 
PRINT IINSTRANY ("abcDeF", "1234C5", 4)    ' Result: 0 
?
PRINT INSTRANY  ("abcdefg", "fbc")      ' Result: 2   implicit position 1 
PRINT IINSTRANY ("ABCDEFG", "fbc")      ' Result: 2   implicit position 1 
?
PRINT INSTRANY  ("abcdefg", "fbc", 1)   ' Result: 2   explicit position 1 
PRINT IINSTRANY ("ABCDEFG", "fbc", 1)   ' Result: 2   explicit position 1 

PAUSE

Result:

 0
 4
 4
 4
 4
 5

 0
 4
 4
 4
 4
 5

 3
 3
 3
 0

 3
 3
 3
 0

 2
 2

 2
 2

Press any key to continue . . .

INSTRREV function

Purpose:

INSTRREV searches backwards through a string to locate a substring. If the substring is found, the function returns an integer indicating the position of the beginning of the substring. The search begins by default from the end of the string to be searched or, optionally, from a specified start position.

Syntax:

Position = INSTRREV(MainStr AS STRING, _
                      Match AS STRING  _
                  [, Start AS INTEGER] _
        [, CaseSensitivity AS INTEGER])

Return Value:

  • Data type: INTEGER
    Position The location of Match in MainStr. If Match is not found, 0 is returned. If MainStr or Match string is zero length, 0 is also returned.
    👉 The return value, Position, is measured from the beginning of the string.

Parameters:

  • Data type: STRING
    MainStr String to be searched for Match.
  • Data type: STRING
    Match Substring to be located in MainStr.
  • Data type: INTEGER
    Start [OPTIONAL] Position in MainStr where to begin search. Default is the string length of MainStr. When a Start position is specified, text to the right of the Start position will not be considered in the search.
  • Data type: INTEGER
    CaseSensitivity [OPTIONAL] Set to 1 for case insensitive search. Default is 0 which is case sensitive.

Example 1:

DIM Position%
Position% = INSTRREV("12345abc67890", "abc")
PRINT Position%

Result:

6

Example 2:

DIM int1%
DIM str1$, str2$

PRINT ""
PRINT "Example 1 demonstrates two parameter INSTRREV"
PRINT "looks for last backslash "
str1$ = "I:\like\this\one\better\bob.exe"
PRINT str1$
str2$ = MID$(str1$, 1, INSTRREV(str1$, "\"))
PRINT str2$
PRINT ""

PRINT "Example 2 demonstrates three parameter INSTRREV"
str1$ = "12345678XXX23456XXX0"
PRINT ""
PRINT "Start looking backwards from position 12 for XXX"
PRINT "in string 12345678XXX23456XXX0"
int1% = INSTRREV(str1$, "XXX", 12)
PRINT int1%; " result should be 9"
PRINT ""

PRINT "Start looking backwards from position 20 for XXX"
PRINT "in string 12345678XXX23456XXX0"
int1% = INSTRREV(str1$, "XXX", 20)
PRINT int1%; " result should be 17"
PRINT ""
'             XXX changed to XYY.
str1$ = "12345678XYY23456XXX0"
PRINT ""
PRINT "Start looking backwards from position 12 for XXX"
PRINT "in string 12345678XYY23456XXX0"
int1% = INSTRREV(str1$, "XXX", 12)
PRINT int1; " result should be 0"

Result:

Example 1 demonstrates two parameter INSTRREV
looks for last backslash
I:\like\this\one\better\bob.exe
I:\like\this\one\better\

Example 2 demonstrates three parameter INSTRREV

Start looking backwards from position 12 for XXX
in string 12345678XXX23456XXX0
 9 result should be 9

Start looking backwards from position 20 for XXX
in string 12345678XXX23456XXX0
 17 result should be 17


Start looking backwards from position 12 for XXX
in string 12345678XYY23456XXX0
 0 result should be 0

INCHR function

Purpose:

INCHR returns the position where the single character Matchar$ is located in MainStr. INCHR is approximately four times faster than INSTR.

Syntax:

Position = INCHR(MainStr AS STRING, _
                 Matchar AS STRING)

Return Value:

  • Data type: INTEGER
    Position position where Matchar is located in MainStr. The first position is 1.

Parameters:

  • Data type: STRING
    MainStr String to be searched for Matchar character.
  • Data type: STRING
    Matchar Character to be located in MainStr. Matchar must be a single character.

Example:

DIM AS STRING TheString
TheString = "0123456789"
DIM AS INTEGER ThePosition
DIM AS STRING TheChar

FOR INTEGER TheLoop = 0 TO 9
  TheChar$ = CHR$(TheLoop + 48)
  ThePosition = INCHR(TheString, TheChar$)
  PRINT "TheChar, ", TheChar, ", is at ThePosition ", ThePosition, " in TheString"
NEXT TheLoop

PAUSE

Result:

TheChar, 0, is at ThePosition  1 in TheString
TheChar, 1, is at ThePosition  2 in TheString
TheChar, 2, is at ThePosition  3 in TheString
TheChar, 3, is at ThePosition  4 in TheString
TheChar, 4, is at ThePosition  5 in TheString
TheChar, 5, is at ThePosition  6 in TheString
TheChar, 6, is at ThePosition  7 in TheString
TheChar, 7, is at ThePosition  8 in TheString
TheChar, 8, is at ThePosition  9 in TheString
TheChar, 9, is at ThePosition  10 in TheString

Press any key to continue . . .

CONTAINEDIN function

Purpose:

CONTAINEDIN searches for a string in a string array.

Syntax:

RetVal = CONTAINEDIN(Match AS STRING, _
               MainArray[] AS STRING  _
            [, Comparison AS INTEGER])

Return Value:

  • Data type: INTEGER
    RetVal Default returns 0 if found, -1 if not found. See table below in the Comparison parameter description for other return values.

Parameters:

  • Data type: STRING
    Match String to be located in MainArray.
  • Data type: STRING
    MainArray Array of strings.
    👉 The last string in the array must be set to "". The example below shows how to SET the array.
  • Data type: INTEGER
    Comparison [OPTIONAL] method of comparison used during search. The default method is 0 which is case sensitive. The following table describes the options for the Comparison parameter argument and the expected value returned in RetVal.
    0 - case sensitive   returns 0 if found -1 if not found
    1 - case insensitive returns 0 if found -1 if not found
    2 - case sensitive   returns i if found -1 if not found
    3 - case insensitive returns i if found -1 if not found
    
    i will represent the number of the MainArray element
      in which the string was located.
    

Example:

SET CN[] AS CHAR PTR
  "&",
  ",",
  ":",
  "+",
  "-",
  "*",
  "/",
  "^",
  ";",
  "=",
  "<",
  ">",
  "THEN",
  ""
END SET

DIM c1, c2
DIM i
DIM x
DIM y
DIM Stk$[128]
DIM Ndx
DIM A$

A$ = "if x = 1 then y = y + 1 : if y > 10 THEN y = 0"
PRINT A$
CALL TinyParse(A$, " ")

c1 = 0
c2 = 0
FOR i = 0 TO Ndx
  x = CONTAINEDIN(Stk$[i], CN, 1)
  IF x <> -1 THEN
    PRINT "Token "; i; " in A$ "; Stk$[i]; " ";
    y = CONTAINEDIN(Stk$[i], CN)
    IF y <> -1 THEN
      PRINT " exact match"
      c2++
    ELSE
      PRINT " match with case difference"
    END IF
    c1++
  END IF
NEXT
PRINT "A total of"; c1; " tokens, regardless of case, in CN[] where found in A$,"; c2; " were exact matches"
PAUSE
c1 = 0
c2 = 0
FOR i = 0 TO Ndx
  x = CONTAINEDIN(Stk$[i], CN, 3)
  IF x <> -1 THEN
    PRINT "the"; i; "th token in A$ "; Stk$[i]; " ";
    y = CONTAINEDIN(Stk$[i], CN, 2)
    IF y <> -1 THEN
      PRINT " exact match of the"; y; "th token in CN[] "; CN$[y]
      c2++
    ELSE
      PRINT " match with case difference of the"; x; "th token in CN[] "; CN$[x]
    END IF
    c1++
  END IF
NEXT

PAUSE

SUB TinyParse (A$, Delim$)
  DIM RAW TB$
  DIM RAW Sep
  DIM STATIC ii
  Ndx = 0
  TB$ = ""
  Sep = INCHR(A$, Delim$)
  IF Sep > 0 THEN
    IF Sep > 1 THEN
      TB$ = LEFT$(A$, Sep - 1)
      Stk$[ii] = TB$
      ii++
    END IF
    A$ = MID$(A$, Sep + 1)
    TinyParse(A$, Delim$)
  ELSE
    Stk$[ii] = A$
    Stk$[ii+1] = ""
    Ndx = ii
    ii = 0
  END IF
END SUB

Result:

if x = 1 then y = y + 1 : if y > 10 THEN y = 0
Token  2 in A$ =  exact match
Token  4 in A$ then  match with case difference
Token  6 in A$ =  exact match
Token  8 in A$ +  exact match
Token  10 in A$ :  exact match
Token  13 in A$ >  exact match
Token  15 in A$ THEN  exact match
Token  17 in A$ =  exact match
A total of 8 tokens, regardless of case, in CN[] where found in A$, 7 were exact matches

FINDINTYPE function

Purpose:

FINDINTYPE searches for a string in a type array. FINDINTYPE is modeled after the CONTAINEDIN function. The main differences in FINDINTYPE are:

Syntax:

RetVal = FINDINTYPE(Match AS STRING, _
             Type.element AS STRING, _
               RangeFrom AS INTEGER, _
                 RangeTo AS INTEGER  _
           [, Comparison AS INTEGER] _
                [, Index AS INTEGER])

Return Value:

  • Data type: INTEGER
    RetVal Default returns 0 if found, -1 if not found. See table below in the Comparison parameter description for other return values.

Parameters:

  • Data type: STRING
    Match String to be located in Type.element of array.
  • Data type: STRING
    Type.element Type array element to be searched.
  • Data type: INTEGER
    RangeFrom Beginning of range of records to be searched.
  • Data type: INTEGER
    RangeTo End of range of records to be searched.
  • Data type: INTEGER
    Comparison [OPTIONAL] method of comparison used during search. The default method is 0 which is case sensitive. The following table describes the options for the Comparison argument and the expected value returned in RetVal
    0 - case sensitive   returns 0 if found -1 if not found
    1 - case insensitive returns 0 if found -1 if not found
    2 - case sensitive   returns i if found -1 if not found
    3 - case insensitive returns i if found -1 if not found
    
    i will represent the number of the MainArray element
      in which the string was located.
    
  • Data type: INTEGER
    Index [OPTIONAL] An index array can be given to return the string position found in relation to the index.

Example:

This demo shows hows to sort by pointer instead of using a separate index and uses FINDINTYPE to find a search term in a TYPE.

This is an image produced by the example code below.

Click here to extract testdata.zip
which contains the database for the below FINDINTYPE example. Unzip it to the same directory as the compiled example code.

$BCXVERSION "5.05.153"
$GENFREE

GUI "PtrSortDemo", PIXELS

GLOBAL Form1 AS CONTROL
GLOBAL Listview1 AS CONTROL
GLOBAL Label1 AS CONTROL
GLOBAL Label2 AS CONTROL

CONST   IDC_Listview1 = 1002

TYPE MyRecord
  Last[50] AS CHAR
  First[50] AS CHAR
  Address[100] AS CHAR
  City[100] AS CHAR
  State[30] AS CHAR
  Zip
END TYPE

SUB FORMLOAD()

  GLOBAL DYNAMIC Addr[5001] AS MyRecord

  Form1 = BCX_FORM("Pointer Sort Find in Type Demonstration", 103, 82, 700, 600)
  Listview1 = BCX_LISTVIEW("Listview1", Form1, IDC_Listview1, 0, 36, 700, 530)
  Label1    = BCX_LABEL("", Form1, 0,  10, 6, 250, 24)
  Label2    = BCX_LABEL("", Form1, 0, 260, 6, 400, 24)
  BCX_SET_FONT Label1, "VERDANA", 12
  BCX_SET_FONT Label2, "VERDANA", 12

  CENTER(Form1)
  SHOW(Form1)

  CALL Loaddata()
  CALL Setup_Listview1()

END SUB

BEGIN EVENTS
  SELECT CASE CBMSG

    '---------------------------
   CASE WM_NOTIFY
    '---------------------------
     STATIC fname$
    RAW pnmlv AS NM_LISTVIEW PTR, col
    IF LOWORD(wParam) = IDC_Listview1 THEN
      pnmlv = (NM_LISTVIEW *)lParam
      IF pnmlv->hdr.code = LVN_COLUMNCLICK THEN
        col = pnmlv->iSubItem
        Display(col)
      END IF

      IF pnmlv->hdr.code = NM_DBLCLK THEN
        ListView_GetItemText(Listview1, pnmlv->iItem, pnmlv->iSubItem, fname$, 2047)
        Countfield(fname$, pnmlv->iSubItem)
      END IF
    END IF

    '---------------------------
   CASE WM_CLOSE
    '---------------------------
     IF MSGBOX("Are you sure?", "Quit Program!", MB_YESNO) = IDYES THEN
      CALL FREEGLOBALS
      DestroyWindow(Form1)
    END IF
    EXIT FUNCTION

  END SELECT
END EVENTS

SUB Loaddata ()

  DOEVENTS

  RAW FileName$, dat$, buffer$[10]

  FileName$ = "testdata.txt"
  IF NOT EXIST(FileName$) THEN
    MSGBOX " TestData.txt not found - aborting"
    PostQuitMessage(0)
  END IF

  OPEN FileName$ FOR INPUT AS hFile


  FOR INTEGER i = 0 to 5000
    DOEVENTS
    LINE INPUT hFile,dat$

    SPLIT(buffer$, dat$, ",")
    WITH Addr[i]
      .Last$    = buffer$[0]
      .First$   = buffer$[1]
      .Address$ = buffer$[2]
      .City$    = buffer$[3]
      .State$   = buffer$[4]
      .Zip      = VAL(buffer$[5])
    END WITH
  NEXT
  CLOSE

END SUB


'---------------------------------------------------------------
 SUB Setup_Listview1 ()

  For integer i = 14 to 0 step -1
    ListView_DeleteColumn(Listview1,i)
  NEXT
  ' Set up ListView columns
   LOCAL LVC AS LV_COLUMN


  LVC.mask = LVCF_FMT OR LVCF_TEXT OR LVCF_WIDTH OR LVCF_SUBITEM
  LVC.pszText = "Last"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 125
  LVC.iSubItem = 0
  SendMessage(Listview1, LVM_INSERTCOLUMN, 0, &LVC)

  LVC.pszText = "First"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 125
  LVC.iSubItem = 1
  SendMessage(Listview1, LVM_INSERTCOLUMN, 1, &LVC)

  LVC.pszText = "Address"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 150
  LVC.iSubItem = 2
  SendMessage(Listview1, LVM_INSERTCOLUMN, 2, &LVC)

  LVC.pszText = "City"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 150
  LVC.iSubItem = 3
  SendMessage(Listview1, LVM_INSERTCOLUMN, 3, &LVC)

  LVC.pszText = "State"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 50
  LVC.iSubItem = 4
  SendMessage(Listview1, LVM_INSERTCOLUMN, 4, &LVC)

  LVC.pszText = "Zip"
  LVC.fmt = LVCFMT_LEFT
  LVC.cx = 50
  LVC.iSubItem = 5
  SendMessage(Listview1, LVM_INSERTCOLUMN, 5, &LVC)

  DOEVENTS

  Display(0)

END SUB

SUB Display (field)

  RAW start AS DWORD
  start = GetTickCount()

  SELECT CASE field
  CASE 0
    QSortIdx 0, 5001, Addr.Last, 0
  CASE 1
    QSortIdx 0, 5001, Addr.First, 0
  CASE 2
    QSortIdx 0, 5001, Addr.Address, 0
  CASE 3
    QSortIdx 0, 5001, Addr.City, 0
  CASE 4
    QSortIdx 0, 5001, Addr.State, 0
  CASE 5
    QSortIdx 0, 5001, Addr.Zip, 1
  END SELECT

  BCX_SET_TEXT Label1,"Sort took" + STR$(GetTickCount() - start) + " milliseconds!"
  BCX_SET_TEXT Label2,"Double click on data entry to FINDINTYPE"

  SendMessage(Listview1, WM_SETREDRAW, FALSE, 0)
  ListView_DeleteAllItems(Listview1)
  DOEVENTS
  ListView_SetItemCount(Listview1, 5001)', 0x00000001)  'LVSICF_NOINVALIDATEALL
   LOCAL lvItem AS LV_ITEM

  lvItem.mask = LVIF_TEXT
  lvItem.cchTextMax = 255

  FOR integer lv1 = 5000 to 0 STEP -1
    DOEVENTS
    lvItem.pszText = (LPSTR)Addr[lv1].Last 'Last
     lvItem.iSubItem = 0 'col
     ListView_InsertItem(Listview1, &lvItem)

    lvItem.pszText = (LPSTR)Addr[lv1].First 'First
     lvItem.iSubItem = 1 'col
     ListView_SetItem(Listview1, &lvItem)

    lvItem.pszText = (LPSTR)Addr[lv1].Address 'Address
     lvItem.iSubItem = 2 'col
     ListView_SetItem(Listview1, &lvItem)

    lvItem.pszText = (LPSTR)Addr[lv1].City 'City
     lvItem.iSubItem = 3 'col
     ListView_SetItem(Listview1, &lvItem)

    lvItem.pszText = (LPSTR)Addr[lv1].State 'State
     lvItem.iSubItem = 4 'col
     ListView_SetItem(Listview1, &lvItem)

    lvItem.pszText = (LPSTR)STR$(Addr[lv1].Zip) 'Zip
     lvItem.iSubItem = 5 'col
     ListView_SetItem(Listview1, &lvItem)

  NEXT lv1
  SendMessage(Listview1, WM_SETREDRAW, TRUE, 0)
  InvalidateRect(Listview1, NULL, FALSE)

END SUB

SUB Countfield (fname$, field)

  DIM RAW count = 0, StartPos = 0

  DO
    IF field = 0 THEN
      StartPos = FINDINTYPE(fname$, Addr.Last$, StartPos, 5000, 3)
    ELSEIF field = 1 THEN
      StartPos = FINDINTYPE(fname$, Addr.First$, StartPos, 5000, 3)
    ELSEIF field = 2 THEN
      StartPos = FINDINTYPE(fname$, Addr.Address$, StartPos, 5000, 3)
    ELSEIF field = 3 THEN
      StartPos = FINDINTYPE(fname$, Addr.City$, StartPos, 5000, 3)
    ELSEIF field = 4 THEN
      StartPos = FINDINTYPE(fname$, Addr.State$, StartPos, 5000, 3)
    ELSE
      EXIT SUB
    END IF
    IF StartPos = -1 THEN EXIT DO
    INCR count
    INCR StartPos
  LOOP

  BCX_SET_TEXT Label2,"Found" + STR$(count) + " occurrences of " + fname$
  BCX_SET_TEXT Label1,"Click column header to sort."

END SUB