PowerCalendar!

A dynamic monthly calendar for Powerhouse users


This screen displays a monthly calendar. It can display the current month, or any user selected month. It can also display computed periods (days until Christmas, etc.) or a list of people whose birthdays occur in the displayed month.

Keep in mind that this is only a sample screen, and hopefully hints at additional functionality you might find of interest in your particular application.

Note: I have not added control of the function keys, but leave that as an exercise for the reader. The keys listed below are my suggestions for their implementation.

Commands:
Help <F1> Reserved for Help
Tdy <F2> Home (Today)
Prev <F3> Prev Month
Next <F4> Next Month
PYr <F5> Prev Year
NYr <F6> Next Year
GoTo <F7> Jump to Month
^ <F8> Exit

And now, the source code, annotated with comments.

Because there is no Primary file, the screen can be a Menu.
     SCREEN CALENDAR MENU

Date-Array is an array to hold the day numbers to be displayed. Tdy-Left and Tdy-Right will hold the brackets that highlight the current day of the month.

     TEMP DATE-ARRAY    INT  SIZE 02 OCCURS 37 TIMES
     TEMP TDY-LEFT      CHAR SIZE 01 OCCURS 37 TIMES
     TEMP TDY-RIGHT     CHAR SIZE 01 OCCURS 37 TIMES

T-Mo and T-Yr hold the month and year currently displayed.

     TEMP T-MO          INT  SIZE 02
     TEMP T-YR          INT  SIZE 02

Cntr is a counter used in building the month table. Day-1 and Day-L hold the day of the week upon which the first of the falls and the last day of the month.

     TEMP CNTR          INT  SIZE 02
     TEMP DAY-1         INT  SIZE 02
     TEMP DAY-L         INT  SIZE 02

These fields are used in prompting the user for a specific month to display. Date-Label is the prompt label. Slash is used to show a slash between the month and year fields when prompting the user. New-Mo and New-Yr hold the month and year the user enters.

     TEMP DATE-LABEL    CHAR SIZE 20
     TEMP SLASH         CHAR SIZE 01
     TEMP NEW-MO        INT  SIZE 02
     TEMP NEW-YR        INT  SIZE 02

Event-List is a file that holds a list of birthdays and holidays that can be displayed or highlighted on the screen. The layout I used is as follows, but you may prefer to access an existing personnel file containing birthdays or similar.

EVENT-LIST:
Key Field Name Size Description
EVENT-YR X(4) Year of event (optional)
* EVENT-MO X(2) Month of event
EVENT-DY X(2) Day of the month
EVENT-TYPE X(1) (H)oliday, (B)irthday or (O)ther
EVENT-NAME X(20) Description of event
Access the file using the month currently displayed. If the year matches the currently displayed year or the year is blank, the event description can be displayed, or the day highlighted within the calendar.

     FILE EVENT-LIST DESIGNER
       ACCESS VIA EVENT-MO USING ASCII(T-MO, 2) OPTIONAL
       SELECT IF  EVENT-YR = T-YR OR EVENT-YR = 0

These fields are used to display up to 4 events at the bottom of the calendar.

     TEMP T-EV-NAME     CHAR SIZE 20 OCCURS 4 TIMES
     TEMP T-EV-DAY      INT  SIZE 02 OCCURS WITH T-EV-NAME
     TEMP T-EV-TYPE     CHAR SIZE 01 OCCURS WITH T-EV-NAME
     TEMP EV-FLAG       CHAR SIZE 01

