"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" FINDING ROWS THAT FALL BETWEEN TWO DATES """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" PRODUCT : R:BASE VERSION : 3.1 CATEGORY : PROGRAMMING SUBCATEGORY : TOOLS """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" From HB Sloan, 1288 W. 11th St. #117, Tracy, CA 95376. You can reach HB at 209-836-5713. Applications frequently need to construct a WHERE clause based on two dates supplied by the person using the application. For example, you might want to print a report for rows that fall between two dates, or browse through rows entered since 6/1/91 or before 1/1/91. To fill this need, I developed a generic utility that I call WHEDATE.CMD (listed below and included in 0891MRIM.ZIP) to construct the WHERE clause. It uses a pop-up screen (WHEDATE.SNP) to collect the beginning and ending dates. Use the program MAKESNAP.CMD (listed below) to make WHEDATE.SNP. When WHEDATE.CMD asks for the beginning and ending dates, you can enter either date or both dates. If you enter only a beginning date, the program assumes you want all the dates since that date (inclusive). If you enter only an ending date, it assumes you want all the dates up to and including that ending date. What WHEDATE.CMD Does """"""""""""""""""""" WHEDATE.CMD takes a snapshot of the current screen (TMP.SNP), collects the dates using WHEDATE.SNP as a pop-up screen, and later restores the screen by displaying TMP.SNP. WHEDATE.CMD uses the collected dates to construct the WHERE clause, which it puts into the variable PV_BETW before returning control to the calling program. WHEDATE.CMD has a default value feature. Set up default values for either or both of the two dates by setting PV_DATE1 or PV_DATE2 to a specific date before running WHEDATE.CMD. WHEDATE.CMD displays */*/* for any date you leave null. During execution, WHEDATE.CMD uses the CVAL function to store original environment conditions, which it restores at the end of the routine. How to Make WHEDATE.SNP """"""""""""""""""""""" WHEDATE.CMD requires a snapshot file named WHEDATE.SNP. To make it, use CONNECT to open any database. Then set the background color to the background color of the application, and run this program: *( MAKESNAP.CMD--Make WHEDATE.SNP,) *( snapshot file required by WHEDATE.CMD.) CLS SET MESSAGES OFF SET ERROR MESSAGES OFF CREATE TABLE snapper (snapper TEXT 63) SET VAR vrow1 = (SFIL(' ',22) + 'Enter Date Range' + + SFIL(' ',22) + CHAR(255)) LOAD snapper .vrow1; ' '; ' '; ' '; ' ' END CLS WRITE ' Press [Enter] ' AT 20,30 white ON red CHOOSE v1 FROM #VALUES FOR snapper FROM snapper AT 10,10 SNAP whedate.snp FROM 10,10 TO 17,76 REMOVE TABLE snapper MAKESNAP.CMD makes the snapshot file by taking a snapshot of an actual pop-up box where all the choices are blank lines. You only need to run it once unless you change the application's background color. When you run WHEDATE.CMD, you see what appears to be a true pop-up box because WHEDATE.SNP is based on a real pop-up and WHEDATE.CMD restores the original screen. How to Run WHEDATE.CMD """""""""""""""""""""" Use the WHEDATE.CMD file included in this MRIM0891.ZIP file and run MAKESNAP.CMD to create WHEDATE.SNP. Then run WHEDATE.CMD by passing the following three parameters in the USING clause: o Screen line number (1 to 19) to display WHEDATE.SNP. o Screen column number (1 to 14) to display the top left corner of WHEDATE.SNP. o Name of the DATE column that you want referenced in the WHERE clause. For example, with the CONCOMP database, you might use the following command to collect and display transaction records falling in a date range: RUN whedate.cmd USING 10,10,'transdate' SELECT * FROM transmaster &pv_betw Listing of WHEDATE.CMD """""""""""""""""""""" *( WHEDATE.CMD--Create and return a variable PV_BETW) *( that contains a WHERE clause specifying a DATE range.) *( It displays a snap file named WHEDATE.SNP to collect) *( beginning and ending dates. Dates left null are shown as */*/*.) *( Before running, you can set default values by setting PV_DATE1) *( to a beginning date and PV_DATE2 to an ending date. When) *( you run WHEDATE.CMD include the following three parameters) *( in USING clause: ...USING scrnline, scrnpos, datecol) *( SCRNLINE--screen line number (1 to 19) to display snap file.) *( SCRNPOS--position (1 to 14) on the line to display snap file.) *( DATECOL--name of the DATE column for the WHERE clause.) *( Example: RUN whedate.cmd USING 10,10 'transdate') *( Then use PV_BETW in a command like this:) *( Example: SELECT * FROM transmaster &pv_betw) *( WHEDATE.CMD requires the snap file WHEDATE.SNP and) *( returns the WHERE clause in the variable PV_BETW. It stores) *( the original environment and snaps the original screen. Then it) *( restores the screen and environment at the end of the program.) SNAP tmp.snp *( Snap the current screen.) SET ERROR VAR sv_errv *( Use CVAL to store current environment to restore at the end.) SET VAR lv_oldmess = (CVAL('MESSAGE')), + lv_olderr = (CVAL('ERROR')), oldmany = (CVAL('MANY')) SET VAR vbar TEXT = (CHAR(219)), vbar = (SFIL(.vbar,24)), + lv_dateT TEXT = '*/*/*', lv_org_row INTEGER = .%1, + lv_org_col INTEGER = .%2, lv_column TEXT = .%3, + pv_date1 DATE, pv_date2 DATE, + pv_betw TEXT = ( 'WHERE' & .lv_column ), + lv_r3 = (.lv_org_row + 3), lv_r4 = (.lv_org_row + 4), + lv_c5 = (.lv_org_col + 5), lv_c30 = (.lv_org_col + 30), + lv_c40 = (.lv_org_col + 40) SET MESSAGES OFF; SET ERROR MESSAGES OFF DEBUG SET MESSAGES ON; DEBUG SET ERROR MESSAGES ON *( Change the MANY setting so you can clear percent variables.) SET MANY=* CLEAR VAR %1, %2, %3 SET MANY=% CLS; DISPLAY whedate.snp AT .lv_org_row .lv_org_col WRITE ' Enter Beginning Date: ' AT .lv_r3 .lv_c5 white ON gray WRITE ' ' AT .lv_r3 .lv_c30 *( 10 spaces inside quotes.) WRITE ' Enter Ending Date: ' AT .lv_r4 .lv_c5 white ON gray WRITE ' ' AT .lv_r4 .lv_c30 *( 10 spaces inside quotes.) LABEL date1 WRITE .vbar AT .lv_r3 .lv_c40 gray FILLIN pv_date1=10 AT .lv_r3 .lv_c30 EDIT IF sv_errv <> 0 THEN WRITE ' <--Invalid DATE.' AT .lv_r3 .lv_c40 gray ON black BLINK PAUSE 2 GOTO date1 ENDIF SHOW VAR pv_date1=10 AT .lv_r3 .lv_c30 SET VAR lv_last = (LASTKEY(0)) IF lv_last = '[Esc]' OR lv_last = '[Up]' OR lv_last = '[PgUp]' THEN SET VAR pv_betw = ' ' GOTO goback ENDIF IF pv_date1 IS NULL THEN WRITE .lv_datet AT .lv_r3 .lv_c30 ENDIF LABEL date2 WRITE .vbar AT .lv_r4 .lv_c40 gray FILLIN pv_date2=10 AT .lv_r4 .lv_c30 edit IF sv_errv <> 0 THEN WRITE ' <--Invalid DATE.' AT .lv_r4 .lv_c40 gray ON black BLINK PAUSE 2; GOTO date2 ENDIF SHOW VAR pv_date2=10 AT .lv_r4 .lv_c30 SET VAR lv_last = (LASTKEY(0)) IF lv_last = '[Esc]' OR lv_last = '[Up]' OR lv_last = '[PgUp]' THEN GOTO date1 ENDIF IF pv_date2 IS NULL THEN; WRITE .lv_datet AT .lv_r4 .lv_c30 ENDIF *( Check for both dates null.) LABEL both_null IF pv_date1 IS NULL AND pv_date2 IS NULL THEN SET VAR pv_betw = (.pv_betw & 'IS NOT NULL' ), + pv_date1 TEXT = .lv_datet, pv_date2 TEXT = .lv_datet GOTO goback ENDIF *( Check for only an ending date.) IF pv_date1 IS NULL AND pv_date2 IS NOT NULL THEN SET VAR pv_betw = (.pv_betw & '<=' & CTXT(.pv_date2)), + pv_date1 TEXT = .lv_datet GOTO goback ENDIF *( Check for only a beginning date.) IF pv_date1 IS NOT NULL AND pv_date2 IS NULL THEN SET VAR pv_betw = (.pv_betw & '>=' & CTXT(.pv_date1) ), + pv_date2 TEXT = .lv_datet GOTO goback ENDIF *( Both dates are present. Check them.) LABEL no_null IF pv_date1 = pv_date2 THEN SET VAR pv_betw = (.pv_betw & '=' & CTXT(.pv_date1)) GOTO goback ENDIF *( Check for beginning date bigger than ending date.) IF pv_date1 > .pv_date2 THEN PAUSE 1 USING + 'Beginning date is after ending date, so all dates included.' SET VAR pv_date1 = NULL, pv_date2 = NULL GOTO both_null ENDIF SET VAR pv_betw = (.pv_betw & 'BETW' & CTXT(.pv_date1) + & 'AND' & CTXT(.pv_date2)) LABEL goback CLS; DISPLAY tmp.snp *( Redisplay the current screen.) DEL tmp.snp SET ERROR MESSAGES .lv_olderr; SET MESSAGES .lv_oldmess CLEAR VAR lv%, pv_date%, vbar, sv_errv SET MANY=.oldmany; CLEAR VAR oldmany RETURN WHEDATE.CMD's Four Possibilities """""""""""""""""""""""""""""""" WHEDATE.CMD handles all four possible combinations. For example, if the column name passed in the USING clause is TDATE, here are the four possible WHERE clauses: o Null beginning & null ending date: WHERE tdate IS NOT NULL. o 8/1/91 ending date & null beginning date: WHERE tdate <= 8/1/91. o 7/1/91 beginning date & null ending date: WHERE tdate >= 7/1/91. o 7/1/91 beginning date & 8/1/91 ending date: WHERE tdate BETWEEN 7/1/91 AND 8/1/91.