home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-04-01 | 33.2 KB | 1,418 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
- * DELCOUNT() ::= # of records marked for deletion in current file
- * DIV() ::= integer division of n1 by n2
- * EDFUNC() ::= My editor function for the DBEDIT function in DBU
- * library
- * FEXISTS() ::= T/F if file with/without extension exists
- * FIELDNUM() ::= # of 'field' in currently used file
- * 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
- * PERC() ::= 100 * Num1/Num2
- * RITE() ::= string of any variable, with two options
- * SPERC() ::= string of PERC()
- * STRIP() ::= Memo/Character field with <Target> stripped out
- * or optionally replaced with <Replacement>
- * SZERO() ::= string(Zero())
- * ULEN() ::= length of any type of variable
- * ZERO() ::= n1/n2 if n2#0, otherwise 0
- *
- *
- * PROCEDURES
- * CNTR ::= Center text on a line
- * 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
- * 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
- * RESETINDEX ::= Generic index (re)setter
- * SELEFIELDS ::= Select fields from the current database
- * SELEFILE ::= Select a file from the current subdirectory
- * SETFILT ::= Set a filter
- * SHOWFIELDS ::= Show the fields in the currently selected database
- * SHOWFILES ::= Display the files on current subdirectory
- * STATUS ::= Closest I could get to dB3's display status
- * TITLE ::= Make a title on the screen
- *
- *
-
- 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>] )
- * Return.: A character string of <Exp?> either len(<Exp?>) long or the
- * "ALLTRIM( <Exp?> )"
- * Default: <Delimiter> = ''
- *
- 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(strip(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=strip(FldName)
- OTHERWISE
- st=&FldName
- ENDCASE
- ENDCASE
- RETURN (st)
-
- FUNCTION Strip
- * Syntax.: STRIP( <ExpC> [<Target>, [<Replacement>]])
- * Notes..: <ExpC> is name of Memo/Character field to strip <Target> from,
- * or replace target with <Replacement>
- * Return.: Memo field without <Target> or replaced with <Replacement>
- * Default: <Target to Strip> = Soft Carriage Return for memo field
- *
- PARA Memo,Tar,Repl
- PRIV st,bltst
- IF TYPE('TAR') ='U'
- tar=chr(141)+chr(10)
- ENDIF
- IF TYPE('TAR') # 'C' .OR. EMPTY(Tar)
- Tar=chr(141)+chr(10) && Soft return code for memos
- ENDIF
- IF TYPE('REPL') # 'C'
- Repl=''
- ENDIF
- BltSt=''
- IF ! TYPE(Memo) $ 'MC'
- RETURN ('')
- ELSE
- st=&memo
- DO WHILE AT(Tar,st)>0
- BltSt=BltSt+LEFT(st,at(Tar,st)-1)+Repl
- st=RIGHT(st,len(st)-at(Tar,st)-len(tar)+1)
- ENDDO
- IF ! EMPTY(St)
- BltSt=BltSt+St
- ENDIF
- RETURN (BltSt)
- ENDIF
-
- 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
- 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
- IF PCOUNT()<1
- Mask='*.*'
- ENDIF
- IF TYPE('Mask')#'C'
- Mask='*.*'
- ENDIF
- Selected=Mask
- 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
- I=1
- IF ! Empty(Selected)
- I=ASCAN(Files,Selected)
- ENDIF
- I=IF(I<1,1,I)
- 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]
- 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 '*.DBF',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'
- DO OOPS WITH 'Variable "COND" should be public'
- 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 'No commas may be used in 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 'No commas may be used in 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 'No commas may be used in 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 'No commas may be used in 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 'No commas may be used in REPLACING FOR 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
- @ 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 'No commas may be used in 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
- @ 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 'No commas may be used in 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 index order on any active index
- *
- 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)
- 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 TYPE('Var') # 'U'
- DO CASE
- CASE TYPE(Var)='N'
- RETURN (len(str(&var)))
- CASE TYPE(Var)='L'
- RETURN (3)
- CASE TYPE(Var) $ 'MC'
- RETURN (Len(&var))
- CASE TYPE(Var)='D'
- RETURN (8)
- OTHERWISE
- RETURN (0)
- ENDCASE
- ELSE
- RETURN (0)
- ENDIF
-
- 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 STATUS
- * Syntax: DO STATUS
- * 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,2),'key:',INDEXKEY(J)
- ENDIF
- NEXT
- ?
- ENDIF
- NEXT
- inkey(0)
- SELE &Ret_Area
- @ 0,0 CLEA
- ? 'Operating system: DOS',OS()
- ? 'System memory: ',SysMem()
- ?? 'K'
- ? 'Free memory: ',Fre(),'Bytes'
- ? 'Current drive: ',Curr_Drive()
- ? 'Current directory:',Curr_dir()
- ? 'Current date: ',CDOW(Date())+',',DTOW(Date())
- ? 'Current time: ',AMPM(Time())
- ? 'Video page: ',Get_Page()
- ? 'Video mode: ',Get_Mode()
- ?
- 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) .AND. Type(FiltCond)='L'
- 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 a new record
- *
- PRIV I,FN
- IF RecCount()=0
- APPE BLAN
- RETURN
- ENDIF
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- M->&FN = &FN
- NEXT
- APPE BLAN
- FOR I=1 TO FCOUNT()
- FN=Field(I)
- REPL &FN WITH M->&FN
- NEXT
- RETU
-
- PROCEDURE EXECMAC
- * Syntax: DO ExecMac
- * Notes.: Executes a specified HP Laserjet Macro a specified # of times
- * This assumes that you have my library, HPLJLIB.PRG
- PRIV I,J,K
- I=1
- K=1
- DO COL1
- CLEA
- DO TITLE WITH 'Executing an HP LaserJet Plus Macro'
- DO BOXIT WITH 4,20,8,60
- DO CNTR WITH 'The program assumes that the macro is already correctly loaded',10
- DO CNTR WITH 'into the LaserJet Plus RAM.',12
- Cor=.N.
- DO WHIL ! Cor
- @ 5,22 SAY 'Macro to Execute ' GET I PICT '9999'
- @ 7,22 SAY '# of repetitions ' GET K PICT '999'
- READ
- IF Empty(I).AND.Empty(K)
- RETU
- ENDIF
- DO CORRECT
- ENDDO
- DO CNTR WITH 'Executing the macro '+alltrim(str(K))+' times. <Esc> to abort.',23
- SET PRIN ON
- SET CONS OFF
- SET PRIN ON
- SET CONS OFF
- J=1
- Key=0
- DO WHIL J<=K.AND.Key#27
- Key=inkey()
- IF Key#27
- ?? HPEmac(I)
- ENDIF
- J=J+1
- ENDDO
- SET PRIN OFF
- SET CONS ON
- RETU
-
- * These procedures are also generated by my program CLIPMENU.COM
-
- 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
-
- 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
- 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
- IF TYPE("Clear")="C"
- Bframe=Bframe+Clear
- ENDIF
- DO BOXCOL
- @ Top,left CLEA TO Bottom,Right
- IF Border#0
- @ Top,left,bottom,right BOX Bframe
- ENDIF
- DO COL1
- RETU
- * EOP: Procedure BOXIT
-
-
- *************************
- * 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, os, allalpha, allnum, allascii, fre
- EXTERNAL timeh, isdir, dl_version, csr_top, csr_bot, isprint
-
- * EOP: EXTENDB2.PRG