home *** CD-ROM | disk | FTP | other *** search
- ****
- * TBWhile.prg
- * Illustration of TBROWSE with While Condition
- * Modified From TBDEMO/DBUEDIT.prgs which are:
- * Copyright (c) 1990 Nantucket Corp. All rights reserved.
- *
- * Note: compile with /n/w/a
-
- * This Demo shows Names.dbf consisting of Last, First, Addr, City, State, Zip
- * with active index on last + first
- * It shows Last Name, First Name, City only for those Last Names That
- * Begin With Letter That You Input For The cKey GET.
-
- * This program is entered into the public domain by James J. Orlowski, M.D.
- * Correction 11/7/90: added goTopBlock() and goBottomBlock() to simplify code
-
- #include "inkey.ch"
- #include "setcurs.ch"
-
- * Set Up these two MEMVARS, which track top and bottom record
- * for use with goTopBlock() and goBottomBlock(). They are declared as
- * PUBLIC in main loop
- MEMVAR nTopNo, nBotNo
-
- ****
- * main part of tbwhile
- *
- PROCEDURE TBWhile
- LOCAL aFields := {}, aHead := {}
- LOCAL cKey := "O"
- MEMVAR GetList
- PUBLIC nTopNo, nBotNo
- * Index on Last + First
- USE Names INDEX Names NEW
- * Need Separate Fieldname and Alias To Use FIELDWBLOCK() function
- AADD(aFields, {"Last" , "Names" })
- AADD(aFields, {"First", "Names" })
- AADD(aFields, {"City" , "Names" })
-
- AADD(aHead, "Last Name")
- AADD(aHead, "First Name")
- AADD(aHead, "City")
- SETCOLOR("N/BG")
- CLEAR SCREEN
- @ 5,10 SAY "Enter First Letter Of Last Name:" GET cKey PICTURE "!"
- READ
- CLEAR SCREEN
-
- IF .NOT. TBWhileSet(cKey) // Passes Key to set nTopNo and nBotNo
- SET COLOR TO
- CLEAR SCREEN
- ? "Sorry, But There Were NO Records To List"
- QUIT
- ENDIF
- * Names->Last = cKey is the Conditional Block passed to this function
- * you can make it as complicated as you want, but you would then
- * have to modify TBWhileSet() to find first and last records
- * matching your key.
- MyBrowse(3, 6, MaxRow() - 2, MaxCol() - 6, ;
- aFields, aHead, {||Names->Last = cKey} )
-
- SET COLOR TO
- @ MaxRow(), 0 CLEAR
- RETURN
- * EOP TBWhile
-
- ***
- * MyBrowse()
- *
- FUNCTION MyBrowse(nTop, nLeft, nBottom, nRight, aFields, aHead, bWhileCond)
- LOCAL b, column, cType, i
- LOCAL cHead, cField, cAlias
- LOCAL cColorSave, nCursSave
- LOCAL lMore, nKey
-
- /* make new browse object */
- b := TBrowseDB(nTop, nLeft, nBottom, nRight)
-
- /* default heading and column separators */
- b:headSep := "═╤═"
- b:colSep := " │ "
- b:footSep := "═╧═"
-
- /* add custom 'SkipWhile' (to handle passed condition) */
- b:skipBlock := {|x| SkipWhile(x, bWhileCond)}
-
- /* Set up substitute goto top and goto bottom */
- /* with While's top and bottom records */
- b:goTopBlock := {|| __dbGoto(nTopNo)}
- b:goBottomBlock := {|| __dbGoto(nBotNo)}
-
- /* colors */
- b:colorSpec := "N/W, N/BG, B/W, B/BG, B/W, B/BG, R/W, B/R"
-
- /* add a column for each field in the current workarea */
- FOR i = 1 TO LEN(aFields)
- cHead := aHead[i]
- cField := aFields[i, 1]
- cAlias := aFields[i, 2]
-
- /* make the new column */
- column := TBColumnNew( cHead, FieldWBlock(cField, Select(cAlias) ) )
-
- /* evaluate the block once to get the field's data type */
- cType := VALTYPE( Eval(column:block) )
- column:defColor := {3, 4}
-
- b:addColumn(column)
- NEXT
-
- /* make a window shadow */
- cColorSave := SETCOLOR("N/N")
- @ nTop+1, nLeft+1 CLEAR TO nBottom+1, nRight+1
- SETCOLOR("W/W")
- @ nTop, nLeft CLEAR TO nBottom, nRight
- SETCOLOR(cColorSave)
-
- nCursSave := SetCursor(0)
-
- lMore := .t.
- WHILE (lMore)
-
- /* stabilize the display */
- WHILE ( .NOT. b:stabilize() )
- nKey := INKEY()
- IF ( nKey <> 0 )
- EXIT /* (abort IF a key is waiting) */
- ENDIF
- ENDDO
-
- IF ( b:stable )
- /* display is stable */
- IF ( b:hitTop .OR. b:hitBottom )
- Tone(125, 0)
- ENDIF
-
- /* everything's done; just wait for a key */
- nKey := INKEY(0)
- ENDIF
-
- /* process key */
- DO CASE
- CASE ( nKey == K_DOWN )
- b:down()
-
- CASE ( nKey == K_UP )
- b:up()
-
- CASE ( nKey == K_PGDN )
- b:pageDown()
-
- CASE ( nKey == K_PGUP )
- b:pageUp()
-
- CASE ( nKey == K_CTRL_PGUP )
- b:goTop()
-
- CASE ( nKey == K_CTRL_PGDN )
- b:goBottom()
-
- CASE ( nKey == K_RIGHT )
- b:right()
-
- CASE ( nKey == K_LEFT )
- b:left()
-
- CASE ( nKey == K_HOME )
- b:home()
-
- CASE ( nKey == K_END )
- b:end()
-
- CASE ( nKey == K_CTRL_LEFT )
- b:panLeft()
-
- CASE ( nKey == K_CTRL_RIGHT )
- b:panRight()
-
- CASE ( nKey == K_CTRL_HOME )
- b:panHome()
-
- CASE ( nKey == K_CTRL_END )
- b:panEnd()
-
- CASE ( nKey == K_ESC )
- lMore := .f.
-
- CASE ( nKey == K_RETURN )
- lMore := .f.
-
- ENDCASE
-
- ENDDO
-
- SetCursor(nCursSave)
-
- RETURN (.t.)
-
- ****
- * SkipWhile()
- *
- STATIC FUNCTION SkipWhile(n, bWhileCond)
- LOCAL i
-
- i := 0
- IF ( LASTREC() <> 0 )
- IF ( n == 0 )
- SKIP 0
-
- ELSEIF ( n > 0 .AND. RECNO() <> LASTREC() )
- WHILE ( i < n )
- SKIP 1
- IF ( EOF() .OR. .NOT. Eval(bWhileCond) )
- SKIP -1
- EXIT
- ENDIF
- i++
- ENDDO
-
- ELSEIF ( n < 0 )
- WHILE ( i > n )
- SKIP -1
- IF ( BOF() )
- EXIT
- ELSEIF .NOT. Eval( (bWhileCond) )
- SKIP
- EXIT
- ENDIF
- i--
- ENDDO
- ENDIF
- ENDIF
- RETURN (i)
- * EOFcn SkipWhile()
-
- ****
- * TBWhileSet()
- *
- FUNCTION TBWhileSet(cKey)
- * Sets Up nTopNo And nBotNo For TBWhile()
- IF ( cKey == NIL ) // if no cKey, set up for all records
- GOTO BOTTOM
- nBotNo := RECNO()
- GOTO TOP
- nTopNo := RECNO()
- RETURN(.t.)
- ENDIF
-
- SEEK cKey
- IF EOF() .OR. LASTREC() == 0
- nTopNo := nBotNo := 0
- RETURN(.f.)
- ENDIF
-
- nTopNo := RECNO()
- * goto last record for cKey in indexed dbf
- SeekLast(cKey)
- * don't need to check if keyfield = cKey since previous
- * Seek cKey/IF EOF()/Return(.f.) already showed data present
- nBotNo := RECNO()
- GOTO nTopNo
- RETURN(.t.)
- * EOFcn TBWhileSet
-
- FUNCTION SeekLast(cKey)
- * SeekLast: Finds Last Record For Matching Key
- * Developed By Jon Cole
- * With softseek set on, seek the first record after condition.
- * This is accomplished by incrementing the right most character of the
- * string cKey by one ascii character. After SEEKing the new string,
- * back up one record to get to the last record which matches cKey.
- SET SOFTSEEK ON
- SEEK LEFT(cKey, LEN(cKey) -1) + CHR( ASC( RIGHT(cKey,1) ) +1)
- SET SOFTSEEK OFF
- SKIP -1
- RETURN NIL
- * EOFcn SeekLast
-
-
-