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", 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", 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:

 0
 4
 4
 4
 4
 0

 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