home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-07-22 | 46.9 KB | 1,905 lines |
- * Filename: EXTENDB2.PRG
- * Program.: Additions to the Clipper Extended Library by Tom Rettig
- * Author..: John Kaster
- * Date....: September 2, 1986
- * Notice..: Placed in the public domain by John Kaster.
- * Clipper is a trademark of Nantucket.
- * FlashUp Windows is a trademark of The Software Bottling Company
- * of New York. It is an excellent Window, Screen and Help window
- * utility that can be used with many languages. Call them for
- * more information - they're not paying me for advertising.
- * Notes...: Since I wrote these functions and procedures for my own use, any
- * confusing abbreviations or code without comments is because I hate
- * documenting things already completed. If any coding is unclear,
- * you may direct questions to me on EXEC-PC BBS in Milwaukee at
- * 414/964-5160 (9600 baud capable, N, 8, 1; Kermit, Ymodem and Xmodem
- * support), or ACUMEN at 703-321-7441 (2400 baud).
- * If anyone has working FKLABEL(),NDX() functions, I would
- * appreciate a copy.
- *
- * Following is a list of user defined functions to extend Clipper's
- * abilities:
- *
- * New Functions Not found in Clipper
- * ASRCH() ::= Returns closest value to a target in a sorted array
- * CONFIRM() ::= Y/N, T/F question without READ
- * CSTRING() ::= character string of any data type
- * DEFAULT() ::= Gives a variable a default value
- * DELCOUNT() ::= # of records marked for deletion in current file
- * DIV() ::= integer division of n1 by n2
- * EDFUNC() ::= My editor function for DBEDIT in DBU.LIB
- * FEXISTS() ::= T/F if file with/without extension exists
- * FIELDNUM() ::= # of 'field' in currently used file
- * FRAME() ::= Border type for boxes
- * ISFOUND() ::= Is target in index
- * JUSTIFY() ::= space(difference b/n Field Length & Field Name)
- * KNT() ::= # of times a string occurs in Mem/Char field + 1
- * LOGIC() ::= Any part of 'Yes' or 'No ' value of logic variable
- * OS() ::= Tom Rettig's DOSVERS()
- * PERC() ::= 100 * Num1/Num2
- * RITE() ::= string of any variable, with two options
- * SPERC() ::= string of PERC()
- * SZERO() ::= string(Zero())
- * ULEN() ::= length of any type of variable
- * VALDIR() ::= is directory valid?
- * ZERO() ::= n1/n2 if n2#0, otherwise 0
- *
- * PROCEDURES
- * ALIST ::= print out array
- * ASORT ::= Sort an array of one type in A/D order
- * BOXCOL ::= Set the color for box frames
- * BOXIT ::= Draw a box on the screen
- * CNTR ::= Center text on a line
- * COL1 ::= Set the normal screen colors
- * COL2 ::= Set inverse screen colors for displaying GET fields
- * COPYVARS ::= Copy data from current record to new record
- * CORRECT ::= If get variables were updated, asks if correct
- * FORMFEED ::= Form feed for whatever output you have
- * GENSEEK ::= Generic seeking procedure (any index!)
- * INDEX ::= Revised Nantucket index.PRG
- * INITVARS ::= Initialize X<FieldName> memory vars from record
- * INSTALL ::= Generic installation procedure
- * LISTRECS ::= List records to the screen
- * OOPS ::= Flashing message centered on line 0
- * OPCHOICE ::= Select an output device and set it
- * OPTIONS ::= Options for EDFUNC()
- * PACKEM ::= generic pack utility
- * PRINTOFF ::= Output redirection procedure
- * PRINTON ::= Output redirection procedure
- * REPLVARS ::= Replace record with memory variable values
- * RESETINDEX ::= Generic index (re)setter
- * SELEFIELDS ::= Select fields from the current database
- * SELEFILE ::= Select a file from the current subdirectory
- * SELEREC ::= Select a record in a file
- * SETFILT ::= Set a filter
- * SHOWCLIP ::= Show status of Clipper environment
- * SHOWFIELDS ::= Show the fields in the currently selected database
- * SHOWFILES ::= Display the files on current subdirectory
- * SHOWREC ::= Shows list of fields at x,y w/ separator
- * SHOWSYS ::= Display the DOS system configuration
- * STATS ::= Closest I could get to dB3's display status
- * TITLE ::= Make a title on the screen
- *
- * Warnings: I recently optimized this since I got Tom Rettig's library for
- * Clipper, so some of the utilities that I used to have in here
- * I got rid of because his "C" or Assembler source code is faster.
- * If I inconvenience anyone by removing my slower Clipper-coded
- * routines, sorry . . . but these are MY routines, and I'll do what
- * conveniences me the most with them. Also, any serious Clipper
- * programmer should get Tom Rettig's library, anyway. The external
- * routines listed on the bottom of this file and used in some of
- * my routines are from Dirk Lesko's library (DL1B.ARC). Probably
- * any bulletin board you got this from will have them. If not,
- * try Rockland in New York, Exec-PC in Milwaukee, Darwin in D.C.,
- * or Acumen in Virginia.
- *
- * You can obtain a copy of Tom Rettig's Library from:
- * Tom Rettig Associates
- * 9300 Wilshire Boulevard, Suite 470
- * Beverly Hills, California 90212-3237
- * (213) 272-3784
- *
-
- FUNCTION DIV
- * Syntax: DIV( <ExpN1>, <ExpN2> )
- * Notes.: Returns int(<ExpN1>/<ExpN2>) if <ExpN2>#0, otherwise 0
- PARA ZN1,ZN2
- IF PCOUNT()<2
- RETURN (0)
- ENDIF
- IF ZN2=0
- RETURN (0)
- ENDIF
- RETURN ( INT(ZN1/ZN2))
-
- FUNCTION DELCOUNT
- * Syntax.: Delcount ( [<ExpC>] )
- * Returns: Number of records marked for deletion in the <ExpC> or current file
- *
- PARA D_File
- PRIV K,RetArea
- RetArea=ALIAS()
- IF PCOUNT()>0
- IF TYPE('D_File')='C'
- SELE &D_File
- ENDIF
- ENDIF
- SET DELE OFF
- COUN FOR DELETED() TO K
- SET DELE ON
- SELE &RetArea
- RETURN (K)
-
- FUNCTION FIELDNUM
- * Syntax: FIELDNUM( <ExpC> )
- * Return: The field number of <ExpC> in current DBF, or '0' if not found
- *
- PARAMETERS fldname
- PRIVATE Kount,fit
- KOUNT=1
- fit=0
- DO WHILE field(KOUNT)>' '.AND.fit=0
- IF trim(field(KOUNT))=trim(fldname)
- fit=Kount
- ENDIF
- KOUNT=KOUNT+1
- ENDDO
- RETURN (fit)
-
- FUNCTION JUSTIFY
- * Syntax: JUSTIFY ( <Exp?> )
- * Return: Number of spaces = the difference in Length b/n name of variable and
- * its contents
- PARAMETERS Width
- PRIVATE Difference
- IF TYPE('Width')='U'
- RETURN ('')
- ELSE
- Difference=len(Width)-ulen(Width)
- RETURN (space(abs(Difference)))
- ENDIF
-
- FUNCTION Logic
- * Syntax.: LOGIC( <ExpL>, [<length>] )
- * Return.: The leftmost <ExpN> of 'Yes' or 'No ', or 'Yes' or 'No ' + <length>
- * minus 3 spaces
- * Default: <length> = 3
- PARA YN,Lnth
- PRIV st
- IF Type('Lnth')='U'
- Lnth=3
- ENDIF
- IF YN
- st='Yes'
- ELSE
- st='No '
- ENDIF
- IF Lnth>3
- RETURN (st+space(Lnth-3))
- ELSE
- RETURN (LEFT(st,Lnth))
- ENDIF
-
- FUNCTION PERC
- * Syntax.: PERC( <ExpN1> , <ExpN2> )
- * Return.: 100 * <ExpN1> / <ExpN2>
- PARA Made,Att
- IF Type('Made')<>'N'.OR.Type('Att')<>'N'
- RETURN(0)
- ELSE
- RETURN(100*ZERO(Made,Att))
- ENDIF
-
- FUNCTION SPERC
- * Syntax.: SPERC( <ExpN1> , <ExpN2> , [<width>,[<decimal>]] )
- * Return.: str(100 * <ExpN1>/<ExpN2>,<width>,<decimal>)
- * Default: <width> = 7, <decimal> = 3
- PARA Made,Att,Wid,Dec
- IF type('Dec') # 'N'
- Dec=3
- ENDIF
- IF Type('Wid') # 'N'
- Wid=7
- ENDIF
- IF Type('Made')<>'N'.OR.Type('Att')<>'N'
- RETURN(repl('*',wid))
- ELSE
- RETURN(str(PERC(Made,Att),Wid,Dec))
- ENDIF
-
- FUNCTION Rite
- * Syntax.: RITE( <Exp?>, [<Delimiter>] )
- * Returns: A character string of <Exp?> either len(<Exp?>) long or the
- * "ALLTRIM( <Exp?> )"
- * Default: <Delimiter> = ''
- * Notes..: WPSTRIP is from Tom Rettig's library. I used it because the
- * C source code is faster than my Clipper version. If you don't
- * have WPSTRIP, look at my MEMOUTIL library's MEMOREPL or LINEWRAP
- * functions.
- PARA FldName,Delim
- PRIV St
- IF Type('Delim') # 'C'
- Delim=''
- ENDIF
- DO CASE
- CASE Delim='D'
- DO CASE
- CASE TYPE(FldName)='D'
- st=DTOC(&FldName)
- CASE TYPE(FldName)='N'
- st=ltrim(str(&FldName))
- CASE TYPE(FldName)='L'
- st=trim(logic(&FldName))
- CASE TYPE(FldName)='M'
- st=trim(WPSTRIP(FldName))
- OTHERWISE
- st=Alltrim(&FldName)
- ENDCASE
- st='"'+st+'"'
- OTHERWISE
- DO CASE
- CASE TYPE(FldName)='D'
- st=DTOC(&FldName)
- CASE TYPE(FldName)='N'
- st=str(&FldName)
- CASE TYPE(FldName)='L'
- st=logic(&FldName)
- CASE TYPE(FldName)='M'
- st=WPStrip(FldName)
- OTHERWISE
- st=&FldName
- ENDCASE
- ENDCASE
- RETURN (st)
-
- FUNCTION CSTRING
- * Syntax.: CSTRING ( <Exp?> )
- * Returns: Character string of any data type
- PARA S
- IF PCOUNT()<1
- RETURN ( "" )
- ENDIF
- DO CASE
- CASE TYPE('S')='U'
- RETURN ( "" )
- CASE TYPE('S')='L'
- RETURN ( IF(S,'Yes','No ') )
- CASE TYPE('S')='D'
- RETURN ( SUBSTR(CMONTH(S),1,3) )
- CASE TYPE('S')='N'
- RETURN ( STR(S) )
- ENDC
- RETURN ( S )
-
- FUNCTION Knt
- * Syntax.: KNT( <ExpM>, [<separator>] )
- * Return.: Number of words, or # of occurences of [<separator>] in <ExpM>
- * Default: <Separator> = space(1)
- PARA Targ,Sep
- IF Type('Sep') # 'C'
- Sep=' '
- ENDIF
- PRIV Kount,St
- Kount=0
- St=Targ
- IF Type('Targ')$'CM'
- DO WHILE AT(sep,st)>0
- Kount=Kount+1
- st=Right(st,len(st)-at(sep,st)-len(sep)+1)
- IF AT(sep,st)=1
- DO WHILE AT(Sep,st)=1
- st=Right(st,len(st)-at(sep,st)-len(sep)+1)
- ENDDO
- ENDIF
- ENDDO
- IF sep=' '
- Kount=Kount+1
- ENDIF
- ENDIF
- RETURN (Kount)
-
- PROCEDURE SHOWFIELDS
- * Syntax: DO SHOWFIELDS
- * Notes.: Displays the fields in the currently selected database
- PRIV I,FSTOP
- FSTOP=FCOUNT()
- BotLine=6+DIV(FSTOP,6)
- DO BOXIT WITH 4,0,BotLine,79,1
- FOR I=1 TO FSTOP
- DO COL1
- @ 5+DIV(I-1,6),5+MOD(i-1,6)*12 SAY type(Field(I))
- DO COL2
- ?? FIELD(I)
- NEXT
- DO COL1
- RETURN
-
- PROCEDURE SELEFIELDS
- * Syntax: DO SELEFIELDS
- * Notes.: Calls SHOWFIELDS, then allows you to select any and all fields in
- * the file and returns the field list in the array FLIST
- * Possible problems - does not detect for doubled variable selection,
- * because I didn't want to - maybe someone wants to use a field twice
- PARA FLIST,FNUM
- IF EMPTY(Alias())
- DO OOPS WITH 'No file has been selected'
- RETU
- ENDIF
- IF PCOUNT()<1
- DO OOPS WITH 'An array must be passed to SELEFIELDS'
- RETU
- ENDIF
- IF PCOUNT()<2
- FNUM=FCOUNT()
- ENDIF
- IF TYPE('FLIST')#'A'
- DO OOPS WITH 'An array must be passed to SELEFIELDS'
- RETU
- ENDIF
- PRIV Row,Col,LastLine,I,J
- DO COL1
- CLEA
- DO TITLE WITH 'Selecting fields from '+ALIAS()
- DO SHOWFIELDS
- i=1
- FStop=Fcount()
- IF DIV(FStop,6)=1
- LastLine=1
- ELSE
- LastLine=DIV(FStop,6)+1
- ENDIF
- @ 23,0 SAY 'Fields'
- SET COLO TO W+
- key=0
- FNUM=0
- DO WHIL key#27
- SET COLO TO W+
- @ 5+DIV(I-1,6),4+MOD(I-1,6)*12 SAY ''
- key=inkey(0)
- @ 5+DIV(I-1,6),4+MOD(I-1,6)*12 SAY ' '
- DO COL1
- DO CASE
- Case Key=HelpKey
- @ 0,0 SAY 'Move: arrows, [Home], [End]; [Enter] selects field, [D]elete field, [Esc] leaves'
- CASE Key=LfArrow
- i=IF(I>1,i-1,i)
- CASE Key=RtArrow
- i=IF(i<FStop,i+1,i)
- CASE Key=HomeKey
- i=1
- CASE Key=EndKey
- I=FCount()
- CASE Key=UpArrow
- i=IF(i-6>1,i-6,1)
- CASE Key=DnArrow
- i=if(I+6<Fcount(),i+6,Fcount())
- CASE (Key=68.OR.Key=100).AND.FNUM>0 && D or d
- FLIST[FNUM]=.F.
- FNUM=FNUM-1
- @ 23,7
- @ 24,0
- IF FNUM>0
- DO COL2
- @ 23,7 SAY FLIST[1]
- FOR J = 2 to FNUM
- ?? ','+trim(FLIST[J])
- NEXT
- DO COL1
- ENDIF
- CASE Key=13
- IF FNUM<FCOUNT()
- FNUM=FNUM+1
- FLIST[FNUM]=FIELD(I)
- i=IF(i<Fstop,i+1,1)
- @ 23,7
- DO COL2
- @ 23,7 SAY FLIST[1]
- FOR J = 2 to FNUM
- ?? ','+trim(FLIST[J])
- NEXT
- DO COL1
- ELSE
- DO OOPS WITH 'Attempted to select more fields than there are.'
- ENDIF
- ENDC
- ENDDO
- RETU
-
- FUNC FExists
- * Syntax: FExists ( <ExpC>, [<Ext>] )
- * Return: .T. if <ExpC> empty or it exists, .F. if not
- PARA File,Ext
- IF PCOUNT()<1
- RETURN ( .T. )
- ENDIF
- IF PCOUNT()<2
- Ext='.'
- ELSE
- IF TYPE('Ext')='C'
- Ext='.'+alltrim(Ext)
- ELSE
- Ext='.'
- ENDIF
- ENDIF
- IF ! EMPTY(File)
- RETURN ( File (IF(AT('.',File)=0,trim(File)+Ext,file)) )
- ENDIF
- RETURN ( .T. )
-
- PROCEDURE SHOWFILES
- * Syntax: DO SHOWFILES WITH [<Mask> [,<Array of Files> [,<# of Files> [,<Title>]]]]
- * Notes.: Returns the list of files in <Array of Files>
- PARA Mask,Files,Num,Title
- IF PCOUNT()<1
- Mask='*.*'
- ENDIF
- IF TYPE('Mask')#'C'
- Mask='*.*'
- ENDIF
- IF PCOUNT()<2
- DECLARE FILES[ADIR(Mask)]
- ENDIF
- IF TYPE('FILES')#'A'
- DECLARE FILES[ADIR(MASK)]
- ENDIF
- IF PCOUNT()<3
- Num=ADIR(Mask,Files)
- ENDIF
- IF TYPE('Num')#'C'
- Num=ADIR(Mask,Files)
- ENDIF
- DO ASort WITH Files,'A'
- IF TYPE('Title')#'C'
- Title='Directory of '+trim(Mask)+' Files'
- ENDIF
- DO COL1
- CLEA
- DO TITLE WITH Title
- DO BOXIT WITH 3,0,5+DIV(Num-1,5),79
- FOR I = 1 to num
- @ 4+DIV(I-1,5),5+MOD(i-1,5)*14 SAY Files[I]
- NEXT
- RETU
-
- PROCEDURE SELEFILE
- * Syntax: DO SHOWFILES WITH [<Mask>],[<FName>],[<Must exist?>],[<Title>]
- * Notes.: Returns the name of the file selected. Calls SHOWFILES
- PARA Mask,Selected,MustExist,Title
- PRIV Row,Col,LastLine,ValCon,Ext,Num,I,Prefix,SrchMask
- IF PCOUNT()<1
- Mask='*.*'
- ENDIF
- IF TYPE('Mask')#'C'
- Mask='*.*'
- ENDIF
- Selected=Mask
- SrchMask=''
- IF PCOUNT()<3
- MustExist=.F.
- ENDIF
- IF TYPE('MustExist')#'L'
- MustExist=.F.
- ENDIF
- IF MustExist
- ValCon='Selected'
- ELSE
- ValCon="''"
- ENDIF
- IF PCOUNT()<4
- Title='Directory of '+alltrim(Mask)+' files.'
- ENDIF
- DO WHIL '*' $ Selected
- Ext=''
- Mask=Selected
- IF ! '.*' $ Mask
- Ext=RIGHT(Mask,len(Mask)-AT('.',Mask))
- ENDIF
- DECLARE FILES[ADIR(Mask)]
- Num=0
- DO SHOWFILES WITH Mask,Files,Num,Title
- Insert=''
- DO CASE
- CASE '\' $ Mask
- p=len(mask)-2
- DO WHIL substr(mask,p,1)#'\'.AND.P>0
- p=p-1
- ENDDO
- IF P>0
- Insert=left(mask,p)
- ENDIF
- CASE ':' $ Mask
- p=len(mask)-2
- DO WHIL ( ! substr(mask,p,1) $ ':\').AND.P>0
- p=p-1
- ENDDO
- IF P>0
- Insert=left(mask,p)
- ENDIF
- ENDC
- IF ! Empty(Selected)
- I=ASRCH(Files,Selected)
- ENDIF
- IF DIV(Num,5)=1
- LastLine=1
- ELSE
- LastLine=DIV(Num,5)+1
- ENDIF
- @ 24,0 SAY 'File '
- SET COLO TO W+
- Selected=Files[I]
- key=0
- DO WHIL key#13.AND.key#27.AND.Num>0
- DO COL2
- @ 24,5
- @ 24,5 SAY Insert+trim(Files[I])+space(60-len(Insert+trim(files[i])))
- SET COLO TO W+
- @ 4+DIV(I-1,5),4+MOD(I-1,5)*14 SAY ''
- key=inkey(0)
- @ 4+DIV(I-1,5),4+MOD(I-1,5)*14 SAY ' '
- DO CASE
- Case Key=HelpKey
- DO COL1
- @ 0,0 SAY 'Move: arrows, [Home], [End]; [Enter] selects file, [Esc] to type in file'
- CASE Key=LfArrow
- i=IF(I>1,i-1,i)
- CASE Key=RtArrow
- i=IF(i<num,i+1,i)
- CASE Key=HomeKey
- i=1
- CASE Key=EndKey
- I=Num
- CASE Key=UpArrow
- i=IF(i-5>1,i-5,1)
- CASE Key=DnArrow
- i=if(I+5<Num,i+5,Num)
- CASE Key=13
- Selected=Files[I]
- CASE Key>31.AND.Key<127
- IF KEY#32
- SrchMask=SrchMask+UPPER(CHR(key))
- I=ASCAN(Files,SrchMask)
- I=IF(I=0,ASRCH(Files,SrchMask),I)
- ELSE
- SrchMask=''
- ENDIF
- ENDC
- ENDDO
- IF num>0
- Selected=Insert+trim(Files[I])+space(60-len(Insert+trim(files[i])))
- ELSE
- Selected=space(60)
- ENDIF
- DO COL1
- @ 0,0
- IF Key#13
- @ 24,5
- @ 24,5 GET Selected PICT '@K!' VALI FExists(&ValCon,Ext)
- READ
- ENDIF
- ENDDO
- RETU
-
- PROCEDURE INDEX
- * Syntax: DO INDEX
- * Notes.: Revised code from Nantucket
- IF EMPTY(ALIAS())
- DBFile=space(20)
- DO SELEFILE WITH '*.DBF',DBFile,.T.,'Select a data file to index'
- IF EMPTY(DBFILE)
- RETU
- ENDIF
- USE &DBFile
- ENDIF
- NDXFile=space(20)
- DO SELEFILE WITH '*.NTX',NDXFile,.F.,'Select an index file name'
- IF EMPTY(NDXFile)
- RETU
- ENDIF
- IF FILE(NDXFile)
- USE &DBFile INDE &NDXFile
- Key=INDEXKEY(0)
- ENDIF
- CLEA
- DO TITLE WITH 'Creating an index file'
- @ 12,0 SAY 'Key expression: ' GET Key
- READ
- INDEX ON &key TO &ntx
- ? RECCOUNT(), " Records indexed"
- RETU
-
- PROCEDURE TITLE
- * Syntax.: DO TITLE WITH <Title>, [<starting line>]
- * Notes..: Clears line 1 and 2 and centers <Title> on line 1
- PARAMETER Ttl,start
- IF TYPE('Start')<>'N'
- Start=1
- ENDIF
- @ Start,0
- @ Start+1,0
- BFrame = '┌ ┐│╛═╘│'
- Cent=INT(len(Ttl)/2)
- BotLine=INT(FCOUNT()/6+5)
- IF ISCOLOR()
- SET COLOR TO RB/N
- ELSE
- SET COLOR TO W/N
- ENDIF
- @ Start,40-cent-2,Start+1,40+cent+IF(LEN(Ttl)/2=INT(len(Ttl)/2),1,2) BOX Bframe
- SET COLO TO W+/N
- @ Start,40-cent-1 SAY ' '+Ttl+' '
- DO COL1
- RETURN
-
- PROCEDURE OOPS
- * Syntax.: DO OOPS WITH <Message>
- * Notes..: Centers <Message> on line 24, and flashes it until a key is pressed
- PARAMETER Mess
- IF ISCOLOR()
- SET COLOR TO R+*/N
- ELSE
- SET COLOR TO W+*/N
- ENDIF
- @ 0,40-len(Mess)/2 SAY Mess
- key=inkey(0)
- DO COL1
- @ 0,40-len(mess)/2 say space(Len(Mess))
- RETURN
-
- PROCEDURE PRINTOFF
- * Syntax.: DO PRINTOFF
- * Notes..: Assumes a public variable OUTPUT of type Character
- * Default: OUTPUT = 'S'creen
- IF TYPE('OUTPUT') # 'C'
- OUTPUT='S'
- ENDIF
- IF OUTPUT='S'
- WAIT
- CLEA
- ENDIF
- SET ALTERNATE OFF
- SET PRINT OFF
- IF OUTPUT='D'
- CLOSE ALTERNATE
- ENDIF
- OUTPUT='S'
- SET CONSOLE ON
- RETURN
-
- PROCEDURE PRINTON
- * Syntax.: DO PRINTON
- * Notes..: Assumes a public variable OUTPUT as type 'C' for "S"creen, "P"rinter,
- * or "D"isk
- * Default: OUTPUT = 'S'creen
- IF TYPE('OUTPUT') = 'U'
- PUBLIC OUTPUT
- OUTPUT='S'
- ENDIF
- IF TYPE('OUTPUT') # 'C'
- OUTPUT='S'
- ENDIF
- SET PRINT OFF
- SET CONSOLE OFF
- SET ALTERNATE OFF
- DO CASE
- CASE UPPER(OUTPUT)='D'
- SET ALTERNATE ON
- CASE UPPER(OUTPUT)='P'
- IF ISPRINT()
- SET PRINT ON
- ELSE
- ?? chr(7)
- @ 0,0 SAY 'Hit any key when the printer is ready. [Esc] for Screen output.'
- key=inkey(0)
- DO WHILE Key#27 .AND. (! ISPRINT())
- KEY=INKEY(0)
- ENDDO
- IF Key=27
- SET CONS ON
- OUTPUT='S'
- Pause=.T.
- @ 24,0 SAY 'Pause for each page (Y/N)? ' GET Pause
- READ
- @ 24,0
- ENDIF
- @ 0,0
- ENDIF
- OTHE
- SET CONSOLE ON
- ENDCASE
- RETURN
-
- FUNCTION edfunc
- * Syntax: Controlled by DBEDIT() in DBU.LIB
- * Notes.: Powerful browsing function utility (more than dBASE has!)
- PARAMETERS mode,i
- PRIVATE cur_field,Key
- Key=LastKey()
-
- * get the name of the current field into a regular variable
- cur_field = field_list[i]
-
- * ?? 'before case'
- * inkey(0)
- DO CASE
-
- CASE mode = 0
- * idle mode..display record number
- @ 0,0 SAY "Record " + STR(RECNO(),7)
- RETURN(1)
- CASE mode = 1
- DO OOPS WITH "Top of file."
- inkey(1)
- RETURN(1)
- CASE mode = 2
- Cor=.N.
- Key=Row()+1
- @ Key,0 SAY 'Add another record (Y\N)? ' GET Cor
- READ
- @ Key,0
- IF Cor
- APPE BLAN
- ENDIF
- RETURN(1)
- CASE mode < 4
- * case action can be implemented for each mode
- RETURN(1)
- * mode 4..a keystroke not handled by DBEDIT
- CASE Key = 27 && Esc
- * escape key..quit
- RETURN(0)
- CASE Key = 21 &&CtrlU
- IF DELETED()
- RECA
- ELSE
- DELE
- ENDIF
- RETURN (2)
- CASE Key = 28 && Help Key
- SAVE SCREEN TO EDFUNC1
- DO BOXCOL
- @ 0,0 SAY '╔══════════════════╦═════════════════════╦══════════════╦════════════════════╗'
- @ 1,0 SAY '║ CURSOR <-- --> ║ UP DOWN ║ DELETE ║ Insert Mode: Ins ║'
- @ 2,0 SAY '║ Char: '+chr(26)+' ║ Record: ║ Char: Del ║ Exit: Esc ║'
- @ 3,0 SAY '║ Field: Home End ║ Page: PgUp PgDn ║ Field: ^Y ║ Abort: Alt-C ║'
- @ 4,0 SAY '║ Pan: ^End ^Home║ File: ^PgUp ^PgDn ║ Record: ^U ║ ║'
- @ 5,0 SAY '║ Pan: ^ ^'+chr(26)+' ║ Help: F1 ║ ║ Set Options: ^Enter║'
- @ 6,0 SAY '╚══════════════════╩═════════════════════╩══════════════╩════════════════════╝'
- DO BOXIT WITH 7,20,9,60,2
- DO CNTR WITH '[Ctrl-──┘] for other options',8
- key=inkey(0)
- RESTORE SCREEN FROM EDFUNC1
- IF key=10
- DO OPTIONS
- RETURN (2)
- ELSE
- RETURN (1)
- ENDIF
- CASE Key = 10 && Ctrl-Enter
- DO OPTIONS
- RETURN (2)
- CASE (Key >31 .AND. Key<127) .OR. Key=13 && Valid ASCII Character
- @ ROW(), COL() GET &cur_field
- IF Key#13
- KEYBOARD chr(Key)
- ENDIF
- READ
- KEYBOARD chr(4) &&Right Arrow
- RETURN (2)
- OTHE
- RETURN (1)
- ENDCASE
- RETURN (1)
-
- PROCEDURE OPTIONS
- * Syntax: DO OPTIONS
- * Notes.: List of options and executions for browsing. Called from EDFUNC()
- PRIV I,Key
- SAVE SCREEN TO OPT1
- DO BOXIT WITH 0,0,6,79,2
- DO CNTR WITH '[F1] - Reset index order [F2] - seek with active index ',1
- DO CNTR WITH '[F3] - DELETE FOR condition [F4] - DELETE WHILE condition ',2
- DO CNTR WITH '[F5] - RECALL FOR condition [F6] - RECALL WHILE condition ',3
- DO CNTR WITH '[F7] - REPLACE FOR condition [F8] - REPLACE WHILE condition',4
- DO CNTR WITH '[F9] - LOCATE FOR condition [F10] - CONTINUE LOCATE ',5
- Key=inkey(0)
- IF TYPE('Cond') = 'U'
- PUBL Cond
- Cond=space(140)
- ENDIF
- IF TYPE('Cond') # 'C'
- Cond=space(140)
- ENDIF
- @ 0,0 SAY CLS()
- DO CASE
- CASE Key = 28 &&F1
- DO RESETINDEX
- CASE Key = -1 &&F2
- DO GENSEEK
- CASE Key = -2 &&F3
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the DELETING FOR condition'
- @ 23,0 SAY 'Filter ' GET Cond
- READ
- IF ! Empty(Cond)
- DELE FOR &Cond
- ENDIF
- CASE Key = -3 &&F4
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the DELETING WHILE condition'
- @ 23,0 SAY 'Filter ' GET Cond
- READ
- IF ! Empty(Cond)
- DELE WHIL &Cond
- ENDIF
- CASE Key = -4 &&F5
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the RECALLING FOR condition'
- @ 23,0 SAY 'Condition' GET Cond
- READ
- IF ! Empty(Cond)
- RECA FOR &Cond
- ENDIF
- CASE Key = -5 &&F6
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the RECALLING WHILE condition'
- @ 23,0 SAY 'Condition' GET Cond
- READ
- IF ! Empty(Cond)
- RECA WHIL &Cond
- ENDIF
- CASE Key = -6 && F7
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the REPLACING FOR condition'
- FN=space(11)
- Exp=SPACE(120)
- @ 22, 0 SAY 'REPL ' GET FN PICT '@!' VALI TYPE(FN)#'U' .OR. EMPTY(FN)
- @ 22,20 SAY 'WITH ' GET Exp PICT '@S59'
- @ 23, 0 SAY 'FOR ' GET Cond
- READ
- IF ! (EMPTY(FN).OR.EMPTY(Exp).OR.EMPTY(Cond))
- REPL &FN WITH &Exp FOR &Cond
- ENDIF
- CASE Key = -7 && F8
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the REPLACING WHILE condition'
- FN=space(11)
- Exp=SPACE(60)
- @ 22, 0 SAY 'REPL ' GET FN PICT '@!' VALI TYPE(FN)#'U' .OR. EMPTY(FN)
- @ 22,20 SAY 'WITH ' GET Exp PICT '@S59'
- @ 23, 0 SAY 'WHILE ' GET Cond
- READ
- IF ! (EMPTY(FN).OR.EMPTY(Exp).OR.EMPTY(Cond))
- DO WHIL &Cond
- Currec=recno()
- SKIP
- nextrec=recno()
- SKIP -1
- REPL &FN WITH &Exp
- GOTO Nextrec
- ENDDO
- ENDIF
- CASE Key = -8 &&F9
- DO SHOWFIELDS
- DO TITLE WITH 'Enter the LOCATING FOR condition'
- @ 23,0 SAY 'Condition' GET Cond
- READ
- IF ! Empty(Cond)
- LOCA FOR &Cond
- ENDIF
- CASE Key = -9 &&F10
- CONTINUE
- ENDC
- REST SCREEN FROM OPT1
- RETU
-
- PROCEDURE RESETINDEX
- * Syntax: DO RESETINDEX
- * Notes.: Allows you to change the master index on any active index files
- PRIV I
- SAVE SCREEN TO RES1
- @ 0,0 SAY CLS()
- DO TITLE WITH 'Resetting index order'
- @ 4,0 SAY 'Current index: '+IndexKey(0)
- Key=1
- I = 1
- DO WHIL ! Empty(IndexKey(Key))
- ? 'Index',str(Key,2),':',IndexKey(Key)
- I= IIF (IndexKey(0)=IndexKey(key),key,i)
- key=key+1
- ENDDO
- IF ! Empty(IndexKey(0))
- @ 24,0 SAY 'Select index number: ' GET I PICT '9' RANG 0,Key
- READ
- SET ORDER TO I
- ENDIF
- REST SCREEN FROM RES1
- RETU
-
- PROCEDURE GENSEEK
- * Syntax: DO GENSEEK
- * Notes.: Allows you to do a seek on the active index. Dynamically
- * determines the picture clause to use depending on the index
- * expression.
- PRIV INK,PC
- SAVE SCREEN TO GENSEEK1
- @ 0,0 SAY CLS()
- DO TITLE WITH 'Seeking with active index on data file '+Alias()
- IF ! EMPTY(INDEXKEY(0))
- INK=INDEXKEY(0)
- INK=&INK
- ENDIF
- DO CASE
- CASE EMPTY(INDEXKEY(0))
- @ 4,0 SAY 'No index active.'
- Key=0
- @ 24,0 SAY 'Record number to go to ' GET Key PICT '9999999' RANG 0,RecCount()
- READ
- IF ! Empty(Key)
- GOTO Key
- ENDIF
- CASE TYPE('INK')='N'
- @ 4,0 SAY 'Index key: '+INDEXKEY(0)
- INK=str(INK)
- IF AT('.',INK)>0
- PC=REPL('9',AT('.',INK)-1)+'.'+REPL('9',LEN(INK)-AT('.',INK))
- ELSE
- PC=REPL('9',LEN(INK))
- ENDIF
- INK = 0
- @ 24,0 SAY 'Seek ' GET INK PICT '&PC'
- READ
- SEEK INK
- CASE TYPE('INK')='C'
- @ 4,0 SAY 'Index key: '+INDEXKEY(0)
- PC=REPL('X',LEN(INK))
- @ 24,0 SAY 'Seek ' GET INK PICT '&PC'
- READ
- SEEK trim(INK)
- CASE TYPE('INK')='D'
- @ 4,0 SAY 'Index key: '+INDEXKEY(0)
- @ 24,0 SAY 'Seek ' GET INK PICT '@D'
- READ
- SEEK INK
- ENDC
- RESTORE SCREEN FROM GENSEEK1
- RETU
-
- PROCEDURE FORMFEED
- * Syntax: DO FORMFEED
- * Notes.: Assumes a public variable OUTPUT declared as character
- DO CASE
- CASE OUTPUT='S'
- IF PAUSE
- DO CNTR WITH 'Hit a key'
- inkey(0)
- ENDIF
- CLEA
- CASE OUTPUT = 'D'
- ?? chr(12)
- CASE OUTPUT = 'P'
- EJEC
- ENDC
- RETU
-
- FUNCTION ULEN
- * Syntax: ULEN ( <ExpC> )
- * Return: The length of any variable (variable name is passed as character),
- * 0 if undefined variable
- PARA var
- IF PCOUNT()<1
- RETURN ( 0 )
- ENDIF
- RETURN len(CSTRING(Var))
-
- PROCEDURE CNTR
- * Syntax: DO CNTR WITH <Text>, [<Line>]
- * Notes.: Centers <Text> on <Line>. <Line> defaults to 0
- *
- PARA Text,Line
- IF Pcount()<2
- Line=0
- ENDIF
- @ Line,40-len(text)/2 SAY text
- RETU
-
- PROCEDURE CORRECT
- * Syntax: DO CORRECT
- * Notes.: Assumes a public variable COR. Changes COR to .F. if the current
- * GET variables have been updated, then prompts for correctness.
- Cor=IF(UPDATED(),.N.,.T.)
- @ 24,0
- @ 24,0 SAY 'Is everything correct (Y\N) ? ' GET Cor
- READ
- @ 24,0
- RETU
-
- PROCEDURE SHOWCLIP
- * Syntax: DO SHOWCLIP
- * Notes.: Shows the status of the Clipper environment. Uses Tom Rettig's
- * Library.
- ? 'ALTERNATE: ',UNTRIM(STATUS('ALTERNATE'),3)
- ?? ' BELL: ',UNTRIM(STATUS('BELL'),3)
- ?? ' CONFIRM: ',UNTRIM(STATUS('CONFIRM'),3)
- ?? ' CONSOLE: ',UNTRIM(STATUS('CONSOLE'),3)
- ?? ' DECIMAL: ',STR(STATUS('DECIMAL'),3)
- ? 'DEFAULT: ',UNTRIM(STATUS('DEFAULT'),3)
- ?? ' DELETED: ',UNTRIM(STATUS('DELETED'),3)
- ?? ' DELIMSTAT: ',UNTRIM(STATUS('DELIMSTAT'),3)
- ?? ' DELIMCHRS: ',UNTRIM(STATUS('DELIMCHRS'),3)
- ?? ' DEVICE: ',STATUS('DEVICE')
- ? 'ESCAPE: ',UNTRIM(STATUS('ESCAPE'),3)
- ?? ' EXACT: ',UNTRIM(STATUS('EXACT'),3)
- ?? ' FIXED: ',UNTRIM(STATUS('FIXED'),3)
- ?? ' INTENSITY: ',UNTRIM(STATUS('INTENSITY'),3)
- ?? ' MARGIN: ',STR(STATUS('MARGIN'),3)
- ? 'PATH: ',UNTRIM(STATUS('PATH'),3)
- ?? ' PRINT: ',UNTRIM(STATUS('PRINT'),3)
- RETURN
-
- PROCEDURE STATS
- * Syntax: DO STATS
- * Notes.: Closest emulation of dBASE's DISPLAY STATUS I could think of
- PRIV Ret_Area,Cur_AREA,i,J,K
- SAVE SCREEN TO STAT1
- IF Empty(Alias())
- @ 24,0 SAY 'No files in use.'
- inkey(0)
- ENDIF
- @ 0,0 CLEA
- Ret_Area=ALIAS()
- ? 'Current work area: ',Ret_Area
- ? 'Current index key: ',IndexKey(0)
- K=0
- FOR I=1 to 10
- IF ! EMPTY(Alias(I))
- K=K+1
- IF K>3
- K=0
- inkey(0)
- ENDIF
- Cur_Area=Alias(I)
- SELE &Cur_Area
- ? 'Work area',str(i,2),'database:',Alias(I)
- ? 'Number of records:',reccount()
- ? 'Current record: ',recno()
- ? 'Master index key: ',INDEXKEY(0)
- FOR J=1 to 7
- IF ! Empty(Index(J))
- ? 'Index',str(j,1),'key:',INDEXKEY(J)
- ENDIF
- NEXT
- ?
- ENDIF
- NEXT
- inkey(0)
- SELE &Ret_Area
- @ 0,0 CLEA
- DO SHOWSYS
- inkey(0)
- DO SHOWCLIP
- inkey(0)
- i='I'
- DO WHIL ! EMPTY(I)
- ACCEPT 'Expression to evaluate: ' TO I
- IF ! EMPTY(I)
- ? i,':',&i
- ENDIF
- ENDDO
- RESTORE SCREEN FROM STAT1
- RETU
-
- PROCEDURE PACKEM
- * Syntax: DO PACKEM
- * Notes.: Will use DELCOUNT() to count the deleted records in the file if
- * RecCount()<1000, otherwise prompts for it. Prompts for Packing.
- PRIV BP
- DO COL1
- IF EMPTY(Alias())
- DO CNTR WITH 'No file in use',0
- inkey(0)
- @ 0,0
- ENDIF
- CLEA
- DO TITLE WITH 'Packing the '+Alias()+' datafile'
- DO BOXIT WITH 4,10,8,70
- BP=RecCount()
- Cor=.Y.
- IF BP>1000
- @ 24,0 SAY ltrim(str(BP))+' records. Count deleted ones (Y/N)? ' GET Cor
- READ
- @ 24,0
- ENDIF
- IF Cor
- @ 5,22 SAY 'Records to remove: '
- K=DelCount()
- ?? ltrim(str(K))
- ELSE
- K=1
- ENDIF
- DO CNTR WITH 'Packing '+Alias()+' will remove all deleted records.',7
- IF K>0
- Cor=.Y.
- @ 6,22 SAY 'Go ahead and pack (Y/N)? ' GET Cor
- READ
- IF Cor
- PACK
- DO OOPS WITH ltrim(str(BP-RecCount()))+' records removed.'
- ENDIF
- ELSE
- inkey(0)
- ENDIF
- RETU
-
- PROCEDURE SETFILT
- * Syntax: DO SETFILT
- * Notes.: Allows you to set a filter with limited help. Assumes public
- * FiltCond
- IF EMPTY(Alias())
- DO CNTR WITH 'No file selected',24
- inkey(0)
- RETU
- ENDIF
- IF TYPE('FiltCond')='C'
- @ 12,0 SAY 'Current filter: '+FiltCond
- Cor=.Y.
- @ 24,0 SAY 'Use current filter (Y\N)? ' GET Cor
- READ
- IF Cor
- RETU
- ENDIF
- ELSE
- FiltCond=space(140)
- ENDIF
- Ans=1
- DECL FI[1]
- FI[1]=space(11)
- DO COL1
- CLEA
- DO WHIL ANS#0
- @ 1, 0 PROMPT 'Edit' MESSAGE 'Edit the filter'
- @ 1,10 PROMPT 'Field' MESSAGE 'Select a field'
- @ 1,20 PROMPT 'Help' MESSAGE 'Get help in creating filter'
- @ 1,30 PROMPT 'Quit' MESSAGE 'Filter is finished'
- MENU TO ANS
- DO CASE
- CASE Ans = 1
- @ 22,0 SAY CLS()
- @ 22,0 SAY 'Filter: ' GET FiltCond
- READ
- CASE Ans = 2
- SAVE SCREEN TO FILT1
- DO SELEFIELDS WITH FI,FCount()
- RESTORE SCREEN FROM FILT1
- FiltCond=untrim(trim(FiltCond)+FI[1],140)
- @ 22,0 SAY CLS()
- @ 22,0 SAY 'Filter: '
- DO COL2
- ?? FiltCond
- DO COL1
- KEYBOARD 'E'+chr(6) && end key
- CASE Ans = 3
- SAVE SCREEN TO FILT1
- @ 0,0 CLEA
- DO BOXIT WITH 0,0,15,79
- DO CNTR WITH 'Conditions Common functions ',1
- DO CNTR WITH '! negates str(pi,4,2) = "3.14", etc.',2
- DO CNTR WITH '.NOT. negates dtoc(Christmas) = "12/25/87" ',3
- DO CNTR WITH '.AND. dtos(Christmas) = "19871225" ',4
- DO CNTR WITH '.OR. ctod("12/25/87") = Christmas ',5
- DO CNTR WITH '() nest conditions upper("John") = "JOHN" ',6
- DO CNTR WITH '$ text string contained in left("12345",2) = "12" ',7
- DO CNTR WITH '# not equal to right("12345",2) = "45" ',8
- DO CNTR WITH '<,>,= same meanings substr("123",2,1) = "2" ',9
- DO CNTR WITH 'Examples',11
- DO CNTR WITH '"JOHN" $ UPPER(First) means "is JOHN in First" ',12
- DO CNTR WITH 'Datefield > CTOD("12/25/87") means "Datefield > Christmas" ',13
- DO CNTR WITH '(N1 > N2) .AND. (N4 = N3) ',14
- inkey(0)
- RESTORE Screen FROM FILT1
- KEYBOARD 'E'+chr(6) && end key
- CASE Ans = 4
- Ans = 0
- ENDC
- ENDDO
- IF ! EMPTY(FiltCond)
- SET FILT TO &FiltCond
- ENDIF
- RETU
-
- PROCEDURE OPCHOICE
- * Syntax: DO OPCHOICE
- * Notes.: Determines where output is going: Disk, Printer, or Screen
- * Assumes a public character variable called OUTPUT for other
- * procedures such as PrintOn, PrintOff, and FormFeed
- PRIVATE ANSWER
- ANSWER=0
- @ 23,0 CLEA
- @ 23,0 PROMPT 'Printer' MESSAGE 'Select output to the printer'
- @ 23,10 PROMPT 'Screen' MESSAGE 'Select output to the screen'
- @ 23,20 PROMPT 'Disk' MESSAGE 'Select output to a disk file'
- @ 23,30 PROMPT 'Quit' MESSAGE "Don't select an output device and quit"
- MENU TO ANSWER
- @ 23,0 CLEA
- DO CASE
- CASE ANSWER=1
- OUTPUT='P'
- CASE ANSWER=2
- OUTPUT='S'
- Pause=.F.
- @ 23,0 SAY 'Pause for each page (Y/N)? ' GET Pause
- READ
- CASE ANSWER=3
- OUTPUT='D'
- * sets up the ALTERNATE file to a disk file name after verifying
- * an overwrite if the file exists
- Cor=.N.
- File=space(20)
- DO SELEFILE WITH '*.TXT',File,.N.,'Select a file for output. "*" in filename for a new directory'
- IF ! EMPTY(File)
- SET ALTE TO &File
- ELSE
- OUTPUT='S'
- ENDIF
- ENDC
- RETU
-
- FUNC ZERO
- * Syntax: Zero( <ExpN1>, <ExpN2> )
- * Notes.: Returns <ExpN1>/<ExpN2> if <ExpN2>#0, otherwise 0
- PARA ZN1,ZN2
- IF PCOUNT()<2
- RETURN (0)
- ENDIF
- IF ZN2=0
- RETURN (0)
- ENDIF
- RETURN ( ZN1/ZN2)
-
- FUNC SZERO
- * Syntax: Sero( <ExpN1>, <ExpN2> )
- * Notes.: Returns string of Zero(<ExpN1>,<ExpN2>)
- PARA ZN1,ZN2
- IF PCOUNT()<2
- RETURN ('')
- ENDIF
- RETURN ( ZERO(ZN1,ZN2) )
-
- PROCEDURE INITVARS
- * Syntax: DO INITVARS
- * Notes.: Copies the data from the current record to memory variables of the same
- * name
- PRIV I,FN
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- IF TYPE('X&FN')='U'
- PUBL X&FN
- ENDIF
- X&FN = &FN
- NEXT
-
- PROCEDURE REPLVARS
- * Syntax: DO REPLVARS
- * Notes.: Copies the data from the memory variables to the field in the
- * current record of the same name
- PRIV I,FN
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- IF TYPE('X&FN')#'U'
- REPL &FN WITH X&FN
- ENDIF
- NEXT
- RETU
-
- PROCEDURE COPYVARS
- * Syntax: DO COPYVARS
- * Notes.: Copies the data from the current record to a new record
- PRIV I,FN
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- X&FN = &FN
- NEXT
- APPE BLAN
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- REPL &FN WITH X&FN
- NEXT
- RETU
-
- PROC BOXCOL
- * Syntax: DO BOXCOL
- * Notes.: Sets the box color for color or monochrome systems
- IF ISCOLOR()
- SET COLO TO GR/N
- ELSE
- SET COLO TO W/N
- ENDIF
- RETU
-
- PROC COL1
- * Syntax: DO COL1
- * Notes.: Sets the normal screen for color or monochrome systems
- IF ISCOLOR()
- SET COLO TO GR+/N,W+/B,,,W/B
- ELSE
- SET COLO TO W+/N,N/W,,,B/N
- ENDIF
- RETU
-
- PROC COL2
- * Syntax: DO COL2
- * Notes.: Sets the inverse (GET field) screen for color or monochrome systems
- IF ISCOLOR()
- SET COLO TO W/B
- ELSE
- SET COLO TO B/N
- ENDIF
- RETU
-
- FUNC FRAME
- * Syntax.: Frame ( <ExpC> )
- * Returns: A Frame Border type
- PARA Border
- PRIV BFrame
- IF PCOUNT()<1
- Border=1
- ENDIF
- DO CASE
- CASE Border=0
- Bframe = " "
- CASE Border=2
- BFrame = "╔═╗║╝═╚║"
- CASE Border=3
- BFrame = "╒═╕│╛═╘│"
- CASE Border=4
- BFrame = "╓─╖║╜─╙║"
- CASE Border=5
- BFrame = "▄▄▄█▀▀▀█"
- CASE Border=6
- BFrame = "▄▄▄▐▀▀▀▌"
- CASE Border=7
- BFrame = "████████"
- CASE Border=8
- BFrame = "▓▓▓▓▓▓▓▓"
- CASE Border=9
- BFrame = "▒▒▒▒▒▒▒▒"
- CASE Border=10
- BFrame = "░░░░░░░░"
- CASE Border=11
- BFrame = "┌ ┐│╛═╘│"
- OTHE
- Bframe = "┌─┐│┘─└│"
- ENDC
- RETURN BFrame
-
- PROC BOXIT
- * Syntax.: DO BOXIT WITH <Top>, <Left>, <Bottom>, <Right>,[<Border>,[<Clear>]]
- * Notes..: Creates a box at the above locations with <Border>
- PARAMETERS Top,Left,Bottom,Right,Border,Clear
- IF TYPE("Border")#"N"
- Border=1
- ENDIF
- IF TYPE("Right")#"N".OR.TYPE("Left")#"N".OR.TYPE("Top")#"N".OR.TYPE("Bottom")#"N"
- RETURN
- ENDIF
- IF TYPE("Clear")#"C"
- Clear=''
- ENDIF
- DO BOXCOL
- @ Top,left CLEA TO Bottom,Right
- IF Border#0
- @ Top,left,bottom,right BOX Frame(Border)+Clear
- ENDIF
- DO COL1
- RETU
- * EOP: Procedure BOXIT
-
- FUNCTION DEFAULT
- * Syntax: Default( <Variable to initialize>, <Value> )
- * Notes.: Initializes a variable with the value passed with it. If the
- * type of the variable is in conflict with the value, the variable
- * will be initialized to the value
- PARA IV,PV
- IF PCOUNT()<2
- RETURN ( .F. )
- ENDIF
- IF TYPE('IV')='U'
- RETURN ( PV )
- ENDIF
- IF TYPE('IV')#TYPE('PV')
- RETURN ( PV )
- ENDIF
- RETURN (IV)
-
- PROC ALIST
- * Syntax: DO ALIST WITH <AR>
- * Notes.: Lists the array <AR> to the output device
- *
- PARA AR
- PRIV TotElem
- IF PCOUNT()<1
- RETURN
- ENDIF
- IF TYPE('AR')#'A'
- RETURN
- ENDIF
- TotElem=Len(AR)
- FOR I = 1 to TotElem
- ? I,AR[I]
- NEXT
- RETURN
-
- PROC ASORT
- * Syntax: DO Asort WITH <Array> [,<Order>]
- * Notes.: Returns sorted array if all elements in the array are the same type.
- * I attempted doing this as a function, but evidently the pointers got
- * as confused as I did, and it would not RETURN the array correctly.
- PARA AR,Order
- PRIV CurEl,MovEl,I,Expression,TotElem
- Expression='AR[I]<AR[CurEl]' && This expression is used to evaluate an
- * ascending or descending sort
- DO CASE
- CASE PCOUNT()<1
- RETURN &&( '' )
- CASE TYPE('AR')#'A'
- RETURN &&( AR )
- CASE Pcount()=2
- IF Type('Order')='C'
- * Assigning sorting order
- Expression=IF(UPPER(Order)='D','AR[CurEl]<AR[I]','AR[I]<AR[CurEl]')
- ENDIF
- ENDC
- TotElem=LEN(AR)
- FOR CurEl = 2 TO TotElem
- i=1
- DO WHIL &Expression && You don't need the out-of-dimension test because
- i=i+1 && the last element will be equal to itself. There
- ENDDO && is no way to go beyond TotElem.
- IF CurEl#I && Have to move element
- MovEl=AR[CurEl] && Assigning element to temp variable
- ADel(AR,CurEl) && Removing it from where it was in the array
- AIns(AR,I) && Making a blank space for it
- AR[i]=MovEl && Putting the element back in
- ENDIF
- NEXT
- RETURN &&( AR )
-
- FUNC ASRCH
- * Syntax: Asrch( <Array>,<Targ> )
- * Notes.: Returns the number in the array closest to the target
- * Assumes the array is sorted in Ascending or Descending order
- PARA AR,Targ
- PRIV I,TotElem,Hi,Lo,Direction,Mid
- IF PCOUNT()<2
- RETURN ( 0 )
- ENDIF
- IF TYPE('AR')#'A'
- RETURN ( 0 )
- ENDIF
- TotElem=Len(AR)
- IF TotElem<2
- RETURN ( 1 )
- ENDIF
- Mid=INT(TotElem/2)
- Hi=TotElem
- Lo=1
- DO WHIL HI-LO>1
- DO CASE
- CASE AR[Mid]=Targ
- Hi=Mid
- Lo=Mid
- CASE AR[Mid]<Targ
- Lo=Mid
- Mid=INT((Hi+Lo)/2)
- OTHE
- Hi=Mid
- Mid=INT((Hi+Lo)/2)
- ENDC
- ENDDO
- RETURN ( Mid )
-
- PROCEDURE SHOWSYS
- * Syntax: DO ShowSys
- * Notes.: Shows DOS and System configurations
- ? 'Operating system: DOS',OS()
- ? 'Free memory: ',alltrim(str(Mem())),'Bytes'
- ? 'Current directory: ',Curdir(CurDrive())
- ? 'Disk type: ',IF(ISFIXED(CurDrive()),'Hard','Floppy')
- ? 'Current date: ',CDOW(Date())+',',DTOW(Date())
- ? 'Current time: ',AMPM(Time())
- ? 'Display type: ',IF(IsColor(),'Color','Monochrome')
- ? 'Configured Buffers: ',alltrim(str(Buffers(),3,0))
- ? 'Configured Files: ',alltrim(str(Files(),3,0))
- ? 'Configured Last drive: ',LastDrive()
- RETU
-
- PROCEDURE INSTALL
- * Syntax.: DO INSTALL [ WITH <Configuration file> ]
- * Notes..: Allows the user to install their system
- PARA CONFIG
- IF TYPE('WorkDir')='U'
- PUBL WorkDir,SysDir,SrchPath,BackDir
- ENDIF
- IF Type('OUTPUT')='U'
- PUBL Output,Cor
- Output='S'
- Cor=.F.
- ENDI
- IF Pcount()=0
- Config='CLINST.MEM'
- ENDIF
- DO COL1
- IF File(Config)
- RESTORE FROM &Config ADDI
- ENDIF
- WorkDir=DEFAULT(WorkDir,untrim(curr_dir(),60))
- SysDir=DEFAULT(SysDir,untrim(curr_dir(),60))
- SrchPath=DEFAULT(SrchPath,untrim(GETE('PATH'),122))
- BackDir=DEFAULT(BackDir,untrim('B:\',40))
- OutPut=DEFAULT(OutPut,'S')
- CLEA
- DO TITLE WITH 'Setting up &Config configuration file'
- @ 10,0 SAY 'Miscellaneous information'
- DO SHOWSYS
- Cor=.F.
- DO WHIL ! Cor
- @ 4,0 SAY 'Default directory ' GET WorkDir PICT '@!' VALI ValDir(WorkDir)
- @ 5,0 SAY 'System directory ' GET SysDir PICT '@!' VALI ValDir(SysDir)
- @ 6,0 SAY 'File search path ' GET SrchPath PICT '@!S60'
- @ 8,0 SAY 'Default output : [S]creen or [P]rinter ' GET OutPut PICT '!' VALI Output $ [SP]
- READ
- Cor= (! Updated())
- @ 24,0 Say 'Is everything correct (Y\N)? ' GET Cor
- READ
- @ 24,0
- ENDDO
- SAVE TO &Config
- SET PATH TO &Path
- IF Curr_Dir()#trim(WorkDir)
- chdir(trim(WorkDir))
- ENDIF
- DO OOPS WITH 'Installation completed'
- RETU
-
- FUNC OS
- * Syntax.: OS()
- * Notes..: Uses Tom Rettig's Library
- * Returns: DOS Version Number
- RETURN DosVers()
-
- FUNC ValDir
- * Syntax.: ValDir( <Directory> )
- * Returns: .T. if <Directory> is valid, .F. otherwise
- PARA Direc
- @ 0,0
- IF IsDir(Direc)
- RETURN (.T.)
- ENDIF
- DO CNTR WITH Trim(Direc)+' was not found.'
- inkey(0)
- RETURN (.F.)
-
- FUNCTION ISFOUND
- * Syntax: IsFound ( <Mask> [,<File>] )
- * Notes.: SEEKS <Mask> in the current file, or else selects <File> and SEEKS
- * <Mask>, re-selecting the current file before returning
- *
- PARA Mask,File
- PRIV RetArea,OK
- OK=PCOUNT()
- IF OK<1
- RETURN ( .F. )
- ENDIF
- RetArea=ALIAS()
- IF OK=2
- IF TYPE('File')='C'
- SELE &File
- ENDIF
- ENDIF
- IF EMPTY(Mask)
- RETURN ( .T. )
- ENDIF
- IF TYPE('Mask')='C'
- SEEK TRIM(Mask)
- ELSE
- SEEK Mask
- ENDIF
- OK=EOF()
- SELE &RetArea
- RETURN ( ! OK )
-
- FUNCTION Confirm
- * Syntax: Confirm( <ExpL> [, <ExpC> ])
- * Notes.: Asks Y/N without get
- PARA Changed,Text
- PRIV I
- I=PCOUNT()
- IF I<1
- RETURN ( .T. )
- ENDIF
- IF TYPE('Changed')#'L'
- RETURN ( .T. )
- ENDIF
- IF I<2
- Text='Information has been altered. Overwrite old data (Y/N)? '
- ENDIF
- @ 24,0
- @ 24,0 SAY Text
- DO COL2
- ?? IF (Changed,'Y','N')
- DO COL1
- Key=0
- DO WHIL ! Chr(Key) $ 'YyNnTtFf'+chr(13)+chr(3)
- Key=Inkey(0)
- ENDD
- @ 24,0
- Changed=IF (Chr(Key) $ 'YyTt'+chr(13)+chr(3),.T.,.F.)
- RETURN Changed
-
- PROC SHOWREC
- * Syntax: DO SHOWREC WITH <Field List>, <Start Row>, <Start Col>, <Field Sep>
- * Notes.: The array of FLDS that are passed to this procedure must be the
- * NAMES of the fields in the database
- PARA Flds,Y,X,Filler
- PRIV I,J
- I=PCOUNT()
- IF i<2
- RETURN
- ENDIF
- IF I<3
- X=0
- ENDIF
- IF I<4
- Filler='│'
- ENDIF
- IF TYPE('Flds')='A'
- I=2
- FN=Flds[1]
- @ Y,X SAY &FN
- DO WHIL ! EMPTY(Flds[I]).AND.I<LEN(Flds)
- FN=Flds[I]
- IF COL()<78
- ?? Filler
- ?? &FN
- ENDIF
- I=I+1
- ENDDO
- ELSE
- @ Y,X SAY &Flds
- ENDIF
- DO COL1
- @ 0,10 SAY IF(Deleted(),'Deleted',' ')
- RETURN
-
- PROC LISTRECS
- * Syntax: DO ListRecs WITH <FieldLists>, <Filter>, <Start Row>, <Left Column>,
- * <Lines in Window>, <Field Separator>
- * Notes.: The array of FLDS that are passed to this procedure must be the
- * NAMES of the fields in the database.
- PARA Flds,Filt,Y,X,Lines,Filler
- PRIV I,J
- I=PCOUNT()
- IF i<1
- RETURN
- ENDIF
- IF I<2
- Filt=.T.
- ENDIF
- IF I<3
- Y=3
- ENDIF
- IF I<4
- X=0
- ENDIF
- IF I<5
- Lines=24-Y
- ENDIF
- IF I<6
- Filler='│'
- ENDIF
- I=0
- RetRec=RecNo()
- DO WHIL &Filt .AND. ! EOF().AND.I<Lines
- DO SHOWREC WITH Flds,Y+I,X,Filler
- I=I+1
- SKIP
- ENDDO
- GO RetRec
- RETURN
-
- PROCEDURE SELEREC
- * Syntax: DO SELEREC WITH <FieldList>, <Filter>, <Row>, <Col>, <Lines>,
- * <Filler>
- * Notes.: Uses the current data file
- PARA Flds,Filt,Row,Col,Lines,Filler
- PRIV X1,X2,Y1,Y2,I,DelStat
- I=PCOUNT()
- IF I<1
- RETURN
- ENDIF
- IF I<2
- Filt='.T.'
- ENDIF
- IF I<3
- Row=3
- ENDIF
- IF I<4
- Col=0
- ENDIF
- IF I<5
- Lines=24-Row
- ENDIF
- IF I<6
- Filler='║'
- ENDIF
- IF ! &Filt
- LOCA FOR &Filt
- IF EOF()
- @ 24,0 SAY 'No records found for &Filt'
- Inkey(0)
- RETU
- ENDIF
- ENDIF
- DelStat=STATUS('DELETED')
- SET DELE OFF
- Y1=Row-1
- X1=Col
- Y2=Y1+Lines
- X2=79
- FirstRec=RecNo()
- * Since TR's CURSOR conflicted with another function that I had, I recompiled
- * it as CURSOR2.
- CALL CURSOR2 WITH "OFF"
- DO COL1
- CALL SCROLL2 WITH Y1,X1,Y2,X2,0,'U'
- DO LISTRECS WITH Flds,Filt,Row,Col,Lines,Filler
- Key=0
- I=1
- GO FirstRec
- DO COL2
- FirstField=Flds[1]
- @ Row,Col SAY &FirstField
- DO WHIL Key#13
- DO COL2
- @ Y1+I,X1 SAY &FirstField
- DO COL1
- Key=Inkey(0)
- TempRec=Recno()
- @ Y1+I,X1 SAY &FirstField
- DO CASE
- CASE Key=27 && Esc
- Key=13
- CASE Key=28 && F1
- SAVE SCREEN TO TEMPBUFF
- @ 0,0 SAY '╔══════╤═══════════════════════════╗'
- @ 1,0 SAY '║ Key │ Result ║'
- @ 2,0 SAY '╟──────┼───────────────────────────╢'
- @ 3,0 SAY '║ ─, │ next record ║'
- @ 4,0 SAY '║ ─, │ previous record ║'
- @ 5,0 SAY '║ PgUp │ next screen ║'
- @ 6,0 SAY '║ PgDn │ previous screen ║'
- @ 7,0 SAY '║ Home │ 1st record match ║'
- @ 8,0 SAY '║ Del │ (un)delete current record ║'
- @ 9,0 SAY '║ ──┘ │ select current record ║'
- @ 10,0 SAY '║ F1 │ this screen ║'
- @ 11,0 SAY '╚══════╧═══════════════════════════╝'
- @ 12,0 SAY ' Hit any key to continue'
- inkey(0)
- RESTORE SCREEN FROM TEMPBUFF
- CASE Key=1 &&HomeKey
- GO FirstRec
- CALL SCROLL2 WITH Y1,X1,Y2,X2,0,'U'
- DO LISTRECS WITH Flds,Filt,Row,Col,Lines,Filler
- I=1
- CASE Key=18 &&PgUp
- SKIP -Lines
- IF &Filt .AND. ! BOF()
- I=1
- CALL SCROLL2 WITH Y1,X1,Y2,X2,0,'U'
- DO LISTRECS WITH Flds,Filt,Row,Col,Lines,Filler
- ELSE
- GO TempRec
- ENDIF
- CASE Key=3 &&PgDn
- SKIP Lines
- IF &Filt .AND. ! EOF()
- I=1
- CALL SCROLL2 WITH Y1,X1,Y2,X2,0,'U'
- DO LISTRECS WITH Flds,Filt,Row,Col,Lines,Filler
- ELSE
- GO TempRec
- ENDIF
- CASE (Key=24.OR.Key=4).AND.! EOF() && Down or Right arrow
- I=I+1
- SKIP
- IF &Filt .AND. ! EOF()
- IF I>Lines
- I=I-1
- CALL SCROLL2 WITH Y1,X1,Y2,X2,1,'U'
- DO SHOWREC WITH Flds,Y1+I,X1,Filler
- ENDIF
- ELSE
- I=I-1
- GO TempRec
- ENDIF
- CASE (Key=5.OR.Key=19).AND.! BOF() && Up or Left arrow
- I=I-1
- SKIP -1
- IF &Filt .AND. ! BOF()
- IF I<1
- I=I+1
- CALL SCROLL2 WITH Y1,X1,Y2,X2,1,'D'
- DO SHOWREC WITH Flds,Y1+I,X1,Filler
- ENDIF
- ELSE
- I=I+1
- GO TempRec
- ENDIF
- CASE Key=7 && Delete key
- IF DELETED()
- RECA
- ELSE
- DELETE
- ENDIF
- ENDC
- ENDDO
- DO COL1
- CALL CURSOR2 WITH "ON"
- SET DELE &DelStat
- RETURN
-
- PROCEDURE JJMA
- IF ISCOLOR()
- SET COLO TO B+
- ELSE
- SET COLO TO W+
- ENDIF
- CLEA
- CALL CURSOR2 WITH "OFF"
- TEXT
-
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄ ▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄ ▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
- ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
- ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
- ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
- ENDTEXT
- IF ISCOLOR()
- SET COLO TO W+
- ELSE
- SET COLO TO W
- ENDIF
- TEXT
-
- COMPUTER APPLICATIONS
-
-
- John J. McMullen Associates, Incorporated.
- Century Building, Suite 715
- 2341 Jefferson Davis Highway, Arlington, Virginia 22202
- (703) 521 - 6500
- ENDTEXT
- DO COL1
- inkey(10)
- CALL CURSOR2 WITH "ON"
- RETU
-
- *************************
- * External declarations:
- *************************
-
- ** These external utilities are from DL1B.ARC - if you don't have it, get it!
-
- * EXTERNAL untrim,dtow,getkey, dial, set_page, reset, prtscr, get_mode
- * EXTERNAL get_page, chdir, mkdir, rmdir, set_mode, sysmem, cursor, cls
- * EXTERNAL curr_drive, set_time, curr_dir, set_date, setdate, set_drive, subset
- * EXTERNAL isupper, islower, ltow, subsets, allalpha, allnum, allascii
- * EXTERNAL timeh, isdir, isprint
-
- * EOP: EXTENDB2.PRG