Newsgroups: comp.databases.informix Subject: Useful 4gl Function Date: 10 Feb 94 21:46:41 GMT here is a very userful Informix function that all users will love. It pops up a calendar with the starting date of the calendar being the date the programmer calls it with. The user can then select a valid date, or go back a month or forward a month or to any date. Have Fun Stuart Litel 75110.1120@compuserve.com 9 years of Informix programming and I feel like I am stuck in a ring menu with no Exit main define cc smallint define dte date defer interrupt options input wrap call calx(TODAY) returning cc, dte if (cc = TRUE) then display "User selected: ", dte else display "User cancelled" end if end main # #############CUT HERE FOR CALX.4gl########################################### # Modified by Stuart Litel (Internet: 75110.1120@compuserve.com) # # This program lets you pop up a calendar with a default date # The user then may press Function keys to the next month or previous month # Or they may enter any date and the calendar will go to that month # # If the user presses the Accept key, the function will return TRUE and # the date. If they press the INTERRUPT (in this case where I wrote it # for it was ^C) then it will return FALSE meaning the user selected no # date. # # # The only requirement is calx.per which is at the bottom of this # file. This is very useful and all users who have any date entry # love it since they now have a calendar. It can be setup with an on-key # statement for any date field you have to call the pop-up calendar. # # To test it out,simply cut out the form below and call it calx.per. # # Then compile the form and compile this program "as is" and run it. # # To build into your code, simply remove the main above and and include it # in your code. # ############################################################################# ############################################################################# # Routine : calx # # Purpose : setup and control for calendar display # # Arguments : sdte - date to start display with # # Returns : cc - TRUE if user selected, FALSE if they did not # sdte - a selected date (IF CC = TRUE) # ############################################################################# function calx(sdte) define sdte date define cc smallint define in_date date define old_date date if (sdte is not NULL) then let in_date = sdte else let in_date = today end if open window calx at 6,15 with form "calx" #14 rows, 25 columns attribute (border, comment line 1, form line 1) display "^N=Next Mon, ^P-Prev. Mon, ^T=Today" at 13,2 display "^C=Interrupt, Esc=Accept" at 14,2 call calendar(in_date,2,1,1) let old_date = in_date let cc = TRUE let int_flag = FALSE input in_date without defaults from formonly.in_date on key (control-N) #next month call get_mon("N",old_date) returning in_date call calendar(in_date,2,1,1) let old_date = in_date display in_date to formonly.in_date on key (Control-P) #last month call get_mon("B",old_date) returning in_date call calendar(in_date,2,1,1) let old_date = in_date display in_date to formonly.in_date on key (Control-T) let in_date = today call calendar(in_date,2,1,1) let old_date = in_date display in_date to formonly.in_date before field in_date display in_date to formonly.in_date after field in_date if (in_date is not NULL) then call calendar(in_date,2,1,1) let old_date = in_date end if end input if (int_flag = TRUE) then let cc = FALSE let int_flag = FALSE end if close window calx return cc, old_date end function #PB #----------------------------------------------------------------------------- # Routine : calendar # # Purpose : calculates and displays actual calendar # # Arguments : in_date date to start display at # v_pos Vertical position of top of calendar # h_offset horizontal start of display # actual_flag smallint # # Returns : Nothing. #----------------------------------------------------------------------------- function calendar(in_date,v_pos,h_offset,actual_flag) define temp_date date #First date for the month {05/01/1989} define in_date date define in_month smallint #Month passed in through in_date define in_year smallint #Year passed in through in_date define in_day smallint #Day of mon passed in through in_date{1-31} define in_wkday smallint #Weekday in numerical form {0 = Sunday} define first_wkday smallint #Weekday of the first day of the month define v_pos smallint #Vertical position of top of calendar define h_pos smallint #+ h_offset = screen position of next date #to be displayed define h_offset smallint define actual_flag smallint define day_count smallint #Position within wk of the date to display define max_days smallint #Number of days in this month define in_mon_word char(20) define in_day_word char(20) #English word for the day of the week define v_sp_pos smallint define x smallint # Break the date up into its parts let in_wkday = weekday(in_date) let in_month = month(in_date) let in_year = year(in_date) let in_day = day(in_date) # create the first day of the month to get the first wkday of the month let temp_date = mdy(in_month,1,in_year) let first_wkday = weekday(temp_date) # get the number of days in the month let max_days = maximum_days(in_month,in_year) # get the English abbreviation of the month and day let in_mon_word = month_word(in_month) let in_day_word = day_word(in_wkday) # Display the verbiage at the top of the calendar for x = v_pos to v_pos + 7 display "" at x,1 end for #display month and year we are in display " ",in_mon_word clipped,", ",in_year at v_pos,h_offset #update the vertical position let v_pos = v_pos + 1 #Show the Saturday through Sunday bar at the top of the calendar display " S M T W T F S " at v_pos,h_offset attribute(reverse) #calculate the horizontal position on the screen for the 1st day of month let h_pos = h_offset+((first_wkday)*3) # update the vertical position let v_pos = v_pos + 1 # clear the line first display "" at v_pos,h_offset # place days on the calendar for day_count = 1 to max_days if (day_count = in_day) and (actual_flag = 1) then # high-light the passed in date display day_count using "###" at v_pos,h_pos attribute (REVERSE) else # display the dates in normal video display day_count using "###" at v_pos,h_pos end if if (h_pos < h_offset+18) then # haven't reached the right side let h_pos = h_pos + 3 else # move to the next week position let h_pos = h_offset let v_pos = v_pos + 1 # clear the line first display "" at v_pos,h_offset end if end for end function #----------------------------------------------------------------------------- # Routine : day_word # # Purpose : figure out what day of the week it is # # Arguments : in_wkday (0 for Sunday .... 6 for Saturday) # # Returns : dow Character day of the week (Sunday, Monday....) #----------------------------------------------------------------------------- function day_word(in_wkday) define in_wkday smallint define dow char(9) case when in_wkday = 0 let dow = "Sunday" when in_wkday = 1 let dow = "Monday" when in_wkday = 2 let dow = "Tuesday" when in_wkday = 3 let dow = "Wednesday" when in_wkday = 4 let dow = "Thursday" when in_wkday = 5 let dow = "Friday" when in_wkday = 6 let dow = "Saturday" end case return dow end function #PB #----------------------------------------------------------------------------- # Routine : month_word # # Purpose : figure out what month it is # # Arguments : in_month (1 for January .... 12 for December) # # Returns : mon Character month (January, Febuary, etc...) #----------------------------------------------------------------------------- function month_word(in_month) define in_month smallint define mon char(11) case when in_month = 1 let mon = "January" when in_month = 2 let mon = "February" when in_month = 3 let mon = "March" when in_month = 4 let mon = "April" when in_month = 5 let mon = "May" when in_month = 6 let mon = "June" when in_month = 7 let mon = "July" when in_month = 8 let mon = "August" when in_month = 9 let mon = "September" when in_month = 10 let mon = "October" when in_month = 11 let mon = "November" when in_month = 12 let mon = "December" end case return mon end function #----------------------------------------------------------------------------- # Routine : maximum_days # # Purpose : To figure how many days are in the month # # Arguments : in_month 1 thru 12 fro month we want # in_year what year are we in??? # # Returns : dy the number of days in the month #----------------------------------------------------------------------------- function maximum_days(in_month,in_year) define in_month smallint define in_year smallint define dy smallint case when (in_month = 1 or in_month = 3 or in_month = 5 or in_month = 7 or in_month = 8 or in_month = 10 or in_month = 12) let dy = 31 when in_month = 4 or in_month = 6 or in_month = 9 or in_month = 11 let dy = 30 otherwise # this is February so check for a leap year if (in_year mod 4 = 0 and in_year != 2000 ) then # this is a leap year let dy = 29 else let dy = 28 end if end case return dy end function #----------------------------------------------------------------------------- # Routine : get_mon # # Purpose : to get next or previous month # # Arguments : opt #'F'orwards or 'B'ackwards # dte the date we want to find the month for # # Returns : dte start of month #----------------------------------------------------------------------------- function get_mon(opt,dte) define opt char(1) #'F'orwards or 'B'ackwards define dte date define str char(10) define mon smallint define yr smallint let str = dte using "MM/DD/YYYY" let mon = str[1,2] let yr = str[7,10] if (opt = "B") then let mon = mon - 1 if (mon < 1) then let mon = 12 let yr = yr - 1 end if else let mon = mon + 1 if (mon > 12) then let mon = 1 let yr = yr + 1 end if end if let str = mon using "##", "/01/",yr using "####" let dte = str return dte end function ####CUT HERE for calx.per ########################### database formonly screen { Date [f000 ] } end attributes f000 = formonly.in_date, reverse; end ######END OF FORM calx.per #####################################