Curr-Mo and Curr-Yr are used to store the current real-world month and year (as opposed to the currently displayed month and year. Curr-Date is needed because SYSDATE may or may not have the century included, and you can't have computations on the left side of an equation, even when it's a comparison in an IF statement.

Many of the following fields are temporaries to save processing time. Bob Deskin explained it better than I could have: "Any static data or data calculated once should be a TEMP. DEFINE's are recalculated every time you reference them."

     TEMP CURR-MO       INT  SIZE 02 INIT MOD(FLOOR(SYSDATE / 100), 100)    &
                                     RESET AT STARTUP

     TEPM CURR-YR       INT  SIZE 02 INIT FLOOR(SYSDATE / 10000)            &  
                                       IF SYSDATE > 991231                  &  
                                     ELSE FLOOR(SYSDATE / 10000) + 1900     &
                                     RESET AT STARTUP

     TEMP CURR-DATE     INT  SIZE 04 RESET AT STARTUP

The names of months, and the currently displayed month/year for display use.

     TEMP MONTH-NAMES CHAR SIZE 108 INIT " January " + &
                                         " February" + &
                                         "  March  " + &
                                         "  April  " + &
                                         "   May   " + &
                                         "   June  " + &
                                         "   July  " + &
                                         "  August " + &
                                         "September" + &
                                         " October " + &
                                         " November" + &
                                         " December"   &
                                    RESET AT STARTUP

     DEFINE DISP-MONTH  CHAR SIZE 15 = TRUNC(MONTH-NAMES                 &
                                             [(T-MO * 9) - 8:9]) +       &
                                       ", " + ASCII(T-YR,4)

Some sample computed numbers -- Days until December 31, 1999 and days until Christmas.

     TEMP EOCENT      INT  SIZE 04 INIT DAYS(19991231) - DAYS(SYSDATE)    &
                                   RESET AT STARTUP

     TEMP XMAS        INT  SIZE 04 INIT DAYS((CURR-YR * 10000) + 1225) -  &
                                        DAYS(SYSDATE)                     &
                                     IF 1225 > MOD(SYSDATE, 10000)        &
                                   ELSE DAYS((CURR-YR * 10000) + 11225) - &
                                        DAYS(SYSDATE)                     &
                                   RESET AT STARTUP

     SKIP TO 01
     ALIGN (,,33)

Title for the calendar, consisting of the month and year. It Could also include a department name or other information.

     FIELD DISP-MONTH DISPLAY NOLABEL NOID

Titles for the days of the week.

     TITLE "Sunday"     AT 03,04
     TITLE "Monday"     AT 03,15
     TITLE "Tuesday"    AT 03,26
     TITLE "Wednesday"  AT 03,37
     TITLE "Thursday"   AT 03,48
     TITLE "Friday"     AT 03,59
     TITLE "Saturday"   AT 03,70

Lines to draw the actual calendar boxes.

     DRAW THIN FROM 04,02 TO 04,79
     DRAW THIN FROM 07,02 TO 07,79
     DRAW THIN FROM 10,02 TO 10,79
     DRAW THIN FROM 13,02 TO 13,79
     DRAW THIN FROM 16,02 TO 16,79
     DRAW THIN FROM 19,02 TO 19,79
     DRAW THIN FROM 22,02 TO 22,24

     DRAW THIN FROM 04,02 TO 22,02
     DRAW THIN FROM 04,13 TO 22,13
     DRAW THIN FROM 04,24 TO 22,24
     DRAW THIN FROM 04,35 TO 19,35
     DRAW THIN FROM 04,46 TO 19,46
     DRAW THIN FROM 04,57 TO 19,57
     DRAW THIN FROM 04,68 TO 19,68
     DRAW THIN FROM 04,79 TO 19,79

Fields used to prompt the user for a specific month to display.

     SKIP TO 1
     ALIGN (,,53) (,,73) (,,75) (,,76)
     
     FIELD DATE-LABEL DISPLAY
     FIELD NEW-MO     PIC "^^"   BWZ VALUES 1 TO 12
     FIELD SLASH
     FIELD NEW-YR     PIC "^^^^" BWZ VALUES 0 TO 100, 1800 TO 2800

The array that displays the days of the month.

     CLUSTER OCCURS WITH DATE-ARRAY FOR 3,11 AT 5,3 NOID

     ALIGN (,,09) (,,10) (,,12)

     FIELD TDY-LEFT    NOLABEL NOID DISPLAY PIC "^"
     FIELD DATE-ARRAY  NOLABEL NOID DISPLAY PIC "^^" BWZ
     FIELD TDY-RIGHT   NOLABEL NOID DISPLAY PIC "^"
     
     CLUSTER

Sample computed numbers.

     SKIP TO 20

     ALIGN (,27,44)

     FIELD EOCENT DISPLAY LABEL "Days until '00:  "                      &
                  PIC " ^,^^^" LEAD SIGN "-" PREDISPLAY
     FIELD XMAS   DISPLAY LABEL "Days until Xmas: "                      &
                  PIC " ^,^^^" LEAD SIGN "-" PREDISPLAY

Fields to display info from the Event-List file.

     SKIP TO 20

     CLUSTER OCCURS WITH T-EV-NAME FOR 1,28 AT 20,53
     
     ALIGN (,,53) (,,75) (,,79)

     FIELD T-EV-NAME DISPLAY NOLABEL NOID
     FIELD T-EV-DAY  DISPLAY NOLABEL NOID PIC "^^"
     FIELD T-EV-TYPE DISPLAY NOLABEL NOID

     CLUSTER

Checks if the user entered a two-digit year, and adds a default century.

     PROCEDURE EDIT     NEW-YR
       BEGIN
         IF NEW-YR < 100
            THEN BEGIN
              LET FIELDVALUE = FIELDVALUE + 1900
            END
       END

Loads the display fields for events with data from the file.

     PROCEDURE INTERNAL GET-EVENTS
       BEGIN
         LET EV-FLAG = "N"
         FOR T-EV-NAME
           BEGIN
             IF T-EV-NAME = "" AND EV-FLAG = "N"
                THEN BEGIN
                  LET T-EV-NAME = EVENT-NAME
                  LET T-EV-DAY  = EVENT-DY
                  LET T-EV-TYPE = EVENT-TYPE
                  DISPLAY T-EV-NAME
                  DISPLAY T-EV-DAY
                  DISPLAY T-EV-TYPE
                  LET EV-FLAG = "Y"
                END
           END
       END

Generates the actual calendar.

     PROCEDURE INTERNAL CALC-CAL
       BEGIN
         LET CNTR  = 1
         LET DAY-1 = MOD(DAYS((T-YR * 10000) + (T-MO * 100) + 01), 7) + 1
         LET DAY-L = MOD(LASTDAY((T-YR * 10000) + (T-MO * 100) + 01), 100)
         FOR DATE-ARRAY
           BEGIN
             IF CNTR >= DAY-1 AND CNTR <= DAY-L + DAY-1 - 1
                THEN BEGIN
                  LET DATE-ARRAY = CNTR - DAY-1 + 1
                  IF CURR-DATE = (T-YR * 10000) + &
                                 (T-MO * 100)   + &
                                 DATE-ARRAY
                     THEN BEGIN
                       LET TDY-LEFT  = "["
                       LET TDY-RIGHT = "]"
                     END
                     ELSE BEGIN
                       LET TDY-LEFT  = " "
                       LET TDY-RIGHT = " "
                     END
                END
                ELSE LET DATE-ARRAY = 0
             DISPLAY DATE-ARRAY
             DISPLAY TDY-LEFT
             DISPLAY TDY-RIGHT
             LET CNTR = CNTR + 1
           END
         FOR T-EV-NAME
           LET T-EV-NAME = " "
         WHILE RETRIEVING EVENT-LIST
           BEGIN
             DO INTERNAL GET-EVENTS
           END
         DISPLAY DISP-MONTH
         INFO " " NOW
       END

Sets the display month to the real-world month and displays the calendar.

     PROCEDURE DESIGNER TDY NODATA
       BEGIN
         LET T-MO = CURR-MO
         LET T-YR = CURR-YR
         DO INTERNAL CALC-CAL
       END

Computes the next month and displays it.

     PROCEDURE DESIGNER NEXT NODATA
       BEGIN
         LET T-YR = T-YR + FLOOR(T-MO  / 12)
         LET T-MO = MOD(T-MO , 12) + 1
         DO INTERNAL CALC-CAL
       END

Computes the previous month and displays it.

     PROCEDURE DESIGNER PREV NODATA
       BEGIN
         LET T-MO = MOD(T-MO + 10, 12) + 1
         LET T-YR = T-YR - FLOOR(T-MO /12)
         DO INTERNAL CALC-CAL
       END

Computes and displays the same month last year.

     PROCEDURE DESIGNER PYR  NODATA
       BEGIN
         LET T-YR = T-YR - 1
         DO INTERNAL CALC-CAL
       END

Computes and displays the same month next year.

     PROCEDURE DESIGNER NYR  NODATA
       BEGIN
         LET T-YR = T-YR + 1
         DO INTERNAL CALC-CAL
       END

Prompts the user for a specific month and year, and displays the appropriate calendar.

     PROCEDURE DESIGNER   GOTO NODATA
       BEGIN
         LET DATE-LABEL = "Enter month & year:"
         LET NEW-MO     = T-MO
         LET SLASH      = "/"
         LET NEW-YR     = T-YR
         DISPLAY DATE-LABEL
         DISPLAY NEW-MO
         DISPLAY SLASH
         DISPLAY NEW-YR
         ACCEPT NEW-MO
         ACCEPT NEW-YR
         LET T-MO = NEW-MO
         LET T-YR = NEW-YR
         DO INTERNAL CALC-CAL
         LET DATE-LABEL = " "
         LET NEW-MO     = 0
         LET SLASH      = " "
         LET NEW-YR     = 0
         DISPLAY DATE-LABEL
         DISPLAY NEW-MO
         DISPLAY SLASH
         DISPLAY NEW-YR
       END

The screen initially displays the current real-world month.

     PROCEDURE INITIALIZE
       BEGIN
         LET CURR-DATE = (CURR-YR * 10000) +               &
                         (CURR-MO * 100)   +               &
                         MOD(SYSDATE, 100)
         LET T-MO = CURR-MO
         LET T-YR = CURR-YR
         DO INTERNAL CALC-CAL
       END

     BUILD LIST

This program may be used, modified, copied, or otherwise put to use so long as credit is given to the author, and it is not used in or as part of a commercial program or other for-profit venture without prior approval. You can download a copy of the source code, ready to be compiled and put to use.

If you have any questions or comments about this screen, Powerhouse, or how Roger Louis Sinasohn & Associates can assist you, please feel free to e-mail us at <roger@sinasohn.com> or contact us at 1-415-469-7924.


Many thanks to Bob Deskin, Cognos' own Powerhouse Guru Extraordinaire for comments and suggestions.


[Home] [Back]