home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_code2 / v_browse / brw001m.bas < prev    next >
BASIC Source File  |  1993-09-20  |  76KB  |  1,628 lines

  1. Global ngBRWFormTxtInstances  As Integer
  2. Global ngCurrListIdx          As Integer
  3. Global ngLBXBrowserDispItems  As Integer
  4. Global ngLBXBrowserFirstRow   As Integer
  5. Global ngLBXBrowserLastRow    As Integer
  6. Global ngLBXBrowserNumOfRows  As Integer
  7. Global ngLBXBrowserValue      As Integer
  8. Global ngIgnoreTblsClick      As Integer
  9. Global ngIgnoreVSRChangeEvent As Integer
  10. Global ngJETRowNumber         As Integer
  11. Global ngViewJETFlag          As Integer
  12.  
  13. Global Const BRW_ADD_ABOVE_FLAG = -100
  14. Global Const BRW_ADD_BELOW_FLAG = -101
  15. Global Const BRW_BACKWARD_DIRECTION = -1
  16. Global Const BRW_ERROR = -99
  17. Global Const BRW_FORWARD_DIRECTION = 1
  18. Global Const BRW_MOVE_FIRST = 22
  19. Global Const BRW_MOVE_FROM_BOF_POS = 1
  20. Global Const BRW_MOVE_FROM_CURR_POS = 2
  21. Global Const BRW_MOVE_FROM_EOF_POS = 3
  22. Global Const BRW_MOVE_FROM_UNKNOWN = 0
  23. Global Const BRW_RETURN_FIRST_LISTINDEX = -200
  24. Global Const BRW_RETURN_LAST_LISTINDEX = -201
  25. Global Const BRW_RETURN_SPECIFIED_LISTINDEX = -202
  26. Global Const BRW_SUCCESSFUL = -1
  27. Global Const BRW_UNSUCCESSFUL = -2001
  28. Global Const BRW_VISIBLE_LISTBOX_ITEMS = 10
  29. Global Const DEFAULT_ICON = 0
  30. Global Const HOURGLASS_ICON = 11
  31. Global Const WM_SETREDRAW = &HB
  32.  
  33. Declare Function GetFocus Lib "User" () As Integer
  34. Declare Function SendMessage Lib "User" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long
  35.  
  36. Function BRW001FclbTblsClick% (nIndex%)
  37. Dim nCols%
  38. Dim nFirstRow%
  39. Dim nFunctRetVal%
  40. Dim nNumOfRows%
  41. Dim nRetIdxTypeFlag%
  42. Dim nRetVal%
  43. Dim szMDBTblName$
  44. On Error GoTo BRW001FclbTblsClickErr
  45. ngIgnoreTblsClick = True
  46. BRW001F.lbxBrowser.Clear
  47. BRW001F.lbxBrowser.Enabled = False
  48. BRW001F.pbtNext.Enabled = False
  49. BRW001F.pbtPrevious.Enabled = False
  50. BRW001F.pbtPageUp.Enabled = False
  51. BRW001F.pbtPageDn.Enabled = False
  52. BRW001F.vsrBrowser.Enabled = False
  53. BRW001F.picData.Visible = False
  54. BRW001F.pbtViewJET.Caption = "View &JET"
  55. BRW001F.pbtViewJET.Enabled = False
  56. ngViewJETFlag = False
  57. ngIgnoreVSRChangeEvent = True
  58. BRW001F.vsrBrowser.Value = 1
  59. BRW001F.lblRowNum.Caption = Str$(BRW001F.vsrBrowser.Value)
  60. ngIgnoreVSRChangeEvent = False
  61. szMDBTblName$ = BRW001F.clbTbls.List(nIndex%)
  62. nCols% = fntGetMDBTblNames%(szMDBTblName$)
  63. If (nCols% = False) Then
  64.    '-------------------------------------------------------------------------
  65.    ' NOTE-> number of COLUMNS is ZERO...
  66.    '-------------------------------------------------------------------------
  67.    szMsg$ = "WARNING-> " + szMDBTblName$ + " has NO COLUMNS..."
  68.    MsgBox szMsg$
  69.    ngIgnoreTblsClick = False
  70.    nFunctRetVal% = False
  71.    BRW001FclbTblsClick% = nFunctRetVal%
  72.    Exit Function
  73. End If
  74. ' JDE-> If (ngBRWFormTxtInstances > 1) Then
  75. ' JDE->    nRetVal% = fntUnloadTxtDataInstances%()
  76. ' JDE->End If
  77. nRetVal% = fntLoadTxtDataInstances%(nCols%)
  78. '----------------------------------------------------------------------------
  79. ' NOTE-> get the record count for the table...
  80. '        requires a MoveLast and a MoveFirst...
  81. '----------------------------------------------------------------------------
  82. BRW001F.datJET.RecordSource = szMDBTblName$
  83. BRW001F.datJET.Refresh
  84. If ((BRW001F.datJET.Recordset.BOF = True) And (BRW001F.datJET.Recordset.EOF = True)) Then
  85.    '-------------------------------------------------------------------------
  86.    ' NOTE-> EMPTY TABLE...so INFORM the user about this...and EXIT...
  87.    '-------------------------------------------------------------------------
  88.    szMsg$ = "WARNING-> " + szMDBTblName$ + " is EMPTY..."
  89.    MsgBox szMsg$
  90.    ngIgnoreTblsClick = False
  91.    Exit Function
  92. End If
  93. BRW001F.datJET.Recordset.MoveLast
  94. BRW001F.datJET.Recordset.MoveFirst
  95. nTblRecCount% = BRW001F.datJET.Recordset.RecordCount
  96. ngJETRowNumber = 1
  97. BRW001F.vsrBrowser.Min = 1
  98. BRW001F.vsrBrowser.Max = nTblRecCount%
  99. ngLBXBrowserDispItems = BRW_VISIBLE_LISTBOX_ITEMS
  100. '----------------------------------------------------------------------------
  101. ' NOTE-> load virtual listbox with first (ngLBXBrowserDispItems * 3) rows...
  102. '----------------------------------------------------------------------------
  103. nFirstRow% = 1
  104. nNumOfRows% = ngLBXBrowserDispItems * 3
  105. nRetIdxTypeFlag% = BRW_RETURN_FIRST_LISTINDEX
  106. nRetVal% = fntLoadBrowserLB%(nFirstRow%, nNumOfRows%, nRetIdxTypeFlag%, nValue%)
  107. BRW001F.lblRowNum.Caption = Str$(BRW001F.vsrBrowser.Value)
  108. BRW001F.clbTbls.SetFocus
  109. nFunctRetVal% = True
  110. BRW001FclbTblsClick% = nFunctRetVal%
  111. ngIgnoreTblsClick = False
  112. BRW001F.lbxBrowser.Enabled = True
  113. BRW001F.pbtNext.Enabled = True
  114. BRW001F.pbtPrevious.Enabled = True
  115. BRW001F.pbtPageUp.Enabled = True
  116. BRW001F.pbtPageDn.Enabled = True
  117. BRW001F.vsrBrowser.Enabled = True
  118. BRW001F.pbtViewJET.Caption = "View &JET"
  119. BRW001F.pbtViewJET.Enabled = True
  120. Exit Function
  121. BRW001FclbTblsClickErr:
  122.    szMsg$ = "ERROR-> " + Error$
  123.    MsgBox szMsg$
  124.    ngIgnoreTblsClick = False
  125.    Exit Function
  126. BRW001FclbTblsClickExit:
  127.    BRW001FclbTblsClick% = False
  128. End Function
  129.  
  130. Function BRW001FpbtExitClick% ()
  131. Dim nFunctRetVal%
  132. Unload BRW001F
  133. End Function
  134.  
  135. Function BRW001FvsrBrowserChange% (nValue%)
  136. Dim nAboveRow%
  137. Dim nAddListIdx%
  138. Dim nBelowRow%
  139. Dim nCount%
  140. Dim nDelta%
  141. Dim nEnd%
  142. Dim nFirstRow%
  143. Dim nFunctRetVal%
  144. Dim nItemsInBlock%
  145. Dim nJETCurrPosToFirstRow%
  146. Dim nJETFirstRow%
  147. Dim nJETLastRow%
  148. Dim nLastBrowserRow%
  149. Dim nLCount%
  150. Dim nListCount%
  151. Dim nNearEOF%
  152. Dim nNumOfRows%
  153. Dim nNewIdx%
  154. Dim nRecCount%
  155. Dim nRedraw%
  156. Dim nRetVal%
  157. Dim nRowsUntilEOF%
  158. Dim nStart%
  159. Dim nSteps%
  160. Dim nVSRMax%
  161. nRedraw% = 1
  162. If (nValue% = ngLBXBrowserValue) Then
  163.    nFunctRetVal% = True
  164.    BRW001FvsrBrowserChange% = nFunctRetVal%
  165.    Exit Function
  166. End If
  167. If (ngIgnoreVSRChangeEvent = True) Then
  168.    nFunctRetVal% = True
  169.    BRW001FvsrBrowserChange% = nFunctRetVal%
  170.    Exit Function
  171. End If
  172.  
  173. nCount% = BRW001F.lbxBrowser.ListCount
  174. If (nCount% < 1) Then
  175.    nFunctRetVal% = False
  176.    BRW001FvsrBrowserChange% = nFunctRetVal%
  177.    Exit Function
  178. End If
  179. nListCount% = nCount% - 1
  180. '----------------------------------------------------------------------------
  181. ' NOTE-> the general +idea+ is that the dynaset is read via the datJET
  182. '        control +only+ when rows are +not+ in the browser listbox...
  183. '        so...we keep track of which rows are currently loaded into the
  184. '        listbox...when necessary we add more rows to the listbox, but we
  185. '        can also remove rows from the listbox (so that it does not contain
  186. '        a large amount of data at any given time)...
  187. '        using ngLBXBrowserFirstRow and ngLBXBrowserLastRow, we can determine
  188. '        whether the row data for the +new+ TOP item in the listbox is
  189. '        already loaded into the listbox...in that case, we need to determine
  190. '        the listbox index corresponding to that particular row's data...
  191. '        when that is done, we can set the listbox's ListIndex property to
  192. '        move that item to the top of the visible portion of the listbox...
  193. '        the next concern is whether there are enough rows +following+ the
  194. '        one that is now at the top of the listbox to completely fill the
  195. '        visible portion of the listbox...this is where the first and last
  196. '        loaded row global variables are necessary...if there are not enough
  197. '        rows already loaded to fill the listbox, then we get a few more
  198. '        rows and add them to the listbox...
  199. '----------------------------------------------------------------------------
  200. ' NEXT-> at this point, we could stop and everything would work correctly
  201. '        but the number of items in the listbox would eventually increase to
  202. '        the point at which +all+ of the rows from the datJET dynaset were
  203. '        loaded into the listbox...not such a problem for a few hundred rows,
  204. '        but the +key+ to this virtual browser is the fact that it only
  205. '        contains and displays a small +subset+ of the dynaset controlled by
  206. '        datJET...so, we have to provide an algorithm for removing row data
  207. '        from the listbox...in this case, there are also several
  208. '        considerations...one approach is to load a few more rows initially
  209. '        than the listbox can display in its visible portion, and then unload
  210. '        as many rows as we need to load whenever rows are loaded...as we
  211. '        load and unload rows from the listbox, it is important not to unload
  212. '        too many rows...the general idea is to keep the listbox in the
  213. '        middle of its items and to limit the total number of items in the
  214. '        listbox to (perhaps) three times the number of items that can be
  215. '        displayed at any time...this gives us a buffered set of rows that
  216. '        can be scrolled...one way to accomplish this is to calculate how
  217. '        many items will be above the +new+ TOP item, and if there are more
  218. '        of them than some fixed constant amount, then remove them and adjust
  219. '        all of our global positioning variables...similarly, as we unload
  220. '        those items, we can load an equal amount...that will most likely
  221. '        solve the problem of maintaining enough rows beneath the +new+ TOP
  222. '        row to fill the listbox...there are two special cases: (1) BOF and
  223. '        (2) EOF for datJET...in other words, we cannot unload rows above
  224. '        the first row--because there are +none+ to unload, and we cannot
  225. '        unload rows beneath the last row...
  226. '----------------------------------------------------------------------------
  227. If ((nValue% >= ngLBXBrowserFirstRow) And (nValue% <= ngLBXBrowserLastRow)) Then
  228.    '-------------------------------------------------------------------------
  229.    ' NOTE-> ROW to position at TOP of lbxBrowser is already loaded...
  230.    '-------------------------------------------------------------------------
  231.    nNewIdx% = nValue% - ngLBXBrowserFirstRow
  232.    If ((nNewIdx% > nListCount%) Or (nNewIdx% < 0)) Then
  233.       nFunctRetVal% = False
  234.       BRW001FvsrBrowserChange% = nFunctRetVal%
  235.       Exit Function
  236.    End If
  237.    ngLBXBrowserValue = nValue%
  238.    '-------------------------------------------------------------------------
  239.    ' NOTE-> do we need to get more ROWS...
  240.    '        ngLBXBrowserDispItems contains the number of +visible+ items the
  241.    '        listbox can display...so if nDelta% is a greater than 0 we need
  242.    '        to load more rows...
  243.    '-------------------------------------------------------------------------
  244.    nDelta% = ngLBXBrowserDispItems - (ngLBXBrowserLastRow - ngLBXBrowserValue)
  245.    If (nDelta% > 0) Then
  246.       '----------------------------------------------------------------------
  247.       ' NOTE-> need to get nDelta% more ROWS from datJET...
  248.       '        and add to lbxBrowser...
  249.       '----------------------------------------------------------------------
  250.       nNumOfRows% = nDelta%
  251.       nAddListIdx% = nListCount% + 1
  252.       nJETLastRow% = ngLBXBrowserLastRow
  253.       '----------------------------------------------------------------------
  254.       ' NOTE-> fntAddMoreBrowserRows%() will cause ngLBXBrowserLastRow to
  255.       '        change...
  256.       '----------------------------------------------------------------------
  257.       ' REDRAW-> nRedraw% = 0
  258.       ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  259.       nRetVal% = fntAddMoreBrowserRows%(nNumOfRows%, nAddListIdx%, nJETLastRow%)
  260.       '----------------------------------------------------------------------
  261.       ' NOTE-> since we just added a few items...we can also remove a few
  262.       '        items...observing that removing items will +change+ the value
  263.       '        that represents the ListIndex property for the +new+ item...
  264.       '----------------------------------------------------------------------
  265.       ' NOTE-> fntRemSomeBrowserRows%() will cause ngLBXBrowserFirstRow to
  266.       '        change...
  267.       '----------------------------------------------------------------------
  268.       ' NOTE-> we need to adjust nNewIdx% +because+ we are removing from the
  269.       '        +top+ of the listbox...
  270.       '----------------------------------------------------------------------
  271.       ' NOTE->      nDelta% => number of items to remove from end of listbox...
  272.       '            nNewIdx% => current value for nNewIdx%...
  273.       '        nJETLastRow% => ROW number of LAST LOADED ROW...
  274.       '----------------------------------------------------------------------
  275.       ' NOTE-> fntRemSomeBrowserRows%() returns the +new+ nNewIdx% value or
  276.       '        a negative error code...
  277.       '----------------------------------------------------------------------
  278.       nJETLastRow% = ngLBXBrowserLastRow
  279.       nItemsInBlock% = (ngLBXBrowserDispItems * 3)
  280.       nRecCount% = BRW001F.vsrBrowser.Max
  281.       nRowsUntilEOF% = nRecCount% - nJETLastRow%
  282.       nLCount% = BRW001F.lbxBrowser.ListCount
  283.       
  284.       If ((nRowsUntilEOF% <= nItemsInBlock%) And (nLCount% < (nItemsInBlock% + 1))) Then
  285.          '-------------------------------------------------------------------
  286.          ' NOTE-> since we did not ADD any ITEMS...we should not REMOVE any...
  287.          '        otherwise...the number of items in the listbox will
  288.          '        decrease too much...the idea is to always have
  289.          '        (ngLBXBrowserDispItems * 3) items in a block--except when
  290.          '        the dynaset has fewer than that many items (TOTAL)...
  291.          '-------------------------------------------------------------------
  292.       Else
  293.          '-------------------------------------------------------------------
  294.          ' NOTE-> there are so +many+ possibilities that we might as well
  295.          '        be a bit careful...
  296.          '-------------------------------------------------------------------
  297.          nCount% = BRW001F.lbxBrowser.ListCount
  298.          nExtraLBXItems% = nCount% - nItemsInBlock%
  299.          If (nDelta% > nExtraLBXItems%) Then
  300.             nDelta% = nExtraLBXItems%
  301.          End If
  302.          nRetVal% = fntRemSomeBrowserRows%(nDelta%, nNewIdx%, nJETLastRow%)
  303.          If (nRetVal% < 0) Then
  304.              '---------------------------------------------------------------
  305.              ' NOTE-> an error occurred...
  306.              '---------------------------------------------------------------
  307.              nFunctRetVal% = nRetVal%
  308.              BRW001FvsrBrowserChange% = nFunctRetVal%
  309.              ' REDRAW-> If (nRedraw% = 0) Then
  310.              ' REDRAW->    nRedraw% = 1
  311.              ' REDRAW->    lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  312.              ' REDRAW-> End If
  313.              Exit Function
  314.          Else
  315.             nNewIdx% = nRetVal%
  316.          End If
  317.       End If
  318.    End If
  319.    ngCurrListIdx = nNewIdx%
  320.    BRW001F.lbxBrowser.ListIndex = nNewIdx%
  321.    ' REDRAW-> If (nRedraw% = 0) Then
  322.    ' REDRAW->    nRedraw% = 1
  323.    ' REDRAW->    lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  324.    ' REDRAW-> End If
  325. Else
  326.    '-------------------------------------------------------------------------
  327.    ' NOTE-> ROW to position at TOP of lbxBrowser is NOT loaded...
  328.    '-------------------------------------------------------------------------
  329.    ' ((nValue% >= ngLBXBrowserFirstRow) And (nValue% <= ngLBXBrowserLastRow)) Then
  330.    '-------------------------------------------------------------------------
  331.    ' NOTE-> since the vsrBrowser vertical scrollbar is set so that its
  332.    '        +minimum+ value is the first row in the dynaset, we do not have
  333.    '        to be concerned with nValue% being +negative+...so...one very
  334.    '        simple approach is just to remove as many items as we add...
  335.    '        within the constraints of the special cases (i.e., BOF and EOF)...
  336.    '-------------------------------------------------------------------------
  337.    ' NOTE-> since the ROW to position at TOP of lbxBrowser is NOT loaded,
  338.    '        we may as well clear the listbox and reload it so that there are
  339.    '        a convenient number of rows +above+ and +below+ the item that is
  340.    '        going to be the TOP of the listbox...
  341.    '-------------------------------------------------------------------------
  342.    nNearEOF% = BRW001F.vsrBrowser.Max - ngLBXBrowserDispItems
  343.    nFuzzyZone% = nValue% - ngLBXBrowserValue
  344.    If (nValue% >= nNearEOF%) Then
  345.       If ((nValue% = BRW001F.vsrBrowser.Max) And (nFuzzyZone% = 1)) Then
  346.          GoTo 1
  347.       End If
  348.       '----------------------------------------------------------------------
  349.       '             > > > +near+ datJET.Recordset.EOF < < <
  350.       '----------------------------------------------------------------------
  351.       ' NOTE-> the second special case occurs when nValue% is within
  352.       '        ngLBXBrowserDispItems of datJET.Recordset.EOF (a.k.a. the
  353.       '        vsrBrowser.Max value)...in which case we can do a
  354.       '        datJET.Recordset.MoveLast, lbxBrowser.Clear, and
  355.       '        then do (ngLBXBrowserDispItems * 3) datJET.Recordset.MovePrev
  356.       '        commands and lbxBrowser.AddItem each row +but+ in +reverse+
  357.       '        order because we are reading backwards...
  358.       '----------------------------------------------------------------------
  359.       ' REDRAW-> nRedraw% = 0
  360.       ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  361.       nRetVal% = fntLoadLastBlock%(nValue%)
  362.       If (nRetVal% = False) Then
  363.          '-------------------------------------------------------------------
  364.          ' NOTE-> some unusual ERROR probably occurred...
  365.          '-------------------------------------------------------------------
  366.          nFunctRetVal% = nRetVal%
  367.          BRW001FvsrBrowserChange% = nFunctRetVal%
  368.          ' REDRAW-> nRedraw% = 1
  369.          ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  370.          Exit Function
  371.       End If
  372.       ' REDRAW-> nRedraw% = 1
  373.       ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  374.    Else
  375. 1 :
  376.       '----------------------------------------------------------------------
  377.       ' NOTE-> this is the more +general+ case in which nValue% is either
  378.       '        +above+ or +below+ our currently loaded group of rows...
  379.       '        but is not the special case (i.e., within
  380.       '        ngLBXBrowserDispItems rows from datJET.Recordset.BOF)...
  381.       '----------------------------------------------------------------------
  382.       ' NOTE-> (perhaps) the +best+ way to solve this general problem is
  383.       '        to determine how far forward or backward we are moving...
  384.       '        if we are moving less than ngLBXBrowserDispItems from
  385.       '        the TOP or BOTTOM of the currently loaded subset of ROWS
  386.       '        from datJET.Recordset, the it is probably most efficient
  387.       '        to add and remove just the number of ROWS necessary to get
  388.       '        the desired ROW into +view+ at the TOP or BOTTOM of the
  389.       '        listbox...otherwise, we are probably responding to a PageUP
  390.       '        or PageDN type of vsrBrowser scrollbar movement and may as
  391.       '        well do a lbxBrowser.Clear and reload the listbox with
  392.       '        (ngLBXBrowserDispItems * 3) items...
  393.       '----------------------------------------------------------------------
  394.       nAboveRow% = ngLBXBrowserFirstRow - ngLBXBrowserDispItems
  395.       nBelowRow% = ngLBXBrowserLastRow + ngLBXBrowserDispItems
  396.       If ((nValue% >= nAboveRow%) And (nValue% <= nBelowRow%)) Then
  397.          '-------------------------------------------------------------------
  398.          ' NOTE-> all we need to do is ADD and REMOVE an equal number of
  399.          '        items so we can scroll the nValue% ROW into view...
  400.          '-------------------------------------------------------------------
  401.          ' NOTE-> nNewIdx% will be changed by this process...so be sure to
  402.          '        adjust it...
  403.          '-------------------------------------------------------------------
  404.          If (nValue% < ngLBXBrowserFirstRow) Then
  405.             nDelta% = ngLBXBrowserFirstRow - nValue%
  406.             nAddToListLocFlag% = BRW_ADD_ABOVE_FLAG
  407.          Else
  408.             nDelta% = nValue% - ngLBXBrowserLastRow
  409.             nAddToListLocFlag% = BRW_ADD_BELOW_FLAG
  410.          End If
  411.          nJETFirstRow% = ngLBXBrowserFirstRow
  412.          nJETLastRow% = ngLBXBrowserLastRow
  413.          '-------------------------------------------------------------------
  414.          ' NOTE-> fntAdjDeltaBrowserItems% returns the +new+ ListIndex
  415.          '        value or a negative error code...
  416.          '-------------------------------------------------------------------
  417.          ' NOTE->            nDelta% => the number of rows to adjust...
  418.          '        nAddToListLocFlag% => where to AddItem(s)...
  419.          '                   nValue% => the current vsrBrowser scrollbar VALUE...
  420.          '             nJETFirstRow% => the beginning ROW number of the subset...
  421.          '              nJETLastRow% => the ending ROW number of the subset...
  422.          '-------------------------------------------------------------------
  423.          ' REDRAW-> nRedraw% = 0
  424.          ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  425.          nRetVal% = fntAdjDeltaBrowserItems%(nDelta%, nAddToListLocFlag%, nValue%, nJETFirstRow%, nJETLastRow%)
  426.          If (nRetVal% = BRW_ERROR) Then
  427.             '----------------------------------------------------------------
  428.             ' NOTE-> an error occurred...
  429.             '----------------------------------------------------------------
  430.             nFunctRetVal% = nRetVal%
  431.             BRW001FvsrBrowserChange% = nFunctRetVal%
  432.             ' REDRAW-> nRedraw% = 1
  433.             ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  434.             Exit Function
  435.          Else
  436.             nNewIdx% = nRetVal%
  437.             ngCurrListIdx = nNewIdx%
  438.             BRW001F.lbxBrowser.ListIndex = nNewIdx%
  439.          End If
  440.          ' REDRAW-> nRedraw% = 1
  441.          ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  442.          If (ngJETRowNumber = 1) Then
  443.             '----------------------------------------------------------------
  444.             ' NOTE-> we are are at the TOP of the dynaset...
  445.             '        and our logic for traversing it at this point is
  446.             '        based upon the way things are after we load the first
  447.             '        SUBSET of ROWS into the LISTBOX...and this is nearly
  448.             '        an identical STATE--EXCEPT for the fact that datJET
  449.             '        is currently positioned at the BEGINNING of the SUBSET
  450.             '        rather than at the END (where it SHOULD BE)...
  451.             '        so...we want to make this otherwise unusual case
  452.             '        appear to be the NORMAL case...and the way to do that
  453.             '        is to POSITION datJET at the END of the SUBSET of ROWS...
  454.             '        rather an UNUSUAL thing to do...but it WORKS...
  455.             '----------------------------------------------------------------
  456.             nStart% = 2   ' NOTE-> datJET is ALREADY on the first record...
  457.             nJETCurrPosToFirstRow% = ngLBXBrowserDispItems * 3
  458.             nVSRMax% = BRW001F.vsrBrowser.Max
  459.             If (nJETCurrPosToFirstRow% > nVSRMax%) Then
  460.                nJETCurrPosToFirstRow% = nVSRMax%
  461.             End If
  462.             nEnd% = nJETCurrPosToFirstRow%
  463.             For nSteps% = nStart% To nEnd%
  464.                BRW001F.datJET.Recordset.MoveNext
  465.                ngJETRowNumber = ngJETRowNumber + 1
  466.             Next nSteps%
  467.          End If
  468.       Else
  469.          '-------------------------------------------------------------------
  470.          ' NOTE-> we may as well do a zap the listbox contents and
  471.          '        reload (ngLBXBrowserDispItems * 3) items because we are
  472.          '        here as a result of a change in vsrBrowser.Value that
  473.          '        is greater than ngLBXBrowserDispItems...so there are
  474.          '        several ways to +predict+ the most efficient way to
  475.          '        reload the listbox...if the user is scrolling upward
  476.          '        then the +smart+ thing is to load with all +upward+
  477.          '        rows and set the ListIndex to the +bottom+ of the
  478.          '        listbox...similarly, if the user is scrolling downward
  479.          '        then the +smart+ thing is to load with all +downward+
  480.          '        rows and set the ListIndex to the +top+ of the
  481.          '        listbox...the problem with +predicting+ this way is it
  482.          '        may not be accurate...however, it is a good place to
  483.          '        begin experimentation with browser +behaviors+...
  484.          '-------------------------------------------------------------------
  485.          ' NOTE-> nNewIdx% will be changed by this process...so be sure to
  486.          '        adjust it...
  487.          '-------------------------------------------------------------------
  488.          '                  > > > WHY WE ARE HERE < < <
  489.          '-------------------------------------------------------------------
  490.          '    nAboveRow% = ngLBXBrowserFirstRow - ngLBXBrowserDispItems
  491.          '    nBelowRow% = ngLBXBrowserLastRow + ngLBXBrowserDispItems
  492.          '-------------------------------------------------------------------
  493.          ' THIS IS TRUE-> (nValue% < nAboveRow%) Or (nValue% > nBelowRow%)
  494.          '-------------------------------------------------------------------
  495.          If (nValue% < ngLBXBrowserFirstRow) Then
  496.             '----------------------------------------------------------------
  497.             ' NOTE-> we +predict+ the user is scrolling UPWARDS...
  498.             '----------------------------------------------------------------
  499.             nRetIdxTypeFlag% = BRW_RETURN_FIRST_LISTINDEX
  500.             nFirstRow% = nValue%
  501.             nNumOfRows% = ngLBXBrowserDispItems * 3
  502.             ' REDRAW-> nRedraw% = 0
  503.             ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  504.             nRetVal% = fntLoadBrowserLB%(nFirstRow%, nNumOfRows%, nRetIdxTypeFlag%, nValue%)
  505.             ' REDRAW-> nRedraw% = 1
  506.             ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  507.          Else
  508.             If (nValue% > ngLBXBrowserLastRow) Then
  509.                '-------------------------------------------------------------
  510.                ' NOTE-> we +predict+ the user is scrolling DOWNWARDS...
  511.                '-------------------------------------------------------------
  512.                nRetIdxTypeFlag% = BRW_RETURN_SPECIFIED_LISTINDEX
  513.                nFirstRow% = nValue%
  514.                nNumOfRows% = ngLBXBrowserDispItems * 3
  515.                ' REDRAW-> nRedraw% = 0
  516.                ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  517.                nRetVal% = fntLoadBrowserLB%(nFirstRow%, nNumOfRows%, nRetIdxTypeFlag%, nValue%)
  518.                ' REDRAW-> nRedraw% = 1
  519.                ' REDRAW-> lRetVal& = SendMessage(BRW001F.lbxBrowser.hWnd, WM_SETREDRAW, nRedraw%, ByVal 0&)
  520.             Else
  521.                '-------------------------------------------------------------
  522.                ' NOTE-> we +predict+ this should NEVER occur (g)...
  523.                '-------------------------------------------------------------
  524.             End If
  525.          End If
  526.       End If
  527.    End If
  528. End If
  529. BRW001FvsrBrowserChange% = nFunctRetVal%
  530. End Function
  531.  
  532. Function fntAddMoreBrowserRows% (nNumOfRows%, nAddListIdx%, nJETLastRow%)
  533. Dim nFunctRetVal%
  534. Dim nCols%
  535. Dim nEnd%
  536. Dim nEOF%
  537. Dim nIdx%
  538. Dim nListCols%
  539. Dim nRowsAdded%
  540. Dim nRowIdx%
  541. Dim nStart%
  542. Dim nVSRMax%
  543. Dim szLBStr$
  544. Dim szTxt$
  545. On Error GoTo fntAddMoreBrowserRowsErr
  546. '----------------------------------------------------------------------------
  547. ' NOTE-> do NOT attempt to add more ROWS if we are already at the LAST ROW...
  548. '----------------------------------------------------------------------------
  549. nMaxValue% = BRW001F.vsrBrowser.Max
  550. If ((ngLBXBrowserLastRow = nMaxValue%) And (ngJETRowNumber = nMaxValue%)) Then
  551.    nFunctRetVal% = True
  552.    fntAddMoreBrowserRows% = nFunctRetVal%
  553.    Exit Function
  554. End If
  555. nCols% = BRW001F.clbCols.ListCount
  556. If (nCols% < 1) Then
  557.    nFunctRetVal% = False
  558.    fntAddMoreBrowserRows% = nFunctRetVal%
  559.    Exit Function
  560. End If
  561. nListCols% = nCols% - 1
  562. nRowsAdded% = 0
  563. If (ngLBXBrowserLastRow = nMaxValue%) Then
  564.    nFunctRetVal% = True
  565.    fntAddMoreBrowserRows% = nFunctRetVal%
  566.    Exit Function
  567. End If
  568.  
  569. '----------------------------------------------------------------------------
  570. ' NOTE-> build the lbxBrowser STRING using ALL fields in the TABLE for
  571. '        the CURRENT ROW...
  572. '----------------------------------------------------------------------------
  573. ' WARNING-> the lbxBrowser STRING must be NULL-terminated...
  574. '           this is because VB listbox controls are +really+ Windows
  575. '           listbox controls, and Windows controls know absolutely
  576. '           nothing about VB strings--they only know 'C' strings...
  577. '----------------------------------------------------------------------------
  578. nStart% = nAddListIdx%
  579. nEnd% = nAddListIdx% + (nNumOfRows% - 1)
  580. nOnLastRowExitForEarly% = False
  581. If (ngJETRowNumber < ngLBXBrowserLastRow) Then
  582.    nSteps% = ngLBXBrowserLastRow - ngJETRowNumber
  583.    For nIdx% = 1 To nSteps%
  584.       BRW001F.datJET.Recordset.MoveNext
  585.       ngJETRowNumber = ngJETRowNumber + 1
  586.    Next nIdx%
  587. End If
  588. For nRowIdx% = nStart% To nEnd%
  589.    nVSRMax% = BRW001F.vsrBrowser.Max
  590.    If (ngJETRowNumber = nVSRMax%) Then
  591.       If (nRowIdx% < nEnd%) Then
  592.          nOnLastRowExitForEarly% = True
  593.       End If
  594.       Exit For
  595.    End If
  596.    BRW001F.datJET.Recordset.MoveNext
  597.    ngJETRowNumber = ngJETRowNumber + 1
  598.    nEOF% = BRW001F.datJET.Recordset.EOF
  599.    If (nEOF%) Then
  600.       '----------------------------------------------------------------------
  601.       ' NOTE-> just in case we made a mistake...
  602.       '----------------------------------------------------------------------
  603.       BRW001F.datJET.Recordset.MoveLast
  604.       ngJETRowNumber = ngJETRowNumber - 1
  605.       If (nRowIdx% < nEnd%) Then
  606.          nOnLastRowExitForEarly% = True
  607.       End If
  608.       Exit For
  609.    End If
  610.    szLBStr$ = Space$(1)
  611.    For nIdx% = 0 To nListCols%
  612.       szTxt$ = BRW001F.txtData(nIdx%).Text
  613.       lTxtLen& = Len(szTxt$)
  614.       szType$ = BRW001F.clbTypes.List(nIdx%)
  615.       nBeginParen% = InStr(1, szType$, "(")
  616.       nStart% = nBeginParen% + 1
  617.       nEndParen% = InStr(nStart%, szType$, ")")
  618.       nLen% = nEndParen% - nStart%
  619.       szLen$ = Mid$(szType$, nStart%, nLen%)
  620.       lMaxTxtLen& = Val(szLen$)
  621.       lDeltaLen& = lMaxTxtLen& - lTxtLen&
  622.       szLBStr$ = szLBStr$ + szTxt$ + Space$(2)
  623.       If (lDeltaLen& > 0) Then
  624.          szLBStr$ = szLBStr$ + Space$(lDeltaLen&)
  625.       End If
  626.    Next nIdx%
  627.    szLBStr$ = szLBStr$ + Chr$(0)
  628.    BRW001F.lbxBrowser.AddItem szLBStr$
  629.    nRowsAdded% = nRowsAdded% + 1
  630. Next nRowIdx%
  631. ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows + nRowsAdded%
  632. ngLBXBrowserLastRow = ngLBXBrowserFirstRow + (ngLBXBrowserNumOfRows - 1)
  633. nFunctRetVal% = True
  634. fntAddMoreBrowserRows% = nFunctRetVal%
  635. Exit Function
  636. fntAddMoreBrowserRowsErr:
  637.    Resume Next
  638. fntAddMoreBrowserRowsExit:
  639.    fntAddMoreBrowserRows% = True
  640. End Function
  641.  
  642. Function fntAdjDeltaBrowserItems% (nDelta%, nAddToListLocFlag%, nValue%, nJETFirstRow%, nJETLastRow%)
  643. Dim nBOF%
  644. Dim nCols%
  645. Dim nEnd%
  646. Dim nEOF%
  647. Dim nFirstIdx%
  648. Dim nFunctRetVal%
  649. Dim nIdx%
  650. Dim nLastIdx%
  651. Dim nListCols%
  652. Dim nListCount%
  653. Dim nNewIdx%
  654. Dim nOnLastRowExitForEarly%
  655. Dim nRetVal%
  656. Dim nRowsAdded%
  657. Dim nStart%
  658. Dim nSteps%
  659. Dim szLBStr$
  660. Dim szTxt$
  661. On Error GoTo fntAdjDeltaBrowserItemsErr
  662. '----------------------------------------------------------------------------
  663. ' RETURNS-> 1. if (SUCCESSFUL)   -> BRW_SUCCESSFUL
  664. '           2. if (UNSUCCESSFUL) -> BRW_ERROR
  665. '----------------------------------------------------------------------------
  666. ' NOTE-> this function adds a few rows to one end of the listbox and then
  667. '        removes an equal number of rows from the opposite end of the
  668. '        listbox...
  669. '----------------------------------------------------------------------------
  670. ' RETURNS-> 1. if (SUCCESSFUL)   -> the +new+ ListIndex
  671. '           2. if (UNSUCCESSFUL) -> a negative error code...
  672. '----------------------------------------------------------------------------
  673. ' LOGIC-> we know on which record number datJET is currently positioned
  674. '         (i.e., ngJETRowNumber), and we know all of the +stuff+ sent to
  675. '         us via the function parameters...
  676. '         and we are reasonably sure that we can read forward or backwards
  677. '         as many ROWS as we need to read or we probably would not be in
  678. '         this routine...
  679. '         so the general idea is first to ADD the new ITEMS (to whichever
  680. '         end the parameter [i.e., nAddToListLocFlag%] indicates), and then
  681. '         to REMOVE the unnecessary +extra+ ITEMS...
  682. '----------------------------------------------------------------------------
  683. ' NOTE->            nDelta% => the number of rows to adjust...
  684. '        nAddToListLocFlag% => where to AddItem(s)...(TOP or BOTTOM)
  685. '                   nValue% => the CURRENT VALUE of BRW001F.vsrBrowser...
  686. '             nJETFirstRow% => the beginning ROW number of the subset...
  687. '              nJETLastRow% => the ending ROW number of the subset...
  688. '----------------------------------------------------------------------------
  689. If (nAddToListLocFlag% = BRW_ADD_ABOVE_FLAG) Then
  690.    '-------------------------------------------------------------------------
  691.    ' NOTE-> BRW_ADD_ABOVE_FLAG
  692.    '-------------------------------------------------------------------------
  693.    If (ngJETRowNumber > nJETFirstRow%) Then
  694.       '----------------------------------------------------------------------
  695.       ' NOTE-> we need to MovePrevious to get to the first row to ADD...
  696.       '----------------------------------------------------------------------
  697.       nSteps% = ngJETRowNumber - nJETFirstRow%
  698.       '----------------------------------------------------------------------
  699.       ' NOTE-> we begin the FOR LOOP with 0...
  700.       '----------------------------------------------------------------------
  701.       For nIdx% = 0 To nSteps%
  702.          BRW001F.datJET.Recordset.MovePrevious
  703.          ngJETRowNumber = ngJETRowNumber - 1
  704.       Next nIdx%
  705.       '----------------------------------------------------------------------
  706.       ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  707.       '----------------------------------------------------------------------
  708.    Else
  709.       If (ngJETRowNumber < nJETFirstRow%) Then
  710.          '-------------------------------------------------------------------
  711.          ' NOTE-> we need to MoveNext to get to the first row to ADD...
  712.          '-------------------------------------------------------------------
  713.          nSteps% = nJETFirstRow% - ngJETRowNumber
  714.          '-------------------------------------------------------------------
  715.          ' NOTE-> we begin the FOR LOOP with 0...
  716.          '-------------------------------------------------------------------
  717.          For nIdx% = 0 To nSteps%
  718.             BRW001F.datJET.Recordset.MoveNext
  719.             ngJETRowNumber = ngJETRowNumber + 1
  720.          Next nIdx%
  721.          '-------------------------------------------------------------------
  722.          ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  723.          '-------------------------------------------------------------------
  724.       Else
  725.          '-------------------------------------------------------------------
  726.          ' NOTE-> we need to MovePrevious ONE ROW to get to the first row
  727.          '        of the subset...and then some amount further to get to
  728.          '        the first record outside of the subset...
  729.          '-------------------------------------------------------------------
  730.          BRW001F.datJET.Recordset.MovePrevious
  731.          ngJETRowNumber = ngJETRowNumber - 1
  732.          '-------------------------------------------------------------------
  733.          ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  734.          '-------------------------------------------------------------------
  735.       End If
  736.    End If
  737. Else
  738.    '-------------------------------------------------------------------------
  739.    ' NOTE-> BRW_ADD_BELOW_FLAG
  740.    '-------------------------------------------------------------------------
  741.    If (ngJETRowNumber > nJETLastRow%) Then
  742.       '----------------------------------------------------------------------
  743.       ' NOTE-> we need to MovePrevious to get to the first row to ADD...
  744.       '----------------------------------------------------------------------
  745.       nSteps% = ngJETRowNumber - nJETLastRow%
  746.       '----------------------------------------------------------------------
  747.       ' NOTE-> we begin the FOR LOOP with 2 rather than 1...
  748.       '----------------------------------------------------------------------
  749.       For nIdx% = 2 To nSteps%
  750.          BRW001F.datJET.Recordset.MovePrevious
  751.          ngJETRowNumber = ngJETRowNumber - 1
  752.       Next nIdx%
  753.       '----------------------------------------------------------------------
  754.       ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  755.       '        we are ADDING to the TOP...so need to be positioned BEFORE...
  756.       '----------------------------------------------------------------------
  757.    Else
  758.       If (ngJETRowNumber < nJETLastRow%) Then
  759.          '-------------------------------------------------------------------
  760.          ' NOTE-> we need to MoveNext to get to the first row to ADD...
  761.          '-------------------------------------------------------------------
  762.          nSteps% = nJETFirstRow% - ngJETRowNumber
  763.          '-------------------------------------------------------------------
  764.          ' NOTE-> we begin the FOR LOOP with 0...
  765.          '-------------------------------------------------------------------
  766.          For nIdx% = 0 To nSteps%
  767.             BRW001F.datJET.Recordset.MoveNext
  768.             ngJETRowNumber = ngJETRowNumber + 1
  769.          Next nIdx%
  770.          '-------------------------------------------------------------------
  771.          ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  772.          '-------------------------------------------------------------------
  773.       Else
  774.          '-------------------------------------------------------------------
  775.          ' NOTE-> we need to MoveNext ONE ROW to get to the first row to ADD...
  776.          '        we are ADDING to the BOTTOM...so need to be positioned AFTER...
  777.          '-------------------------------------------------------------------
  778.          BRW001F.datJET.Recordset.MoveNext
  779.          ngJETRowNumber = ngJETRowNumber + 1
  780.          '-------------------------------------------------------------------
  781.          ' NOTE-> now ngJETRowNumber is +THE+ first ROW to ADD to the listbox...
  782.          '-------------------------------------------------------------------
  783.       End If
  784.    End If
  785. End If
  786. '----------------------------------------------------------------------------
  787. ' NOTE-> at this point datJET is positioned on the FIRST ROW that needs to
  788. '        be ADDED to lbxBrowser...so we (again) need to check to which end we
  789. '        adding to and then do a FOR LOOP and add the ROWS...using
  790. '        MoveNext or MovePrevious as appropriate...
  791. '        also note that adding to the TOP is done by +explicitly+ specifying
  792. '        and INDEX = 0 value on the AddItem method...whereas positioning the
  793. '        listbox on its last item and then doing sequential AddItem methods
  794. '        +without+ specifying an INDEX parameter will append the items...
  795. '        UNLESS we somehow set the listbox SORT property to TRUE--in which
  796. '        case we are quite confused...
  797. '----------------------------------------------------------------------------
  798. ' NOTE->            nDelta% => the number of rows to adjust...
  799. '        nAddToListLocFlag% => where to AddItem(s)...(TOP or BOTTOM)
  800. '                   nValue% => the CURRENT VALUE of BRW001F.vsrBrowser...
  801. '             nJETFirstRow% => the beginning ROW number of the subset...
  802. '              nJETLastRow% => the ending ROW number of the subset...
  803. '----------------------------------------------------------------------------
  804. ' NOTE-> get the number of columns in the COLUMNS combo listbox
  805. '----------------------------------------------------------------------------
  806.    nCols% = BRW001F.clbCols.ListCount
  807. If (nCols% < 1) Then
  808.    nFunctRetVal% = False
  809.    fntAdjDeltaBrowserItems% = nFunctRetVal%
  810.    Exit Function
  811. End If
  812. nListCols% = nCols% - 1
  813. If (nAddToListLocFlag% = BRW_ADD_ABOVE_FLAG) Then
  814.    '-------------------------------------------------------------------------
  815.    ' NOTE-> BRW_ADD_ABOVE_FLAG
  816.    '-------------------------------------------------------------------------
  817.    nStart% = 1
  818.    nEnd% = nDelta%
  819.    nOnLastRowExitForEarly% = False
  820.    For nIdx% = nStart% To nEnd%
  821.       '----------------------------------------------------------------------
  822.       ' NOTE-> build the listbox item STRING...
  823.       '----------------------------------------------------------------------
  824.       szLBStr$ = Space$(1)
  825.       For nCols% = 0 To nListCols%
  826.          szTxt$ = BRW001F.txtData(nCols%).Text
  827.          lTxtLen& = Len(szTxt$)
  828.          szType$ = BRW001F.clbTypes.List(nCols%)
  829.          nBeginParen% = InStr(1, szType$, "(")
  830.          nStart% = nBeginParen% + 1
  831.          nEndParen% = InStr(nStart%, szType$, ")")
  832.          nLen% = nEndParen% - nStart%
  833.          szLen$ = Mid$(szType$, nStart%, nLen%)
  834.          lMaxTxtLen& = Val(szLen$)
  835.          lDeltaLen& = lMaxTxtLen& - lTxtLen&
  836.          szLBStr$ = szLBStr$ + szTxt$ + Space$(2)
  837.          If (lDeltaLen& > 0) Then
  838.             szLBStr$ = szLBStr$ + Space$(lDeltaLen&)
  839.          End If
  840.       Next nCols%
  841.       szLBStr$ = szLBStr$ + Chr$(0)
  842.       '----------------------------------------------------------------------
  843.       ' NOTE-> ADD the item to lbxBrowser...at the TOP...(Index = 0)
  844.       '----------------------------------------------------------------------
  845.       BRW001F.lbxBrowser.AddItem szLBStr$, 0
  846.       ngLBXBrowserValue = nValue%
  847.       ngLBXBrowserFirstRow = ngJETRowNumber
  848.       ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows + 1
  849.       ngLBXBrowserLastRow = ngLBXBrowserFirstRow + (ngLBXBrowserNumOfRows - 1)
  850.       BRW001F.datJET.Recordset.MovePrevious
  851.       ngJETRowNumber = ngJETRowNumber - 1
  852.       nBOF% = BRW001F.datJET.Recordset.BOF
  853.       If (nBOF%) Then
  854.          '-------------------------------------------------------------------
  855.          ' NOTE-> just in case we made a mistake...
  856.          '-------------------------------------------------------------------
  857.          BRW001F.datJET.Recordset.MoveFirst
  858.          ngJETRowNumber = 1
  859.          If (nIdx% < nEnd%) Then
  860.             nOnLastRowExitForEarly% = True
  861.          End If
  862.          Exit For
  863.       End If
  864.    Next nIdx%
  865.    If (nOnLastRowExitForEarly% = True) Then
  866.       '----------------------------------------------------------------------
  867.       ' NOTE-> we were unable to ADD nDelta% ITEMS...so REMOVE only the
  868.       '        number of ITEMS we actually ADDED...
  869.       '----------------------------------------------------------------------
  870.       nRowsAdded% = nStart%
  871.    Else
  872.       nRowsAdded% = nDelta%
  873.    End If
  874. Else
  875.    '-------------------------------------------------------------------------
  876.    ' NOTE-> BRW_ADD_BELOW_FLAG
  877.    '-------------------------------------------------------------------------
  878.    nStart% = 1
  879.    nEnd% = nDelta%
  880.    nOnLastRowExitForEarly% = False
  881.    For nIdx% = nStart% To nEnd%
  882.       '----------------------------------------------------------------------
  883.       ' NOTE-> build the listbox item STRING...
  884.       '----------------------------------------------------------------------
  885.       szLBStr$ = Space$(1)
  886.       For nCols% = 0 To nListCols%
  887.          szTxt$ = BRW001F.txtData(nCols%).Text
  888.          lTxtLen& = Len(szTxt$)
  889.          szType$ = BRW001F.clbTypes.List(nCols%)
  890.          nBeginParen% = InStr(1, szType$, "(")
  891.          nStart% = nBeginParen% + 1
  892.          nEndParen% = InStr(nStart%, szType$, ")")
  893.          nLen% = nEndParen% - nStart%
  894.          szLen$ = Mid$(szType$, nStart%, nLen%)
  895.          lMaxTxtLen& = Val(szLen$)
  896.          lDeltaLen& = lMaxTxtLen& - lTxtLen&
  897.          szLBStr$ = szLBStr$ + szTxt$ + Space$(2)
  898.          If (lDeltaLen& > 0) Then
  899.             szLBStr$ = szLBStr$ + Space$(lDeltaLen&)
  900.          End If
  901.       Next nCols%
  902.       szLBStr$ = szLBStr$ + Chr$(0)
  903.       '----------------------------------------------------------------------
  904.       ' NOTE-> ADD the item to lbxBrowser...at the BOTTOM...
  905.       '----------------------------------------------------------------------
  906.       ' CAUTION-> it is VERY IMPORTANT that the Sort property of lbxBrowser
  907.       '           be False...this means that the listbox is NOT SORTED...
  908.       '           furthermore it means that by NOT SPECIFYING AN INDEX VALUE
  909.       '           for the AddItem method, the ITEM will be added to the
  910.       '           END of the listbox...
  911.       '----------------------------------------------------------------------
  912.       BRW001F.lbxBrowser.AddItem szLBStr$
  913.       ngLBXBrowserValue = nValue%
  914.       ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows + 1
  915.       ngLBXBrowserLastRow = ngJETRowNumber
  916.       BRW001F.datJET.Recordset.MoveNext
  917.       nEOF% = BRW001F.datJET.Recordset.EOF
  918.       ngJETRowNumber = ngJETRowNumber + 1
  919.       If (nEOF%) Then
  920.          '-------------------------------------------------------------------
  921.          ' NOTE-> just in case we made a mistake...
  922.          '-------------------------------------------------------------------
  923.          BRW001F.datJET.Recordset.MoveLast
  924.          ngJETRowNumber = ngJETRowNumber - 1
  925.          If (nIdx% < nEnd%) Then
  926.             nOnLastRowExitForEarly% = True
  927.          End If
  928.          Exit For
  929.       End If
  930.    Next nIdx%
  931.    If (nOnLastRowExitForEarly% = True) Then
  932.       '----------------------------------------------------------------------
  933.       ' NOTE-> we were unable to ADD nDelta% ITEMS...so REMOVE only the
  934.       '        number of ITEMS we actually ADDED...
  935.       '----------------------------------------------------------------------
  936.       nRowsAdded% = nStart%
  937.    Else
  938.       nRowsAdded% = nDelta%
  939.    End If
  940. End If
  941. '----------------------------------------------------------------------------
  942. ' NOTE-> at this point we have ADDED nRowsAdded% ITEMS to lbxBrowser...
  943. '        so we need to REMOVE nRowsAdded% ITEMS from lbxBrowser...
  944. '----------------------------------------------------------------------------
  945. ' NOTE->            nDelta% => the number of rows to adjust...
  946. '        nAddToListLocFlag% => where to AddItem(s)...(TOP or BOTTOM)
  947. '                   nValue% => the CURRENT VALUE of BRW001F.vsrBrowser...
  948. '             nJETFirstRow% => the beginning ROW number of the subset...
  949. '              nJETLastRow% => the ending ROW number of the subset...
  950. '----------------------------------------------------------------------------
  951. If (nAddToListLocFlag% = BRW_ADD_ABOVE_FLAG) Then
  952.    '-------------------------------------------------------------------------
  953.    ' NOTE-> BRW_ADD_ABOVE_FLAG
  954.    '-------------------------------------------------------------------------
  955.    nCount% = BRW001F.lbxBrowser.ListCount
  956.    If (nCount% < 1) Then
  957.       '----------------------------------------------------------------------
  958.       ' NOTE-> listbox is EMPTY...
  959.       '----------------------------------------------------------------------
  960.       nFunctRetVal% = BRW_ERROR
  961.       fntAdjDeltaBrowserItems% = nFunctRetVal%
  962.       Exit Function
  963.    End If
  964.    nListCount% = nCount% - 1
  965.    nLastIdx% = nListCount%
  966.    nStart% = 1
  967.    nEnd% = nRowsAdded%
  968.    For nIdx% = nStart% To nEnd%
  969.       '----------------------------------------------------------------------
  970.       ' NOTE-> REMOVE the item to lbxBrowser...at the BOTTOM...
  971.       '----------------------------------------------------------------------
  972.       BRW001F.lbxBrowser.RemoveItem nLastIdx%
  973.       nLastIdx% = nLastIdx% - 1
  974.       ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows - 1
  975.       ngLBXBrowserLastRow = ngLBXBrowserFirstRow + (ngLBXBrowserNumOfRows - 1)
  976.    Next nIdx%
  977. Else
  978.    '-------------------------------------------------------------------------
  979.    ' NOTE-> BRW_ADD_BELOW_FLAG
  980.    '-------------------------------------------------------------------------
  981.    nCount% = BRW001F.lbxBrowser.ListCount
  982.    If (nCount% < 1) Then
  983.       '----------------------------------------------------------------------
  984.       ' NOTE-> listbox is EMPTY...
  985.       '----------------------------------------------------------------------
  986.       nFunctRetVal% = BRW_ERROR
  987.       fntAdjDeltaBrowserItems% = nFunctRetVal%
  988.       Exit Function
  989.    End If
  990.    nListCount% = nCount% - 1
  991.    nFirstIdx% = 0
  992.    nStart% = 1
  993.    nEnd% = nRowsAdded%
  994.    For nIdx% = nStart% To nEnd%
  995.       '----------------------------------------------------------------------
  996.       ' NOTE-> REMOVE the item to lbxBrowser...at the TOP...
  997.       '        leave nFirstIdx% set to 0...
  998.       '----------------------------------------------------------------------
  999.       BRW001F.lbxBrowser.RemoveItem nFirstIdx%
  1000.       ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows - 1
  1001.       ngLBXBrowserFirstRow = ngLBXBrowserFirstRow + 1
  1002.    Next nIdx%
  1003. End If
  1004. '----------------------------------------------------------------------------
  1005. ' NOTE-> at this point...we need to determine the +new+ value for nNewIdx%...
  1006. '----------------------------------------------------------------------------
  1007. If ((nValue% >= ngLBXBrowserFirstRow) And (nValue% <= ngLBXBrowserLastRow)) Then
  1008.    nNewIdx% = nValue% - ngLBXBrowserFirstRow
  1009. Else
  1010.    '-------------------------------------------------------------------------
  1011.    ' NOTE-> this should not occur...but if it does...set nNewIdx% to TOP...
  1012.    '-------------------------------------------------------------------------
  1013.    nNewIdx% = 0
  1014. End If
  1015.  
  1016. If (ngJETRowNumber <> nValue%) Then
  1017.    If (ngJETRowNumber > nValue%) Then
  1018.       nSteps% = ngJETRowNumber - nValue%
  1019.       For nIdx% = 1 To nSteps%
  1020.          BRW001F.datJET.Recordset.MovePrevious
  1021.          ngJETRowNumber = ngJETRowNumber - 1
  1022.       Next nIdx%
  1023.    Else
  1024.       nSteps% = nValue% - ngJETRowNumber
  1025.       For nIdx% = 1 To nSteps%
  1026.          BRW001F.datJET.Recordset.MoveNext
  1027.          ngJETRowNumber = ngJETRowNumber + 1
  1028.       Next nIdx%
  1029.    End If
  1030. End If
  1031. nFunctRetVal% = nNewIdx%
  1032. fntAdjDeltaBrowserItems% = nFunctRetVal%
  1033. Exit Function
  1034. fntAdjDeltaBrowserItemsErr:
  1035.    Resume Next
  1036. fntAdjDeltaBrowserItemsExit:
  1037.    fntAdjDeltaBrowserItems% = True
  1038. End Function
  1039.  
  1040. Function fntLoadBrowserLB% (nFirstRow%, nNumOfRows%, nRetIdxTypeFlag%, nValue%)
  1041. Dim nBOF%
  1042. Dim nBOFToFirstRow%
  1043. Dim nCols%
  1044. Dim nEOF%
  1045. Dim nEOFToFirstRow%
  1046. Dim nFunctRetVal%
  1047. Dim nHowToPosFlag%
  1048. Dim nIdx%
  1049. Dim nJETCurrPosToFirstRow%
  1050. Dim nJETCurrPosToFirstRowDirection%
  1051. Dim nListCols%
  1052. Dim nOnLastRowExitForEarly%
  1053. Dim nVSRMax%
  1054. Dim szLBStr$
  1055. Dim szTxt$
  1056. On Error GoTo fntLoadBrowserLBErr
  1057. nCols% = BRW001F.clbCols.ListCount
  1058. If (nCols% < 1) Then
  1059.    nFunctRetVal% = False
  1060.    fntLoadBrowserLB% = nFunctRetVal%
  1061.    Exit Function
  1062. End If
  1063. nListCols% = nCols% - 1
  1064. BRW001F.lbxBrowser.Clear
  1065.  
  1066. '----------------------------------------------------------------------------
  1067. ' NOTE-> build the lbxBrowser STRING using ALL fields in the TABLE for
  1068. '        the CURRENT ROW...
  1069. '----------------------------------------------------------------------------
  1070. ' WARNING-> the lbxBrowser STRING must be NULL-terminated...
  1071. '           this is because VB listbox controls are +really+ Windows
  1072. '           listbox controls, and Windows controls know absolutely
  1073. '           nothing about VB strings--they only know 'C' strings...
  1074. '----------------------------------------------------------------------------
  1075. ' NOTE-> since this function is used for SEVERAL cases, we cannot presume
  1076. '        that datJET is currently positioned on nFirstRow%...
  1077. '        so...we need to explicitly POSITION datJET on nFirstRow% if it is
  1078. '        not already on it...
  1079. '----------------------------------------------------------------------------
  1080. ' STRATEGY-> since we have to do positioning via MoveXXXX, (perhaps) the
  1081. '            best way to improve efficiency is to minimize the number of
  1082. '            MoveXXXX commands required to position datJET...
  1083. '----------------------------------------------------------------------------
  1084. If (nFirstRow% <> 1) Then                 ' NOTE-> OUTER IF...
  1085. '----------------------------------------------------------------------------
  1086. ' NOTE-> currently...doing a MoveLast reads EVERY row in the dynaset...
  1087. '        so...we need to add that count to our predicting variable...
  1088. '----------------------------------------------------------------------------
  1089. nVSRMax% = BRW001F.vsrBrowser.Max
  1090. nEOFToFirstRow% = (nVSRMax% - nFirstRow%) + nVSRMax%
  1091. nBOFToFirstRow% = nFirstRow%
  1092. nHowToPosFlag% = BRW_MOVE_FROM_UNKNOWN
  1093. If (ngJETRowNumber <> nFirstRow%) Then    ' -------NOTE-> INNER If...
  1094.    '-------------------------------------------------------------------------
  1095.    ' NOTE-> POSITION datJET to nFirstRow%...
  1096.    '-------------------------------------------------------------------------
  1097.    If (ngJETRowNumber < nFirstRow%) Then
  1098.       '----------------------------------------------------------------------
  1099.       ' NOTE-> ngJETRowNumber < nFirstRow%...
  1100.       '----------------------------------------------------------------------
  1101.       nJETCurrPosToFirstRowDirection% = BRW_FORWARD_DIRECTION
  1102.       nJETCurrPosToFirstRow% = nFirstRow% - ngJETRowNumber
  1103.    Else
  1104.       nJETCurrPosToFirstRowDirection% = BRW_BACKWARD_DIRECTION
  1105.       nJETCurrPosToFirstRow% = ngJETRowNumber - nFirstRow%
  1106.    End If
  1107.    If (nJETCurrPosToFirstRow% <= nBOFToFirstRow%) Then
  1108.       If (nJETCurrPosToFirstRow% <= nEOFToFirstRow%) Then
  1109.          '-------------------------------------------------------------------
  1110.          ' NOTE-> use nJETCurrPosToFirstRow%...
  1111.          '-------------------------------------------------------------------
  1112.          nHowToPosFlag% = BRW_MOVE_FROM_CURR_POS
  1113.       Else
  1114.          '-------------------------------------------------------------------
  1115.          ' NOTE-> use nEOFToFirstRow%...
  1116.          '-------------------------------------------------------------------
  1117.          nHowToPosFlag% = BRW_MOVE_FROM_EOF_POS
  1118.       End If
  1119.    Else
  1120.       If (nBOFToFirstRow% <= nEOFToFirstRow%) Then
  1121.          '-------------------------------------------------------------------
  1122.          ' NOTE-> use nBOFToFirstRow%...
  1123.          '-------------------------------------------------------------------
  1124.          nHowToPosFlag% = BRW_MOVE_FROM_BOF_POS
  1125.       Else
  1126.          '-------------------------------------------------------------------
  1127.          ' NOTE-> use nEOFToFirstRow%...
  1128.          '-------------------------------------------------------------------
  1129.          nHowToPosFlag% = BRW_MOVE_FROM_EOF_POS
  1130.       End If
  1131.    End If
  1132. Else                                      ' -------NOTE-> INNER If...
  1133.    '-------------------------------------------------------------------------
  1134.    ' NOTE-> use nJETCurrPosToFirstRow%...
  1135.    '-------------------------------------------------------------------------
  1136.    nHowToPosFlag% = BRW_MOVE_FROM_CURR_POS
  1137. End If                                    ' -------NOTE-> INNER If...
  1138. Else                                      ' NOTE-> OUTER If...
  1139.    nHowToPosFlag% = BRW_MOVE_FIRST
  1140. End If                                    ' NOTE-> OUTER If...
  1141. Select Case nHowToPosFlag%
  1142.    Case BRW_MOVE_FROM_BOF_POS
  1143.       BRW001F.datJET.Recordset.MoveFirst
  1144.       ngJETRowNumber = 1
  1145.       nStart% = 2
  1146.       nEnd% = nBOFToFirstRow%
  1147.       For nSteps% = nStart% To nEnd%
  1148.          BRW001F.datJET.Recordset.MoveNext
  1149.          ngJETRowNumber = ngJETRowNumber + 1
  1150.       Next nSteps%
  1151.    Case BRW_MOVE_FROM_CURR_POS
  1152.       Select Case nJETCurrPosToFirstRowDirection%
  1153.          Case BRW_FORWARD_DIRECTION
  1154.             nStart% = 1
  1155.             nEnd% = nJETCurrPosToFirstRow%
  1156.             For nSteps% = nStart% To nEnd%
  1157.                BRW001F.datJET.Recordset.MoveNext
  1158.                ngJETRowNumber = ngJETRowNumber + 1
  1159.             Next nSteps%
  1160.          Case BRW_BACKWARD_DIRECTION
  1161.             nStart% = 1
  1162.             nEnd% = nJETCurrPosToFirstRow%
  1163.             For nSteps% = nStart% To nEnd%
  1164.                BRW001F.datJET.Recordset.MovePrevious
  1165.                ngJETRowNumber = ngJETRowNumber - 1
  1166.             Next nSteps%
  1167.       End Select
  1168.    Case BRW_MOVE_FROM_EOF_POS
  1169.       BRW001F.datJET.Recordset.MoveLast
  1170.       ngJETRowNumber = BRW001F.vsrBrowser.Max
  1171.       nStart% = 2
  1172.       nEnd% = nBOFToFirstRow%
  1173.       For nSteps% = nStart% To nEnd%
  1174.          BRW001F.datJET.Recordset.MovePrevious
  1175.          ngJETRowNumber = ngJETRowNumber - 1
  1176.       Next nSteps%
  1177.    Case BRW_MOVE_FIRST
  1178.       BRW001F.datJET.Recordset.MoveFirst
  1179.       ngJETRowNumber = 1
  1180. End Select
  1181. '----------------------------------------------------------------------------
  1182. ' NOTE-> at this point...we should be positioned on the BEGINNING ROW of
  1183. '        the subset of ROWS that we are adding to the listbox...
  1184. '----------------------------------------------------------------------------
  1185. nStart% = nFirstRow%
  1186. nEnd% = nFirstRow% + (nNumOfRows% - 1)
  1187. nOnLastRowExitForEarly% = False
  1188. For nRow% = nStart% To nEnd%
  1189.    szLBStr$ = Space$(1)
  1190.    For nIdx% = 0 To nListCols%
  1191.       szTxt$ = BRW001F.txtData(nIdx%).Text
  1192.       If (szTxt$ = "Dunn's Holdings") Then
  1193.          nWhat% = 1
  1194.       End If
  1195.       lTxtLen& = Len(szTxt$)
  1196.       szType$ = BRW001F.clbTypes.List(nIdx%)
  1197.       nBeginParen% = InStr(1, szType$, "(")
  1198.       nStart% = nBeginParen% + 1
  1199.       nEndParen% = InStr(nStart%, szType$, ")")
  1200.       nLen% = nEndParen% - nStart%
  1201.       szLen$ = Mid$(szType$, nStart%, nLen%)
  1202.       lMaxTxtLen& = Val(szLen$)
  1203.       lDeltaLen& = lMaxTxtLen& - lTxtLen&
  1204.       szLBStr$ = szLBStr$ + szTxt$ + Space$(2)
  1205.       If (lDeltaLen& > 0) Then
  1206.          szLBStr$ = szLBStr$ + Space$(lDeltaLen&)
  1207.       End If
  1208.    Next nIdx%
  1209.    szLBStr$ = szLBStr$ + Chr$(0)
  1210.    BRW001F.lbxBrowser.AddItem szLBStr$
  1211.    
  1212.    '-------------------------------------------------------------------------
  1213.    ' NOTE-> are we already on the LAST record...if so then do NOT do a
  1214.    '        MoveNext because it will make our current position UNDEFINED...
  1215.    '        in which case we have to read the +entire+ dynaset to get back
  1216.    '        to the LAST record...
  1217.    '-------------------------------------------------------------------------
  1218.    nVSRMax% = BRW001F.vsrBrowser.Max
  1219.    If (ngJETRowNumber = nVSRMax%) Then
  1220.       If (nRow% < nEnd%) Then
  1221.          nOnLastRowExitForEarly% = True
  1222.       End If
  1223.       Exit For
  1224.    End If
  1225.    BRW001F.datJET.Recordset.MoveNext
  1226.    ngJETRowNumber = ngJETRowNumber + 1
  1227.    nEOF% = BRW001F.datJET.Recordset.EOF
  1228.    If (nEOF%) Then
  1229.       '----------------------------------------------------------------------
  1230.       ' NOTE-> just in case we made a mistake...
  1231.       '----------------------------------------------------------------------
  1232.       BRW001F.datJET.Recordset.MoveLast
  1233.       ngJETRowNumber = ngJETRowNumber - 1
  1234.       If (nRow% < nEnd%) Then
  1235.          nOnLastRowExitForEarly% = True
  1236.       End If
  1237.       Exit For
  1238.    End If
  1239. Next nRow%
  1240. '----------------------------------------------------------------------------
  1241. ' NOTE-> did we do one extra datJET.Recordset.MoveNext...if so, we need
  1242. '        to undo it so we know where we are next time we need to read...
  1243. '----------------------------------------------------------------------------
  1244. If (nOnLastRowExitForEarly% = True) Then
  1245.    '-------------------------------------------------------------------------
  1246.    ' NOTE-> we are on the LAST row and have read it...so do NOTHING here...
  1247.    '-------------------------------------------------------------------------
  1248. Else
  1249.    '-------------------------------------------------------------------------
  1250.    ' NOTE-> we read one too many rows...so back up one row...
  1251.    '-------------------------------------------------------------------------
  1252.    If (ngJETRowNumber = 1) Then
  1253.       '----------------------------------------------------------------------
  1254.       ' NOTE-> we cannot backup any more...we are on the FIRST row...
  1255.       '----------------------------------------------------------------------
  1256.    Else
  1257.       BRW001F.datJET.Recordset.MovePrevious
  1258.       ngJETRowNumber = ngJETRowNumber - 1
  1259.    End If
  1260. End If
  1261. Select Case nRetIdxTypeFlag%
  1262.    Case BRW_RETURN_SPECIFIED_LISTINDEX
  1263.       ngCurrListIdx = nValue - 1
  1264.       BRW001F.lbxBrowser.ListIndex = nValue% - 1
  1265.       ngLBXBrowserValue = nValue%
  1266.    Case BRW_RETURN_FIRST_LISTINDEX
  1267.       ngCurrListIdx = 0
  1268.       BRW001F.lbxBrowser.ListIndex = 0
  1269.       ngLBXBrowserValue = nFirstRow%
  1270.    Case BRW_RETURN_LAST_LISTINDEX
  1271.       nCount% = BRW001F.lbxBrowser.ListCount
  1272.       If (nCount% < 1) Then
  1273.          nFunctRetVal% = BRW_UNSUCCESSFUL
  1274.          fntLoadBrowserLB% = nFunctRetVal%
  1275.          Exit Function
  1276.       End If
  1277.       nListIdx% = nCount% - 1
  1278.       ngCurrListIdx = nListIdx%
  1279.       BRW001F.lbxBrowser.ListIndex = nListIdx%
  1280.       ngLBXBrowserValue = nFirstRow%
  1281. End Select
  1282. ngLBXBrowserFirstRow = nFirstRow%
  1283. ngLBXBrowserNumOfRows = nNumOfRows%
  1284. ngLBXBrowserLastRow = ngLBXBrowserFirstRow + (ngLBXBrowserNumOfRows - 1)
  1285. nFunctRetVal% = BRW001F.lbxBrowser.ListIndex
  1286. fntLoadBrowserLB% = nFunctRetVal%
  1287. Exit Function
  1288.  
  1289. fntLoadBrowserLBErr:
  1290.    Resume Next
  1291. fntLoadBrowserLBExit:
  1292.    fntLoadBrowserLB% = True
  1293. End Function
  1294.  
  1295. Function fntLoadLastBlock% (nValue%)
  1296. Dim nBOF%
  1297. Dim nCols%
  1298. Dim nCount%
  1299. Dim nEnd%
  1300. Dim nEOF%
  1301. Dim nFunctRetVal%
  1302. Dim nIdx%
  1303. Dim nJETCurrPosToLastRow%
  1304. Dim nListCols%
  1305. Dim nListCount%
  1306. Dim nNewIdx%
  1307. Dim nOffset%
  1308. Dim nOnLastRowExitForEarly%
  1309. Dim nStart%
  1310. Dim nSteps%
  1311. Dim nVSRMax%
  1312. Dim szLBStr$
  1313. Dim szTxt$
  1314. '----------------------------------------------------------------------------
  1315. ' NOTE-> the second special case occurs when nValue% is within
  1316. '        ngLBXBrowserDispItems of datJET.Recordset.EOF (a.k.a. the
  1317. '        vsrBrowser.Max value)...in which case we can do a
  1318. '        datJET.Recordset.MoveLast, lbxBrowser.Clear, and
  1319. '        then do (ngLBXBrowserDispItems * 3) datJET.Recordset.MovePrev
  1320. '        commands and lbxBrowser.AddItem each row +but+ in +reverse+
  1321. '        order because we are reading backwards...
  1322. '----------------------------------------------------------------------------
  1323. On Error GoTo fntLoadLastBlockErr
  1324.    nCols% = BRW001F.clbCols.ListCount
  1325.  
  1326. If (nCols% < 1) Then
  1327.    nFunctRetVal% = False
  1328.    fntLoadLastBlock% = nFunctRetVal%
  1329.    Exit Function
  1330. End If
  1331. nListCols% = nCols% - 1
  1332.    BRW001F.lbxBrowser.Clear
  1333.  
  1334. '----------------------------------------------------------------------------
  1335. ' NOTE-> build the lbxBrowser STRING using ALL fields in the TABLE for
  1336. '        the CURRENT ROW...
  1337. '----------------------------------------------------------------------------
  1338. ' WARNING-> the lbxBrowser STRING must be NULL-terminated...
  1339. '           this is because VB listbox controls are +really+ Windows
  1340. '           listbox controls, and Windows controls know absolutely
  1341. '           nothing about VB strings--they only know 'C' strings...
  1342. '----------------------------------------------------------------------------
  1343.    nRecCount% = BRW001F.vsrBrowser.Max
  1344.  
  1345. nItemsPerBlock% = ngLBXBrowserDispItems * 3
  1346. If (nRecCount% >= nItemsPerBlock%) Then
  1347.    '-------------------------------------------------------------------------
  1348.    ' NOTE-> plenty of ROWS...so get the last nItemsPerBlock% ROWS...
  1349.    '        but not now....
  1350.    '-------------------------------------------------------------------------
  1351. Else
  1352.    '-------------------------------------------------------------------------
  1353.    ' NOTE-> NOT so many ROWS...so get ALL of the rows...
  1354.    '        this is the same thing we do when we first begin browsing...
  1355.    '-------------------------------------------------------------------------
  1356.    nFirstRow% = 1
  1357.    nNumOfRows% = nRecCount%
  1358.    nRetIdxTypeFlag% = BRW_RETURN_FIRST_LISTINDEX
  1359.    nRetVal% = fntLoadBrowserLB%(nFirstRow%, nNumOfRows%, nRetIdxTypeFlag%, nValue%)
  1360.    nFunctRetVal% = nRetVal%
  1361.    fntLoadLastBlock% = nFunctRetVal%
  1362.    Exit Function
  1363. End If
  1364. '----------------------------------------------------------------------------
  1365. ' NOTE-> we are loading the listbox in +REVERSE+ order...
  1366. '----------------------------------------------------------------------------
  1367. ' NOTE-> since we are probably near the LAST record, use a MoveNext LOOP to
  1368. '        get to the LAST record...it is faster...
  1369. '----------------------------------------------------------------------------
  1370.    nRecCount% = BRW001F.vsrBrowser.Max
  1371.  
  1372. nJetRowsUntilLast% = nRecCount% - ngJETRowNumber
  1373. nStart% = ngJETRowNumber + 1
  1374. nEnd% = nJetRowsUntilLast% + nStart%
  1375. nOnLastRowExitForEarly% = False
  1376. For nRow% = nStart% To nEnd%
  1377.    '-------------------------------------------------------------------------
  1378.    ' NOTE-> are we already on the LAST record...if so then do NOT do a
  1379.    '        MoveNext because it will make our current position UNDEFINED...
  1380.    '        in which case we have to read the +entire+ dynaset to get back
  1381.    '        to the LAST record...
  1382.    '-------------------------------------------------------------------------
  1383.       nVSRMax% = BRW001F.vsrBrowser.Max
  1384.   
  1385.    If (ngJETRowNumber = nVSRMax%) Then
  1386.       If (nRow% <= nEnd%) Then
  1387.          nOnLastRowExitForEarly% = True
  1388.       End If
  1389.       Exit For
  1390.    End If
  1391.       BRW001F.datJET.Recordset.MoveNext
  1392.    
  1393.    ngJETRowNumber = ngJETRowNumber + 1
  1394.       nEOF% = BRW001F.datJET.Recordset.EOF
  1395.    
  1396.    If (nEOF%) Then
  1397.       '----------------------------------------------------------------------
  1398.       ' NOTE-> just in case we made a mistake...
  1399.       '----------------------------------------------------------------------
  1400.          BRW001F.datJET.Recordset.MoveLast
  1401.       
  1402.       ngJETRowNumber = ngJETRowNumber - 1
  1403.       If (nRow% <= nEnd%) Then
  1404.          nOnLastRowExitForEarly% = True
  1405.       End If
  1406.       Exit For
  1407.    End If
  1408. Next nRow%
  1409. '----------------------------------------------------------------------------
  1410. ' NOTE-> if all went well then we are sitting on the LAST row of the dynaset...
  1411. '----------------------------------------------------------------------------
  1412. nRecCount% = BRW001F.vsrBrowser.Max
  1413. nItemsPerBlock% = ngLBXBrowserDispItems * 3
  1414. nStart% = nRecCount%
  1415. nEnd% = (nStart% - nItemsPerBlock%) + 1
  1416. ngLBXBrowserNumOfRows = 0
  1417. nOnLastRowExitForEarly% = False
  1418. For nRow% = nStart% To nEnd% Step by - 1
  1419.    szLBStr$ = Space$(1)
  1420.    For nIdx% = 0 To nListCols%
  1421.       szTxt$ = BRW001F.txtData(nIdx%).Text
  1422.       lTxtLen& = Len(szTxt$)
  1423.       szType$ = BRW001F.clbTypes.List(nIdx%)
  1424.       nBeginParen% = InStr(1, szType$, "(")
  1425.       nStart% = nBeginParen% + 1
  1426.       nEndParen% = InStr(nStart%, szType$, ")")
  1427.       nLen% = nEndParen% - nStart%
  1428.       szLen$ = Mid$(szType$, nStart%, nLen%)
  1429.       lMaxTxtLen& = Val(szLen$)
  1430.       lDeltaLen& = lMaxTxtLen& - lTxtLen&
  1431.       szLBStr$ = szLBStr$ + szTxt$ + Space$(2)
  1432.       If (lDeltaLen& > 0) Then
  1433.          szLBStr$ = szLBStr$ + Space$(lDeltaLen&)
  1434.       End If
  1435.    Next nIdx%
  1436.    szLBStr$ = szLBStr$ + Chr$(0)
  1437.    '-------------------------------------------------------------------------
  1438.    ' NOTE-> since we are going BACKWARDS...we need to add each item to
  1439.    '        lbxBrowser at INDEX = 0 location...
  1440.    '-------------------------------------------------------------------------
  1441.    BRW001F.lbxBrowser.AddItem szLBStr$, 0
  1442.    ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows + 1
  1443.    BRW001F.datJET.Recordset.MovePrevious
  1444.    ngJETRowNumber = ngJETRowNumber - 1
  1445.    nBOF% = BRW001F.datJET.Recordset.BOF
  1446.    If (nBOF%) Then
  1447.       BRW001F.datJET.Recordset.MoveNext
  1448.       ngJETRowNumber = 1
  1449.       '----------------------------------------------------------------------
  1450.       ' NOTE-> remember...we are going BACKWARDS...so FOR LOOP indexes are
  1451.       '        also going BACKWARDS...
  1452.       '----------------------------------------------------------------------
  1453.       If (nRow% > nEnd%) Then
  1454.          nOnLastRowExitForEarly% = True
  1455.       End If
  1456.       Exit For
  1457.    End If
  1458. Next nRow%
  1459. '----------------------------------------------------------------------------
  1460. ' NOTE-> we did this in REVERSE...so the global first row is set to nEnd%
  1461. '        since nEnd% < nStart% in the above FOR LOOP...
  1462. '        UNLESS we had to exit early...in which case it is set to nRow%...
  1463. '----------------------------------------------------------------------------
  1464. If (nOnLastRowExitForEarly% = True) Then
  1465.     ngLBXBrowserFirstRow = nRow%
  1466. Else
  1467.     ngLBXBrowserFirstRow = nEnd%
  1468. End If
  1469. ngLBXBrowserLastRow = ngLBXBrowserFirstRow + (ngLBXBrowserNumOfRows - 1)
  1470. nVSRMax% = BRW001F.vsrBrowser.Max
  1471. If (ngJETRowNumber < nVSRMax%) Then
  1472.    '-------------------------------------------------------------------------
  1473.    ' NOTE-> we are are at the near the END of the dynaset...
  1474.    '        and our logic for traversing it at this point is
  1475.    '        based upon the way things are after we get here as a
  1476.    '        result of single-stepping through the dynaset...
  1477.    '        in which case we would have gotten to the END via
  1478.    '        the 'ADD an ITEM/REMOVE an ITEM' method...and datJET
  1479.    '        would therefore be sitting on the LAST ROW in the
  1480.    '        dynaset...so...in order to do what we can to make this
  1481.    '        appear to be the NORMAL case...we will now proceed
  1482.    '        to POSITION datJET at the END of the SUBSET of ROWS...
  1483.    '        rather an UNUSUAL thing to do...but it WORKS...
  1484.    '-------------------------------------------------------------------------
  1485.    nStart% = 1
  1486.    nJETCurrPosToLastRow% = ngLBXBrowserDispItems * 3
  1487.    nVSRMax% = BRW001F.vsrBrowser.Max
  1488.    If (nJETCurrPosToLastRow% > nVSRMax%) Then
  1489.       nJETCurrPosToLastRow% = nVSRMax%
  1490.    End If
  1491.    nEnd% = nJETCurrPosToLastRow%
  1492.    For nSteps% = nStart% To nEnd%
  1493.       BRW001F.datJET.Recordset.MoveNext
  1494.       ngJETRowNumber = ngJETRowNumber + 1
  1495.    Next nSteps%
  1496. End If
  1497. '----------------------------------------------------------------------------
  1498. ' NOTE-> position the listbox index and scrollbar...
  1499. '----------------------------------------------------------------------------
  1500. nVSRMax% = BRW001F.vsrBrowser.Max
  1501. nOffset% = nVSRMax% - nValue%
  1502. nCount% = BRW001F.lbxBrowser.ListCount
  1503. If (nCount% < 1) Then
  1504.    '-------------------------------------------------------------------------
  1505.    ' NOTE- UNLIKELY error...
  1506.    '-------------------------------------------------------------------------
  1507. End If
  1508. nListCount% = nCount% - 1
  1509. nNewIdx% = nListCount% - nOffset%
  1510. ngCurrListIdx = nNewIdx%
  1511. BRW001F.lbxBrowser.ListIndex = nNewIdx%
  1512. ngLBXBrowserValue = nValue%
  1513. nFunctRetVal% = True
  1514. fntLoadLastBlock% = nFunctRetVal%
  1515. Exit Function
  1516.  
  1517. fntLoadLastBlockErr:
  1518.    Resume Next
  1519. fntLoadLastBlockExit:
  1520.   fntLoadLastBlock% = False
  1521. End Function
  1522.  
  1523. Function fntLoadTxtDataInstances% (nCols%)
  1524. Dim nIdx%
  1525. Dim nListCols%
  1526. On Error GoTo fntLoadTxtDataInstancesErr
  1527. nListCols% = nCols% - 1
  1528. nIdx% = 0
  1529. BRW001F.txtData(nIdx%).DataField = BRW001F.clbCols.List(nIdx%)
  1530. For nIdx% = 1 To nListCols%
  1531.    If (ngBRWFormTxtInstances < nIdx%) Then
  1532.       Load BRW001F.txtData(nIdx%)
  1533.       ngBRWFormTxtInstances = ngBRWFormTxtInstances + 1
  1534.    End If
  1535.    BRW001F.txtData(nIdx%).DataField = BRW001F.clbCols.List(nIdx%)
  1536. Next nIdx%
  1537. '----------------------------------------------------------------------------
  1538. ' NOTE-> for some UNKNOWN reason...it is NOT EASY (perhaps NOT POSSIBLE) to
  1539. '        to UNLOAD BOUND TEXT controls when they are no longer needed...
  1540. '        this BIZARRE BEHAVIOR appears to be connected with using a DROPDOWN
  1541. '        listbox for TABLE selection...
  1542. '        the WORKAROUND is not to unload unnecessary BOUND CONTROLS...
  1543. '        nevertheless...we can AT LEAST set the DataField property of these
  1544. '        unnecessary BOUND CONTROLS to BLANK...this is a PERFECT EXAMPLE of
  1545. '        Visual Basic's QUANTUM EVENT BEHAVIOR...at least in the sense that
  1546. '        these EXTRA DYNAMICALLY-CREATED, BOUND CONTROLS do not need to EXIST
  1547. '        insofar as WE are concerned, but Visual Basic NEEDS them and will
  1548. '        NOT let us DESTROY them at this particular POINT in the
  1549. '        QUANTUM EVENT CHAIN...so ALL we can do is make the controls INACTIVE...
  1550. '----------------------------------------------------------------------------
  1551. nExtraCtls% = ngBRWFormTxtInstances - nListCols%
  1552. If (nExtraCtls% > 0) Then
  1553.    For nIdx% = nCols% To ngBRWFormTxtInstances
  1554.       BRW001F.txtData(nIdx%).DataField = ""
  1555.    Next nIdx%
  1556. End If
  1557. fntLoadTxtDataInstances% = True
  1558. Exit Function
  1559. fntLoadTxtDataInstancesErr:
  1560.    '-------------------------------------------------------------------------
  1561.    ' WARNING-> we would NOT USUALLY do RESUME NEXT when we get an ERROR...
  1562.    '           but in this PARTICULAR function we EXPECT to get an ERROR
  1563.    '           because we are setting the DataField PROPERTY of BOUND
  1564.    '           controls to a FIELD that is PROBABLY NOT in the CURRENTLY
  1565.    '           SELECTED TABLE...consequently WHEN VB3 tells us IT detected
  1566.    '           an ERROR, our response is "SO WHAT!  JUST DO WHAT WE TELL
  1567.    '           YOU TO DO AND QUIT COMPLAINING!"...
  1568.    '-------------------------------------------------------------------------
  1569.    Resume Next
  1570. End Function
  1571.  
  1572. Function fntRemSomeBrowserRows% (nDelta%, nNewIdx%, nJETLastRow%)
  1573. Dim nEnd%
  1574. Dim nFunctRetVal%
  1575. Dim nIdx%
  1576. Dim nStart%
  1577. '----------------------------------------------------------------------------
  1578. ' NOTE-> this function removes some number of items from the +top+ of the
  1579. '        lbxBrowser listbox, and adjusts the global tracking variables
  1580. '        accordingly...
  1581. '----------------------------------------------------------------------------
  1582. ' NOTE->      nDelta% => number of items to remove from TOP of listbox...
  1583. '            nNewIdx% => current nNewIdx% value...
  1584. '        nJETLastRow% => ROW number of LAST LOADED ROW...
  1585. '----------------------------------------------------------------------------
  1586. ' RETURNS-> if (SUCCESSFUL)   -> the new value for nNewIdx%
  1587. '           if (UNSUCCESSFUL) -> BRW_ERROR
  1588. '----------------------------------------------------------------------------
  1589. nStart% = 0
  1590. nEnd% = nDelta% - 1
  1591. For nIdx% = nStart% To nEnd%
  1592.    BRW001F.lbxBrowser.RemoveItem 0
  1593.    ngLBXBrowserFirstRow = ngLBXBrowserFirstRow + 1
  1594.    ngLBXBrowserNumOfRows = ngLBXBrowserNumOfRows - 1
  1595.    nNewIdx% = nNewIdx% - 1
  1596. Next nIdx%
  1597. If (nNewIdx% < 0) Then
  1598.    nFunctRetVal% = BRW_ERROR
  1599. Else
  1600.    nFunctRetVal% = nNewIdx%
  1601. End If
  1602. fntRemSomeBrowserRows% = nFunctRetVal%
  1603. End Function
  1604.  
  1605. Function fntUnloadTxtDataInstances% ()
  1606. Dim nIdx%
  1607. Dim nTotalInstances%
  1608. On Error GoTo fntUnloadTxtDataInstancesErr
  1609. nTotalInstances% = ngBRWFormTxtInstances
  1610. nIdx% = 0
  1611. BRW001F.txtData(nIdx%).DataField = ""
  1612. For nIdx% = nTotalInstances% To 1 Step by - 1
  1613.    BRW001F.txtData(nIdx%).DataField = ""
  1614.    Unload BRW001F.txtData(nIdx%)
  1615.    ngBRWFormTxtInstances = ngBRWFormTxtInstances - 1
  1616. Next nIdx%
  1617. fntUnloadTxtDataInstances% = True
  1618. Exit Function
  1619. fntUnloadTxtDataInstancesErr:
  1620.    szMsg$ = "ERROR-> " + Error$
  1621.    MsgBox szMsg$
  1622.    ngIgnoreTblsClick = False
  1623.    Exit Function
  1624. fntUnloadTxtDataInstancesExit:
  1625.    fntUnloadTxtDataInstances% = False
  1626. End Function
  1627.  
  1628.