Dec 102017
This test program demonstrates the use of the Clipper GENFUNC function. | |||
---|---|---|---|
File Name | File Size | Zip Size | Zip Type |
READ.ME | 5608 | 2475 | deflated |
TEST.DBF | 454 | 113 | deflated |
TEST.PRG | 12362 | 3809 | deflated |
Download File GENFUNC.ZIP Here
Contents of the READ.ME file
Have you ever needed to dBEDIT a large database? How does the user get to
the record that they need to work with? Well, there's a
neat way to allow the user to type the first few letters of what they are
looking for, and dBEDIT will do a search in the index for those letters.
The search section worked great, but in some of our larger systems, we found
that we had upwards of 40-50 dBEDITS, all using this search string method
(some of them were nested several deep). Therefore, I decided to split out
the dBEDIT control section from that portion which is specific to whatever
we are doing with the dBEDIT. For example, what do you do with a dBEDIT?
You want to browse through the database, Add, Edit, and Delete Records, and
perhaps one or two other functions. Why not have that portion of your dBEDIT
function separated from the section that does the character searches (which
is quite complicated).
Enter GenFunc. This function handles all the dBEDIT Control functions,
including the indexed string searches, and calls a function of your choice
anytime any one of 4 keys is pressed. In your function, you then decide what
to do with those keys. In most of our programs, for example, the INSert key
is used to Add a record; the DEL key is used to Delete a record; the Enter
key is used to Edit a record. But sometimes we were using dBEDIT as a
"lookup" of possible answers for a field, so the Enter key was used to accept
the looked-up value, and the F2 key was used to edit the record in the dBEDIT
look up. (This is why GenFunc calls your function any time INS, DEL, Enter,
or F2 is pressed. If you use different conventions, just change GenFunc; just
make sure that the same keys are used all over your system).
Yes, we used GenFunc and dBEDIT up to 4 layers deep doing this. Consider this
as an example as to what you can do: Say you have an inventory system. You
dBEDIT the Orders database with keys INS, DEL, and Enter active (to make a key
inactive, have your function simply beep and RETURN 1 back to GenFunc, and
thus to dBEDIT). Say the user presses Enter to edit an order. Your box pops
up and one of the questions is Customer Number. You can have a lookup for the
Customer Number by using a Hot Key (SET FUNCTION -3 TO lookup, for example,
and in PROC lookup, have a dBEDIT that displays the Customer database). Now
the user is browsing through the Customer database. You want the to be able
to Add, Edit, or Accept a customer, but not to delete any. So have your
Customer function beep and RETURN 1 if DEL is pressed, append a record if INS
is pressed, edit the record if F2 is pressed, and Accept the record (by
"replacing" the Customer Number in your new order with the Customer Number of
the Customer record and RETURNing 2 (to exit the Customer dBEDIT, and thus
return control to the Order dBEDIT) ).
I think you get the idea... hope this function is useful to you. By the way,
if you need to simulate a filter in you database (i.e., display only order
line items for order A), you can do so by modifying GenFunc as follows:
IF Mode = 0 && already in GenFunc
put in this part below...
IF &fld < &val && i.e, we are before first good record
SEEK &val
err(" Top-of-file ... no more Data in this direction ")
RETURN 2
ELSEIF &fld > &val && i.e, we are after the last good record
IF LASTKEY() = 24 && downarrow
SKIP -1
ELSEIF LASTKEY() = 3 && PgDn
SKIP -10 && SKIP back the number of lines on your dBEDIT
ELSE && screen, not necessarity 10!
SEEK &val
ENDIF
err(" Bottom-of-file ... no more Data in this direction ")
RETURN 2
ENDIF
Where fld is the key fieldname (must be indexed, and all search indexes must
contain this value plus whatever other values are to be searched!), and val
is the constraining value. fld and val must be initialized before the dBEDIT
call. For Example: dBEDIT Line_Item.dbf with fields ord_num and item_num.
Index on (1:) ord_num, and (2:) ord_num+item_num (only want to search for
item X in order A). Say the user wants to work with ord_num "A100".
fld = "ord_num"
val = "A100" <== user inputted.
dBEDIT(...)
Three last notes... If a field is not indexed, indexes[ (column number) ] MUST
be zero!. Also, index searches do work on dates, and numbers, but may act
other than you might expect, in that to seek "12/15/1990", type in: 19901215.
Also, numeric fields need to be zero filled. To seek Customer 12 in a four
digit field, you need to type in 0012 in order for the seek to work. There are
ways to detect these things, but I'll leave that up to you. Lastly, this works
great in Summer '87, but I've not tried it in 5.0. My next project is to try
to turn this into an object and incorporate it into TBROWSE. If I'm
successful, I'll send it up for wahatever it's worth.
Again, I hope this helps!! Have fun!
P.S. GenFunc is located in the enclosed TEST.prg. After playing with it,
just strip GenFunc out and modify it to suit your keystroke conventions.
P.P.S. Test.dbf uses a function called shadbox, a nice p/d function. How-
ever shadbox sometimes acts funny if FUNCky is linked in. The first time
shadbox is invoked, the shadow characters are gobblie-gook. The temporary
solution to this is to do a shadbox once and immediately clearing the screen.
The next time shadbox is called, the shadow works fine.
== Galen Mulrooney 12/11/1990
the record that they need to work with? Well, there's a
neat way to allow the user to type the first few letters of what they are
looking for, and dBEDIT will do a search in the index for those letters.
The search section worked great, but in some of our larger systems, we found
that we had upwards of 40-50 dBEDITS, all using this search string method
(some of them were nested several deep). Therefore, I decided to split out
the dBEDIT control section from that portion which is specific to whatever
we are doing with the dBEDIT. For example, what do you do with a dBEDIT?
You want to browse through the database, Add, Edit, and Delete Records, and
perhaps one or two other functions. Why not have that portion of your dBEDIT
function separated from the section that does the character searches (which
is quite complicated).
Enter GenFunc. This function handles all the dBEDIT Control functions,
including the indexed string searches, and calls a function of your choice
anytime any one of 4 keys is pressed. In your function, you then decide what
to do with those keys. In most of our programs, for example, the INSert key
is used to Add a record; the DEL key is used to Delete a record; the Enter
key is used to Edit a record. But sometimes we were using dBEDIT as a
"lookup" of possible answers for a field, so the Enter key was used to accept
the looked-up value, and the F2 key was used to edit the record in the dBEDIT
look up. (This is why GenFunc calls your function any time INS, DEL, Enter,
or F2 is pressed. If you use different conventions, just change GenFunc; just
make sure that the same keys are used all over your system).
Yes, we used GenFunc and dBEDIT up to 4 layers deep doing this. Consider this
as an example as to what you can do: Say you have an inventory system. You
dBEDIT the Orders database with keys INS, DEL, and Enter active (to make a key
inactive, have your function simply beep and RETURN 1 back to GenFunc, and
thus to dBEDIT). Say the user presses Enter to edit an order. Your box pops
up and one of the questions is Customer Number. You can have a lookup for the
Customer Number by using a Hot Key (SET FUNCTION -3 TO lookup, for example,
and in PROC lookup, have a dBEDIT that displays the Customer database). Now
the user is browsing through the Customer database. You want the to be able
to Add, Edit, or Accept a customer, but not to delete any. So have your
Customer function beep and RETURN 1 if DEL is pressed, append a record if INS
is pressed, edit the record if F2 is pressed, and Accept the record (by
"replacing" the Customer Number in your new order with the Customer Number of
the Customer record and RETURNing 2 (to exit the Customer dBEDIT, and thus
return control to the Order dBEDIT) ).
I think you get the idea... hope this function is useful to you. By the way,
if you need to simulate a filter in you database (i.e., display only order
line items for order A), you can do so by modifying GenFunc as follows:
IF Mode = 0 && already in GenFunc
put in this part below...
IF &fld < &val && i.e, we are before first good record
SEEK &val
err(" Top-of-file ... no more Data in this direction ")
RETURN 2
ELSEIF &fld > &val && i.e, we are after the last good record
IF LASTKEY() = 24 && downarrow
SKIP -1
ELSEIF LASTKEY() = 3 && PgDn
SKIP -10 && SKIP back the number of lines on your dBEDIT
ELSE && screen, not necessarity 10!
SEEK &val
ENDIF
err(" Bottom-of-file ... no more Data in this direction ")
RETURN 2
ENDIF
Where fld is the key fieldname (must be indexed, and all search indexes must
contain this value plus whatever other values are to be searched!), and val
is the constraining value. fld and val must be initialized before the dBEDIT
call. For Example: dBEDIT Line_Item.dbf with fields ord_num and item_num.
Index on (1:) ord_num, and (2:) ord_num+item_num (only want to search for
item X in order A). Say the user wants to work with ord_num "A100".
fld = "ord_num"
val = "A100" <== user inputted.
dBEDIT(...)
Three last notes... If a field is not indexed, indexes[ (column number) ] MUST
be zero!. Also, index searches do work on dates, and numbers, but may act
other than you might expect, in that to seek "12/15/1990", type in: 19901215.
Also, numeric fields need to be zero filled. To seek Customer 12 in a four
digit field, you need to type in 0012 in order for the seek to work. There are
ways to detect these things, but I'll leave that up to you. Lastly, this works
great in Summer '87, but I've not tried it in 5.0. My next project is to try
to turn this into an object and incorporate it into TBROWSE. If I'm
successful, I'll send it up for wahatever it's worth.
Again, I hope this helps!! Have fun!
P.S. GenFunc is located in the enclosed TEST.prg. After playing with it,
just strip GenFunc out and modify it to suit your keystroke conventions.
P.P.S. Test.dbf uses a function called shadbox, a nice p/d function. How-
ever shadbox sometimes acts funny if FUNCky is linked in. The first time
shadbox is invoked, the shadow characters are gobblie-gook. The temporary
solution to this is to do a shadbox once and immediately clearing the screen.
The next time shadbox is called, the shadow works fine.
== Galen Mulrooney 12/11/1990
December 10, 2017
Add comments