home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR19
/
DBX130.ZIP
/
MYFUNC.PRG
< prev
next >
Wrap
Text File
|
1993-03-22
|
23KB
|
728 lines
* Program...: MYFUNC.PRG
* Author....: Your Name Here
* Date......:
* Notes.....: This routine is called by pressing Sh-F1 when browsing a
* database. You can create any routine you like by expanding
* the code below and linking the routine into dbMAX. Sample
* code is included at the end of this file (commented-out).
*
* Compile with -n -l switches
*
* Revised...: 03/15/92, rev 1.30 - revised for Clipper 5.2
*
*****************************************************************************
*
#include "inkey.ch"
*
#ifdef DBFNDX
request dbfndx
#endif
#ifdef DBFCDX
request dbfcdx
#endif
#ifdef DBFMDX
request dbfmdx
#endif
*
* WARNING: do not request or link both DBFCDX and DBFSIX RDDs! Doing so
* will cause the program to lock up your machine!
*
#ifdef DBFSIX
request dbfsix
#endif
*
*****************************************************************************
*
function MyFunc( vnKey,voBrowse,vlEditMode,vlNoAppend,vlNoDelete,vaField, ;
vcEditFunc)
*
* vnKey = the ASCII value of the last key pressed, passed by reference
* (will always be -10/K_SH_F1)
* voBrowse = the current browse object, passed by reference
* vlEditMode = .T. if editing allowed
* vlNoAppend = .T. if no appending allowed (always .F.)
* vlNoDelete = .T. if no deleting allowed (always .F.)
* vaField = DBSTRUCT() of all fields in database, passed by reference
* vcEditFunc = name of a user-defined edit routine (always '')
*
* Although some of the variables above have been passed by reference, any
* changes to them will be ignored (see below for more info).
*
*
* NOTE: PRESSING SH-F1 WILL CALL MYFUNC(), BUT ALL PARAMETERS WILL BE NIL!!
* MYFUNC() is currently called by evaluating the following code block,
* as follows:
*
* bBlock := {|| MyFunc()} && declared in main procedure
* *
* eval(bBlock,@vnKey,@voBrowse,vlEditMode,vlNoAppend,vlNoDelete, ;
* @vaField,vcEditFunc)
*
* To properly allow parameters to be passed, the code block would have
* to be defined as something like:
*
* bBlock := {|p1,p2,p3,p4,p5,p6,p7| MyFunc(p1,p2,p3,p4,p5,p6,p7)}
*
* This version of dbMAX does not do this. HOWEVER, THIS DOES NOT
* REALLY MATTER SINCE ALL PARAMETERS CAN BE OBTAINED BY CHECKING THE
* VARIABLES LISTED BELOW.
*
local vnChoice := 1
local vcColrSave := setcolor(vcMenuBar)
local vcScreen
*
save screen to vcScreen
@ 0,0 && clear off default menu bar
HelpBar('User-defined function menu.')
setcolor(vcColrSave)
*
do while vnChoice<>0
PullDown(0,2,{' Utils '},{'U'},{.T.},nil,@vnChoice)
*
do case
case vnChoice=1
HelpBar('User-defined utilities.')
if UserUtils()
vnChoice := 0
endif
*
otherwise
vnChoice := 0
*
endcase
*
HelpBar()
*
enddo
restore screen from vcScreen
return (nil)
*
*****************************************************************************
*
static function UserUtils()
*
local vnChoice := 1
local vlRetVal := .F. && .T.=exited normally, .F.=used Esc to exit
local vcScreen
*
local vaMenu := {' List dups '}
*
local vaHotKeys := {'L'}
local vaValid := {(vnInUse>0 .and. ordnumber(ordsetfocus(),ordbagname(0))<>0)}
local vaMessage := {'List duplicate records (contributed by John Wright).'}
*
save screen to vcScreen
*
do while vnChoice<>0
*
PullDown(1,1,vaMenu,vaHotKeys,vaValid,vaMessage,@vnChoice)
*
do case
case vnChoice=1
if HuntDups() && if .T. (task complete), quits back to
vnChoice := 0 && ...dbMAX menu or browse
vlRetVal := .T.
endif
*
endcase
enddo
restore screen from vcScreen
*
return (vlRetVal)
*
*****************************************************************************
*
static function HuntDups()
*
* Contributed by: John Wright
* Revised by: David Kennedy, 03/07/93 for Clipper 5.2
*
* HuntDups() uses the currently selected index to hunt for duplicates.
* HuntDups() allows you to create an index with numerous fields, check for
* a specific section of that index and then display even more data than the
* "hunt" criteria. There is no need to create a new index if you already
* have one that meets your search needs.
*
* Example: You have a database of customer names and want to find
* duplicates. Index the database on LASTNAME+FIRSTNAME+CITY,
* search for duplicates of LASTNAME+FIRSTNAME and display
* LASTNAME+FIRSTNAME+CITY+PHONE etc... so you can see if the
* names are really duplicates.
*
* A client's INVOICE database gets messed up when duplicate
* order records are merged in by mistake. Use HuntDups() to
* search on invoice number and delete duplicates. This saves
* the extra step of having to go back to clean up the file.
* The duplicate records are only marked for deletion. You
* still have to pack the database to get rid of the dups...
*
local vcColrSave := setcolor()
local vnRecNo := recno()
local vlOk := .F.
local vcScreen
*
local vcCheck := padr(upper(ordkey(ordsetfocus(),ordbagname(0))),254)
local vcList := padr(upper(ordkey(ordsetfocus(),ordbagname(0))),254)
local vcFile := padr(vcRamDrv+'DUPS.PRN',80)
local vlKill := .F.
local vnDeleted := 0
local vnCount := 0
local vbCheck, vbList, vcPrev, vlFirst
*
save screen to vcScreen
HelpBar('Enter the search parameters.')
PopBox(4,5,13,74,2,'List duplicates')
*
do while .not. vlOK
*
vlOK := .T.
*
@ 6,7 say 'Check for dups of ' get vcCheck picture '@K@S47@X'
@ 7,7 say 'List for each dup ' get vcList picture '@K@S47@X'
@ 8,7 say 'Send dup list to ' get vcFile picture '@K@S47@!'
@ 9,7 say 'Delete duplicates?' get vlKill picture 'Y'
*
@ 11,27 say ' Ok '
@ 11,34 say ' Retry '
@ 11,44 say ' Cancel '
*
set cursor on
read
clear gets
set cursor off
*
if lastkey()<>K_ESC
*
if vlOK
*
* everything is OK, so see if user wants to save
*
@ 11,27 prompt ' Ok '
@ 11,34 prompt ' Retry '
@ 11,44 prompt ' Cancel '
menu to vnTemp
*
do case
case vnTemp=1 .and. !empty(vcCheck) .and. !empty(vcList) ;
.and. !empty(vcFile)
*
case vnTemp=2
vlOK := .F.
*
otherwise
vlOK := .F.
exit
*
endcase
endif
else
vlOK := .F.
exit
endif
enddo
*
* locate data if OK
*
restore screen from vcScreen
if vlOK
*
HelpBar()
PopBox(4,23,8,56,2)
@ 6,25 say 'Please wait while searching...'
*
ZeroCnt()
*
vcFile := FixFile(vcFile,'.PRN')
set printer to (vcFile) additive
set console off
set print on
set device to print
*
* print database information
*
? 'Database: '+vaDbfNtx[vnCurrArea,1]+vaDbfNtx[vnCurrArea,2]
? 'Index: '+vaDbfNtx[vnCurrArea,3,OrdFilePos(ordbagname(0)),1]+;
vaDbfNtx[vnCurrArea,3,OrdFilePos(ordbagname(0)),2]
? 'Look for: '+upper(trim(vcCheck))
? 'Display: '+upper(trim(vcList))
?
vbCheck := &('{||'+trim(vcCheck)+'}' )
vbList := &("{|| if(deleted(),'*',' ')+str(recno(),7,0)+' '+"+trim(vcList)+'}')
*
go top
vlFirst := .T.
vcPrev := eval(vbCheck)
do while !eof() .and. inkey()<>K_ESC
skip
if eval(vbCheck)==vcPrev
if vlFirst // skip back to print first duplicate
skip -1
?
? eval(vbList)
skip
vlFirst := .F.
endif
if vlKill .AND. rec_lock(2)
delete
vnDeleted++
unlock
endif
? eval(vbList)
set device to screen
DispCnt('duplicated')
vnCount++
set device to print
else
vcPrev := eval(vbCheck)
vlFirst := .T.
endif
enddo
*
vcList := ltrim(str(vnCount))+' duplicate records found.'
?
?
? vcList
if vlKill
vcCheck := ltrim(str(vnDeleted))+' records deleted.'
? vcCheck
endif
eject
*
set device to screen
set print off
set console on
set printer to
keyboard '' // clear buffer of any unwanted Esc's
*
* display information about the search for duplicates
*
restore screen from vcScreen
PopBox(10,23,if(vlKill,15,14),26+len(vcList),2)
@ 12,25 say vcList
if vlKill
@ 13,25 say vcCheck
endif
tone(100,1)
HelpBar('Press any key to continue...')
inkey(0)
*
go vnRecNo
setcolor(vcColrSave)
restore screen from vcScreen
if vlKill .and. vnDeleted > 0
vaBrowStak[vnCurrArea,1]:refreshAll()
endif
else
setcolor(vcColrSave)
endif
*
return (vlOK)
*
*****************************************************************************
*
* The following variables are used by dbMAX and CAN be changed:
* ▀▀▀
* vcPath = current drive and path used by dbMAX (initially set to your
* current DOS path but changes when any pop-up directories are
* used (Alt-B, Alt-N, etc.))
* vnInUse = total number of work areas in use
* vnCurrArea = current work area number
* vaDBFNTX = array of .DBFs/.NTXs/open modes
* vaBrowStak = browse object stack
* vlRepaint = set to .T. to completely repaint desktop/browse(s)
*
* vcDosColr = current DOS screen color
* vcDeskTop = desktop color
* vcBrowse = browse color
* vcShadow = box shadow color
* vcMenuBar = menu bar color
* vcPullDown = pull-down menu color
* vcPullBox = pull-down box border color
* vcHotKey = accelerator key color
* vcError = error message color
*
* vcRdd = the name of the currently selected RDD
* vlMultiUser = .T. if running in multi-user mode (database could be opened
* shared or exclusive, regardless of this setting)
* vcRamDrv = temporary files drive
* vcEditor = default memo editor ("" = use MEMOEDIT())
* vnMemoWidth = default memo line length (0 = screen width)
* vcPrnSetup = printer setup string
* vnPageLen = max lines per page
* vnLeftMar = left margin
* vnTopMar = top margin
* vnMaxRow = max rows on screen
* vnInitRow = max initial rows on screen (DOS)
* vnMaxCol = max columns on screen
* vnInitCol = max initial columns on screen (DOS)
* vlDelStru = .T. to delete .STR files when done
* vlAllowEdit = .T. if editing allowed
* vlBadEMS = .T. if bad EMS switch set (bypasses Overlay())
* vnMaxFields = maximum fields that can be browsed
*
*
* The most important variables are the vaDBFNTX and vaBrowStak arrays. The
* vaDBFNTX array contains a list of all open databases. All elements in a
* "row" will be NIL if a database was opened and then closed. The number
* of the array element that is currently active is stored in vnCurrArea,
* which is also SELECT() (usually). The structure for one element is as
* follows:
*
* vaDBFNTX[1] = {"<drive:\path\>","dbase.dbf",{"index <drive:\path\>",;
* "index.ntx"},"E/S","RDD"}
*
* vaDBFNTX[1,1] = the full drive and path with trailing backslash for the
* database; i.e., "C:\DATA\"
* vaDBFNTX[1,2] = the full name and extension of the database; i.e.,
* "MYDATA.DBF"
* vaDBFNTX[1,3] = an array of open indexes for the database; if no indexes
* are open, this will be NIL
*
* vaDBFNTX[1,3,1] = the full drive and path with trailing backslash for
* the index; i.e., "C:\DATA\"
* vaDBFNTX[1,3,2] = the full name and extension of the index; i.e.,
* "MYDATA.NTX"
*
* vaDBFNTX[1,4] = "E" if file is opened exclusively, "S" if shared
*
* vaDBFNTX[1,5] = name of the RDD that the database was opened under,
* such as "DBFNTX" or "DBFNDX".
*
* The vaBrowStak contains all the browse objects currently in use. The
* number of the array element that is currently active is stored in
* vnCurrArea, which is normally the same as SELECT(). The structure for one
* element is as follows:
*
* vaBrowStak[1] = {<oBrowse>,{<structure>}}
*
* vaBrowStak[1,1] = the browse object; oBrowse:cargo contains append mode
* flag; oColumn:cargo contains actual field name/
* expression for the column
* vaBrowStak[1,2] = the structure of the database, the same as that
* created by the DBSTRUCT() function
*
* Usage example:
*
* * refresh the current browse window
* vaBrowStak[vnCurrArea,1]:refreshAll()
*
*****************************************************************************
*
* Some internal dbMAX functions that may be called by your routines are:
*
* ColStru() - returns the structure of a field/expression
*
* Usage: aArray := ColStru( cFieldName )
*
* Where: cFieldName = the name of a field or memory variable
*
* Returns: {cFieldName,cType,nLength,nDecimals} array for a field or
* expression. If cFieldName contains an expression, cType
* will be "E".
*
* Example:
*
* * returns the structure array for the field where a hot-key was
* * pressed
* *
* aArray := ColStru( (voBrowse:getColumn(voBrowse:colPos)):cargo )
*
*
* PullDown() - sets up and displays menu system
*
* Usage: PullDown( nRow,nCol,aMenu,aHotKeys,aValid,aMessage,@nChoice )
*
* Where: nRow = top row of the pop-up menu box. If nRow=0, the
* menu appears horizontally on line 0!
* nCol = left column of the pop-up menu box
* aMenu = array of menu choices
* aHotKeys = array of hot key letters for the menu choices,
* "" for choices with no hot key (horizontal menus
* will not use hot keys)
* aValid = parallel logical array for valid menu choices
* aMessage = help bar messages to display when selecting
* (horizontal menus will not use messages)
* nChoice = variable to take menu selection, passed by ref.
*
* Returns: NIL, but nChoice contains the number of the menu item
* selected, 0 if nothing was selected.
*
* Example:
*
* local nChoice := 0
* PullDown(1,1,{' New... Alt-N ',;
* ' Open... Alt-O ',;
* ' ────────────────── ',;
* ' Quit Alt-Q '},{'N','O','','Q'},;
* {.T.,.T.,.F.,.T.},{'Message 1','Message 2','',''},;
* @nChoice)
*
*
* HelpBar() - places a message on the help bar
*
* Usage: HelpBar( [cMessage] )
*
* Where: cMessage = any character string or NIL
*
* Returns: NIL
*
* Example:
*
* HelpBar() // clears off help bar
* HelpBar('Press <Esc> to quit.')
*
*
* PopBox() - pops up a single- or double-lined filled shadowed box
*
* Usage: PopBox( nTRow,nTCol,nBRow,nBCol,nBorder [,cTitle] )
*
* Where: nTRow = top row of box
* nTCol = top left col of box
* nBRow = bottom row of box
* nBCol = bottom left col of box
* nBorder = 1=single line, 2=double line
* cTitle = optional title to be displayed (@ nTRow,nTCol+2)
*
* Returns: NIL
*
* Example:
*
* PopBox(4,9,10,70,2,'Database name')
*
*
* PopError() - pops up an error message
*
* Usage: PopError( cMessage )
* nChoice := PopError( cMessage [,aPrompts] )
*
* Where: cMessage = any character string for the error message
* aPrompts = an optional array of selection options, defaults
* to " Ok " if nothing passed
*
* Returns: number of choice selected
*
* Example:
*
* PopError('Not enough file handles ('+ltrim(str(MaxHand()))+')!')
* nChoice := PopError('File exists!',{' Overwrite ',' Cancel '})
*
*
* MaxHand() - gets maximum number of file handles remaining
*
* Usage: MaxHand()
*
* Returns: number of file handles remaining
*
* Example:
*
* @ 1,1 say 'You have '+ltrim(str(MaxHand()))+' handles remaining!'
*
*
* fil_lock() - tries to lock a file
*
* Usage: fil_lock( nWait )
*
* Where: nWait = number of seconds to wait for the lock, 0=forever
*
* Returns: .T. if lock was successful, .F. otherwise
*
* Example:
*
* if fil_lock(2)
* replace all field with 'stuff'
* commit
* unlock
* else
* PopError('File could not be locked!')
* endif
*
*
* rec_lock() - tries to lock a record
*
* Usage: rec_lock( nWait )
*
* Where: nWait = number of seconds to wait for the lock, 0=forever
*
* Returns: .T. if lock was successful, .F. otherwise
*
* Example:
*
* if rec_lock(2)
* delete
* commit
* unlock
* else
* PopError('Record could not be locked!')
* endif
*
*
* net_use() - tries to USE a database in shared or exclusive mode
*
* Usage: net_use( cFile,lExclus,nWait )
*
* Where: cFile = name of database to open
* lExclus = .T. to open file exclusively
* nWait = number of seconds to wait for the lock, 0=forever
*
* Returns: .T. if open was successful, .F. otherwise
*
* Example: none! Don't use this function unless you are sure you know
* what's going on inside dbMAX. If you do not update
* vnCurrArea and vaDBFNTX[] when this command is used, you may
* cause the program to crash or operate incorrectly.
*
*
* app_blank() - tries to append a blank record to a shared database
*
* Usage: app_blank( nWait )
*
* Where: nWait = number of seconds to wait for the append, 0=forever
*
* Returns: .T. if append was successful, .F. otherwise
*
* Example:
*
* if app_blank(2)
* replace field with 'stuff'
* commit
* unlock
* else
* PopError('LASTREC()+1 is locked. Something is screwed up!')
* endif
*
*****************************************************************************
*****************************************************************************
*
* Sample MYFUNC() #1
*
* function MyFunc()
* PopError('Function unavailable!')
* return (nil)
*
*****************************************************************************
*****************************************************************************
*
* Sample MYFUNC() #2
*
* *
* function MyFunc()
* *
* local vnChoice := 1
* local vcColrSave := setcolor(vcMenuBar)
* local vcScreen
* *
* save screen to vcScreen
* @ 0,0 && clear off default menu bar
* HelpBar('Shift-F1 Main Menu.')
* setcolor(vcColrSave)
* *
* do while vnChoice<>0
* PullDown(0,2,{' Option 1 ',;
* ' Option 2 ',;
* ' Option 3 '},;
* {'1','2','3'},{.T.,.T.,.T.},nil,@vnChoice)
* *
* do case
* case vnChoice=1
* HelpBar('Option 1 tasks menu.')
* if Sample()
* vnChoice := 0
* endif
* *
* case vnChoice=2
* HelpBar('Option 2 tasks menu.')
* PopError('Option 2 unavailable!')
* *
* case vnChoice=3
* HelpBar('Option 3 tasks menu.')
* PopError('Option 3 unavailable!')
* *
* otherwise
* vnChoice := 0
* *
* endcase
* *
* HelpBar()
* *
* enddo
* restore screen from vcScreen
* return (nil)
* *
* *****************************************************************************
* *
* static function Sample()
* *
* local vnChoice := 1
* local vlRetVal := .F. && .T.=exited normally, .F.=used Esc to exit
* local vcScreen
* *
* local vaMenu := {' Check this ',;
* ' ─────────── ',;
* ' Allow edit ',;
* ' In use > 0 ',;
* ' Browse '}
* *
* local vaHotKeys := {'C','','A','I','B'}
* local vaValid := {.T.,.F.,vlAllowEdit,(vnInUse>0),(vnInUse>0)}
* local vaMessage := {'Check/uncheck this item by pressing <Enter>.','',;
* 'Selectable if editing allowed.',;
* 'Selectable if at least one .DBF opened.',;
* 'Changes the color of the hilighted column.'}
* *
* save screen to vcScreen
* *
* do while vnChoice<>0
* *
* PullDown(1,1,vaMenu,vaHotKeys,vaValid,vaMessage,@vnChoice)
* *
* do case
* case vnChoice=1
* vaMenu[1] := iif(substr(vaMenu[1],1,1)=' ','√',' ')+;
* substr(vaMenu[1],2)
* *
* case vnChoice=3
* restore screen from vcScreen
* *
* *if YourOption() && if .T. (task complete), quits back to
* * vnChoice := 0 && ...dbMAX menu or browse
* * vlRetVal := .T.
* *endif
* *
* case vnChoice=4
* restore screen from vcScreen && don't RESTORE if you want the
* * pull-down to stay on the screen
* *
* *MoreStuff() && quits to dbMAX menu or browse whether task
* vnChoice := 0 && ...was completed or not
* vlRetVal := .T.
* *
* case vnChoice=5
* ChangeColor()
* vnChoice := 0
* vlRetVal := .T.
* *
* endcase
* enddo
* restore screen from vcScreen
* *
* return (vlRetVal)
* *
* *****************************************************************************
* *
* static function ChangeColor()
* *
* * Changes color of the currently highlighted column. Can only be called if
* * a file is being browsed, so error checking is not required. :colorSpec
* * is initially set to vcBrowse color.
* *
* local voBrowse := vaBrowStak[vnCurrArea,1] && get curr browse
* local voColumn := voBrowse:getColumn(voBrowse:colPos) && get column
* *
* voBrowse:colorSpec := voBrowse:colorSpec+',+BG/B,+W/G'
* voColumn:colorBlock := {|| {6,7} }
* *
* voBrowse:setColumn(voBrowse:colPos,voColumn) && reset column
* *
* vaBrowStak[vnCurrArea,1] := voBrowse && save browse
* return (nil)