tags:

views:

41

answers:

2

I have searched in several software repositories but havent come across any.

+1  A: 

Most complex ISQL forms and reports are fairly tightly tied to a specific operational database and are not of much interest outside the particular niche where they are used.

Another problem is that complex reports and forms are fairly bit. This is one of the largest, and one of the latest I've written. The system is not in use any more. It was for tracking Feature Requests etc for Informix. It will fit within the limit of what SO accepts, but not with all that much to spare (443 lines, about 20KB with no tabs). It generates a reasonably complex report with HTML formatting. (The schema produced by DB-Schema is too big for a single answer at over 40 KB, but mainly because it included a number of moderately complex stored procedures invoked by triggers.)

-- @(#)$Id: frdbhtml95.ace,v 4.14 2003/02/12 19:55:00 jleffler Exp $
-- @(#)Project: Servers 9.Next Feature Prioritization
-- @(#)Feature Prioritization Report - HTML Output
-- @(#)Author: JL

DATABASE frdb@smartpts END

DEFINE
    PARAM[1] list_num INTEGER
    VARIABLE asd_url CHAR(70)
    VARIABLE pts_url CHAR(70)
    VARIABLE version CHAR(45)
    VARIABLE c CHAR(1)      -- HTML metacharacter mapping
    VARIABLE i INTEGER      -- HTML metacharacter mapping
    VARIABLE j INTEGER      -- HTML metacharacter mapping
    VARIABLE map VARCHAR(5)     -- HTML metacharacter mapping
    VARIABLE pad INTEGER        -- HTML metacharacter mapping
    VARIABLE sd      CHAR(350)  -- Copy of short description
    VARIABLE theme_count INTEGER
    VARIABLE disp_count INTEGER
    VARIABLE gr_disp_count INTEGER  -- Count of groups of dispositions
    VARIABLE gr_fgrp_count INTEGER  -- Count of feature groups within theme
    VARIABLE ov_fgrp_count INTEGER  -- Count of feature groups overall
    VARIABLE ov_fnum_count INTEGER  -- Count of feature numbers overall
END

OUTPUT
    PAGE LENGTH 90
    TOP MARGIN 0
    BOTTOM MARGIN 0
    LEFT MARGIN 0
    RIGHT MARGIN 80
END

-- Create temp table x8 with fr_grp numbers, and fr_num as members of group.
-- Group leaders are tagged 'A'; group members are tagged 'B'.
SELECT f9.fr_num as fr_grp, f9.fr_num as fr_num, 'A' AS fr_type
    FROM fr_list_items f9
    WHERE f9.fr_num NOT IN (SELECT member FROM fr_bug_group WHERE fr_list_num = $list_num)
      AND f9.abc_category != 'X'
      AND f9.fr_status != 'D'
      AND f9.fr_list_num = $list_num
UNION
SELECT f9.fr_num as fr_grp, grp.member as fr_num, 'B' AS fr_type
    FROM fr_list_items f9, fr_bug_group grp
    WHERE f9.fr_num = grp.master
      AND f9.abc_category != 'X'
      AND f9.fr_list_num = $list_num
      AND grp.fr_list_num = $list_num
    INTO TEMP x8;

-- Create temp table with fr_grp number and number of rows in the group.
SELECT fr_grp, COUNT(*) AS grp_size
    FROM x8
    GROUP BY fr_grp
    INTO TEMP x9;

SELECT
    f8.theme AS theme,              -- defined by group master
    f8.disposition AS disposition,  -- defined by group master
    f8.abc_category AS category,    -- defined by group master
    f8.priority AS fe_priority,     -- defined by group master
    x8.fr_grp,                      -- sequencing
    x8.fr_type,                     -- sequencing
    x8.fr_num,                      -- PTS FR number
    th.priority AS th_priority,     -- sequencing
    bug.short_description,          -- FR Description
    th.description AS theme_name,   -- sequencing
    di.description AS disp_name,    -- sequencing
    di.priority AS di_priority,     -- sequencing
    l.title,                        -- list title
    o.owner_name AS owner,          -- list owner
    l.updated,                      -- last time list modified
    p.project_id,                   -- project number
    p.codename,                     -- project code name
    p.description,                  -- project description
    p.projname,                     -- project name
    f8.risk,                        -- defined by group master
    f8.effort,                      -- defined by group master
    f8.benefit,                     -- defined by group master
    f8.impacts_csdk,                -- defined by group master
    f8.req_user AS req_who,         -- who it was requested by
    f8.req_why,                     -- why it was requested
    x9.grp_size                     -- for ROWSPAN information.
FROM
    x8,
    x9,
    fr_list_items f8,
    themes th,
    dispositions di,
    pts_bug bug,
    fr_lists l,
    projects p,
    owners o
WHERE f8.theme = th.theme
  AND f8.disposition = di.code
  AND x8.fr_grp = f8.fr_num
  AND x8.fr_grp = x9.fr_grp
  AND x8.fr_num = bug.bug_num
  AND f8.fr_list_num = $list_num
  AND f8.fr_list_num = l.fr_list_num
  AND l.owner_id = o.owner_id
  AND l.project_id = p.project_id
  AND th.project_id = p.project_id
  AND di.project_id = p.project_id
ORDER BY th_priority DESC, theme_name, di_priority DESC, disposition,
         category, fe_priority DESC, fr_grp, fr_type, fr_num

END

FORMAT

FIRST PAGE HEADER
    LET pts_url = "http://lxptsws1.lenexa.ibm.com/Reporter/buginfo.cgi?bug="
    LET asd_url = "http://rose.oak.informix.com/projects/falcon/FalconDocs3.html"
    PRINT "<HTML>"
    PRINT "<HEAD>"
    PRINT "<TITLE> Feature List: Themes and Prioritization </TITLE>"
    PRINT "</HEAD>"
    PRINT "<BODY BGCOLOR=WHITE>"
    PRINT "<A NAME='top'>&nbsp;</A>"
    PRINT "<H1 ALIGN=CENTER> Feature List: Themes and Prioritization </H1>"
    PRINT "<CENTER><B> <!--REPORT-DATE--> ", CURRENT YEAR TO SECOND, " </B></CENTER>"
    PRINT "<BR>"

    PRINT "<TABLE ALIGN=CENTER WIDTH=95% BORDER=2 BGCOLOR='#CCCCFF'>"
    PRINT "<TR><TD COLSPAN=2 ALIGN=CENTER>", " Project Number ", project_id, "</TD></TR>"
    PRINT "<TR><TH WIDTH=50%> ", codename CLIPPED, " </TH><TH WIDTH=50%> ", projname CLIPPED, "</TH></TR>"
    PRINT "<TR><TD COLSPAN=2 ALIGN=CENTER>", description, "</TD></TR>"
    PRINT "</TABLE>"
    PRINT "<BR>"

    PRINT "<TABLE ALIGN=CENTER WIDTH=95% BORDER=2 BGCOLOR='#CCCCFF'>"
    PRINT "<TR><TD COLSPAN=2 ALIGN=CENTER>", " Feature List Number ", list_num, "</TD></TR>"
    PRINT "<TR><TH COLSPAN=2 ALIGN=CENTER>", title, "</TH></TR>"
    PRINT "<TR><TD WIDTH=50%>", " Owner ", owner, "</TD><TD WIDTH=50%>", " Last Modified ", updated, "</TD></TR>"
    PRINT "</TABLE>"
    PRINT "<BR>"

    PRINT "<P><TABLE ALIGN=CENTER WIDTH=95% BORDER=2>"
    PRINT "<TR><TD> Categories: A (must fix), B (might fix), C (won't fix) </TD></TR>"
    PRINT "<TR><TD> Priorities: -1 unassigned, 0 (won't happen) to 9 (very important)"
    PRINT "</TD></TR>"
    PRINT "<TR><TD> Risk: H(igh), M(edium), L(ow) </TD></TR>"
    PRINT "<TR><TD> Cost: H(igh), M(edium), L(ow) </TD></TR>"
    PRINT "<TR><TD> Benefit: H(igh), M(edium), L(ow) </TD></TR>"
    PRINT "<TR BGCOLOR='#CCFFCC'><TD>";
    PRINT "[CSDK] Items tagged with [CSDK] on a green background impact CSDK.";
    PRINT "</TD></TR>"
    PRINT "<TR><TD>";
    PRINT "Items with a white background should not impact CSDK."
    PRINT "</TD></TR>"
    PRINT "</TABLE>"

    PRINT "<P>"

    PRINT "Themes:"

    -- FOREACH SELECT theme, description, priority, COUNT(*)
    --              INTO x_theme, x_desc, x_priority
    --              FROM themes
    --              GROUP BY theme, description, priority
    --              HAVING COUNT(*) > 0
    --              ORDER BY priority DESC, description
    --     PRINT "[<A HREF=#", x_theme CLIPPED, "> ", x_desc CLIPPED, " </A>]"
    -- END FOREACH

    LET theme_count = COUNT WHERE theme = "*no theme*"
    IF theme_count > 0 THEN PRINT "[<A HREF=#*no theme*> No specific theme designated </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "api"
    IF theme_count > 0 THEN PRINT "[<A HREF=#api> Application Development & Standards Compliance </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "bug"
    IF theme_count > 0 THEN PRINT "[<A HREF=#bug> Defect Reduction </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "cms"
    IF theme_count > 0 THEN PRINT "[<A HREF=#cms> Content Management Support </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "harp"
    IF theme_count > 0 THEN PRINT "[<A HREF=#harp> High Availability, Replication, Performance </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "hk"
    IF theme_count > 0 THEN PRINT "[<A HREF=#hk> Housekeeping </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "istar"
    IF theme_count > 0 THEN PRINT "[<A HREF=#istar> Distributed Database </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "isv"
    IF theme_count > 0 THEN PRINT "[<A HREF=#isv> Partner Interoperability/Compatibility </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "os"
    IF theme_count > 0 THEN PRINT "[<A HREF=#os> Platforms and Operating Systems </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "ras"
    IF theme_count > 0 THEN PRINT "[<A HREF=#ras> RAS Improvements </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "security"
    IF theme_count > 0 THEN PRINT "[<A HREF=#security> Security, Authentication, Encryption </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "smart"
    IF theme_count > 0 THEN PRINT "[<A HREF=#smart> SMART Initiative / Ease of Use </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "smv"
    IF theme_count > 0 THEN PRINT "[<A HREF=#smv> Storage Management Vendors </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "swg"
    IF theme_count > 0 THEN PRINT "[<A HREF=#swg> SWG Initiatives </A>]" ELSE PRINT ""
    LET theme_count = COUNT WHERE theme = "xb"
    IF theme_count > 0 THEN PRINT "[<A HREF=#xb> IBM Cross-Brand Integration/Interoperability </A>]" ELSE PRINT ""

    LET ov_fgrp_count = 0
    LET ov_fnum_count = 0

BEFORE GROUP OF theme_name
    PRINT "<HR>"
    PRINT "<A NAME=", theme CLIPPED, "> &nbsp; </A>"
    PRINT "<TABLE WIDTH=95% ALIGN=CENTER BORDER=2>"
    PRINT "<TR><TH COLSPAN=7> <BIG><BIG><B>Theme: ", "<A HREF='Themes-9.50/frdb-", theme CLIPPED, ".html'>",
            theme_name CLIPPED, "</A>", "</B></BIG></BIG></TH></TR>"
    PRINT "<TR>",
          "<TH WIDTH=5%>", "PTS No", "</TH>",
          "<TH COLSPAN=5 WIDTH=15%>", "Category, Priority,<BR>",
          "Risk, Cost, Benefit", "</TH>",
          "<TH WIDTH=80%>", "Description", "</TH>",
          "</TR>"
    LET gr_disp_count = 0
    LET gr_fgrp_count = 0

BEFORE GROUP OF disposition
    SKIP 1 LINE
    PRINT "<TR><TH COLSPAN=7 BGCOLOR='#FFFFCC'>", disp_name, "</TH>"
    PRINT "</TR>"
    LET gr_disp_count = gr_disp_count + 1

BEFORE GROUP OF fr_grp
    LET gr_fgrp_count = gr_fgrp_count + 1
    LET ov_fgrp_count = ov_fgrp_count + 1
    IF impacts_csdk = 'Y' THEN
        PRINT "  <TR BGCOLOR='#CCFFCC'>"
    ELSE
        PRINT "  <TR>"
    PRINT "    <TD WIDTH=5%>";
    PRINT "<A HREF='", pts_url CLIPPED,
            fr_grp USING "<<<<<<", "'> ", fr_grp USING "&&&&&&", " </A>", "</TD>"
    IF (disposition = 'pre-fixed' OR
        disposition = 'rejected' OR
        disposition = 'nfp' OR
        disposition = 'sep') THEN
        PRINT "    <TD COLSPAN=5> &nbsp; </TD>"
    ELSE
        BEGIN
        PRINT "    <TD WIDTH=3%>", category, "</TD>"
        PRINT "    <TD WIDTH=3%>", fe_priority USING "-&", "</TD>"
        PRINT "    <TD WIDTH=3%>", risk, "</TD>"
        PRINT "    <TD WIDTH=3%>", effort, "</TD>"
        PRINT "    <TD WIDTH=3%>", benefit, "</TD>"
        END
    PRINT "    <TD WIDTH=80%><SMALL>"
    IF impacts_csdk = 'Y' THEN PRINT "[CSDK] ";

    # Map HTML characters out of the way
    LET i = 150 # length(short_description) - except that isn't in ACE!
    LET sd = ""
    LET pad = 0
    FOR j = 1 TO i DO
    BEGIN
        LET c = short_description[j]
        IF c = "<" THEN LET map = "&lt;"
        ELSE IF c = ">" THEN LET map = "&gt;"
        ELSE IF c = "&" THEN LET map = "&amp;"
        ELSE LET map = c
        IF pad != 0 THEN
            LET sd = sd CLIPPED, " ", map
        ELSE
            LET sd = sd CLIPPED, map
        IF c = " " OR c IS NULL THEN LET pad = 1
        ELSE LET pad = 0
    END
    PRINT sd CLIPPED WORDWRAP
    PRINT "</SMALL>"
    IF req_who != "no-one" OR req_why != "no reason" THEN
        BEGIN
        PRINT "<BR><SMALL><FONT COLOR=BLUE>", "Requested by ", req_who, " because: "
        PRINT req_why CLIPPED WORDWRAP
        PRINT " </FONT></SMALL>"
        END

        IF grp_size > 1 THEN
        BEGIN
                PRINT "<BR>"
                PRINT "Related feature requests include: "
        END

ON EVERY ROW
    IF fr_type = 'B' THEN
                PRINT "    <A HREF='", pts_url CLIPPED,
                        fr_num USING "<<<<<<", "'> ", fr_num USING "&&&&&&", " </A>"

AFTER GROUP OF fr_grp
    PRINT "</TD></TR>"
    SKIP 1 LINE

AFTER GROUP OF disposition
    SKIP 1 LINE

AFTER GROUP OF theme_name
    PRINT "</TABLE>"
    PRINT "<BR>"
    PRINT "<A HREF='#top'> Top </A>"
    PRINT
        GROUP COUNT USING "<<<<", " Feature Requests listed in ",
        gr_fgrp_count USING "<<<<", " Feature Groups ",
        gr_disp_count USING " with <<<< dispositions",
        " within theme <B>", theme_name CLIPPED, "</B>"
    PRINT "<BR>"

ON LAST ROW
    PRINT "<HR>"
    PRINT "<BR>"
    PRINT COUNT USING "<<<<<", " Total Feature Requests listed in ",
          ov_fgrp_count USING "<<<<<", " Feature Groups"

    PRINT "<P>"
    PRINT "<TABLE WIDTH=60% ALIGN=CENTER><TR><TD>"
    PRINT "<SM><I>"
    PRINT "NB: These statistics are not guaranteed accurate."
    PRINT "But they are much more reliable than those in previous"
    PRINT "versions of this report."
    PRINT "</I></SM>"
    PRINT "</TD></TR></TABLE>"

    PRINT "<P>"
    PRINT "<TABLE WIDTH=60% ALIGN=CENTER BORDER=2>"
    PRINT "<TR><TH COLSPAN = 2> Summary by Categories </TH></TR>"
    PRINT "<TR><TD WIDTH=80%> Category A (must fix) </TD><TD>", (COUNT WHERE category = 'A') USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Category B (may fix) </TD><TD>", (COUNT WHERE category = 'B') USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Category C (won't fix) </TD><TD>", (COUNT WHERE category = 'C') USING "###&", "</TD></TR>"
    PRINT "</TABLE>"
    SKIP 1 LINE

    PRINT "<P>"
    PRINT "<TABLE WIDTH=60% ALIGN=CENTER BORDER=2>"
    PRINT "<TR><TH COLSPAN = 2> Summary by Priorities </TH></TR>"
    PRINT "<TR><TD WIDTH=80%>Priority -1 (no decision) </TD><TD>", (COUNT WHERE fe_priority = -1) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  0 (rejected) </TD><TD>", (COUNT WHERE fe_priority = 0) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  1 (low) </TD><TD>", (COUNT WHERE fe_priority = 1) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  2 </TD><TD>", (COUNT WHERE fe_priority = 2) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  3 </TD><TD>", (COUNT WHERE fe_priority = 3) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  4 </TD><TD>", (COUNT WHERE fe_priority = 4) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  5 (medium) </TD><TD>", (COUNT WHERE fe_priority = 5) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  6 </TD><TD>", (COUNT WHERE fe_priority = 6) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  7 </TD><TD>", (COUNT WHERE fe_priority = 7) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  8 </TD><TD>", (COUNT WHERE fe_priority = 8) USING "###&", "</TD></TR>"
    PRINT "<TR><TD> Priority  9 (high) </TD><TD>", (COUNT WHERE fe_priority = 9) USING "###&"
    PRINT "</TABLE>"

    PRINT "<P>"
    PRINT "<TABLE WIDTH=60% ALIGN=CENTER BORDER=2>"
    PRINT "<TR><TH COLSPAN = 2> Summary by Dispositions </TH></TR>"

    LET disp_count = (COUNT WHERE disposition = "8.33")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for XPS 8.33 release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "8.40")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for XPS 8.40 Release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "8.40-fp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for XPS 8.40 Fix Pack </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "8.50")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for XPS 8.50 Release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.30-fp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.30 Fix Pack </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.31")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.31 release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.40")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.40 release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.40-fp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.40 Fix Pack </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.50")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.50 release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.50-fp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Scheduled for IDS 9.50 Fix Pack </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.60")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Possibility for IDS 9.60 Release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "9.70")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Possibility for IDS 9.70 Release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "deferred")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Deferred until after 9.60 </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "dup")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Duplicate of another feature request </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "nfi")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> No fix planned in the foreseeable future </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "nfp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> No fix possible - not enough information </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "pre-fixed")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Fixed in a previous release </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "rejected")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Feature request is rejected completely  </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "sep")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Someone else's problem (not IDS 9.x R&D) </TD><TD>",
            disp_count USING "###&", "</TD></TR>"
    LET disp_count = (COUNT WHERE disposition = "techsupp")
    IF disp_count > 0 THEN
        PRINT "<TR><TD> Tool to be provided by Technical Support </TD><TD>",
            disp_count USING "###&", "</TD></TR>"

    PRINT "</TABLE>"

    PRINT "<HR>"

    LET version = "$Id: frdbhtml95.ace,v 4.14 2003/02/12 19:55:00 jleffler Exp $"
    LET version = version[6,45]
    PRINT "<CENTER><SMALL><I>Report produced by ISQL ACE and ", version CLIPPED,
            "</I></SMALL></CENTER>"

    PRINT "<H3 ALIGN=CENTER> End of Report </H3>"
    PRINT "</BODY>"
    PRINT "</HTML>"

END
Jonathan Leffler
@Jonathan- Yikes!.. Never thought of using Ace to produce HTML, good example! I thought there was a limit on character string space available for Ace, as I have encountered the "character string space exceeded..." error message when I included to many char's in my print statements.
Frank Computer
+1  A: 

Here's a moderately complex form - this from Chapter 11 of my book 'Using Informix-SQL' (or, strictly, an answer to the exercise posed in Chapter 11 of the book). (Yes, it uses a different login ID - one I'd forgotten about until I saw it again. It is ...o...l...d...!)

{
    @(#)$Id: sales.per,v 5.5 1991/03/22 21:44:46 john Exp $
    Answer to Chapter 11 Question 1
'\" @(#)%Q%
}

DATABASE Cars

SCREEN
{

        Stock List
        ==========

Registration   [f000   ]
Model Number   [f001] [f011]
Description    [f021                ]
               [f012                ]
               [f013                ]
Colour         [f002    ]

Notes
[f006                                              ]
[f008                                              ]
}

SCREEN
{

 [b1                                                  ]
 [b]                                                [b]
 [b] Sales entry form                               [b]
 [b]                                                [b]
 [b] Registration [f000   ]                         [b]
 [b] Model Number [p001] [f011]                     [b]
 [b] Description  [f021                ]            [b]
 [b]              [f012                ]            [b]
 [b]              [f013                ]            [b]
 [b] Customer     [c000]                            [b]
 [b] Name         [c001 ][c002    ][c003          ] [b]
 [b] Sold for     [p003        ]                    [b]
 [b] Date sold    [p004      ]                      [b]
 [b] Terms        [p005]                            [b]
 [b] Colour       [p102    ]                        [b]
 [b]                                                [b]
 [b2                                                  ]
}

SCREEN
{

Sensitive Sales data -- do not show to the customer

Registration    [f000   ]
Model Number    [f001] [f011]
Description     [f021                ]
                [f012                ]
                [f013                ]

Condition     [p]
Datebought    [p103      ]
Boughtfor     [p104        ]
Mileage       [p105       ]

Notes
[p106                                              ]
[p108                                              ]

        Profit [profit   ]
        Markup [markup]%
}

SCREEN
{

Sensitive Stock data -- do not show to the customer

Condition     [a]
Datebought    [f003      ]
Boughtfor     [f004        ]
Mileage       [f005       ]
}

SCREEN
{

           Customer details

Number  [c000]
Name    [c001 ][c002    ][c003          ]

Address  [c004                    ]
         [c005                    ]
         [c006                    ]
Post code[c007    ]

Phone number [c008            ]

Type of enquiry[c]

Spending Power (estimated) [c009       ]
Model Number    [c010]

Last contact date [c011            ]
}

SCREEN
{

         Guide prices

Model Number    [f001] [f011]
Description     [f021                ]
                [f012                ]
                [f013                ]

Year [g001] Low [g002   ] High [g003   ]

Average [gavg   ]
Minimum [gmin   ]
Maximum [gmax   ]
}

SCREEN
{

        Model List
        ==========

Model           [f001]
Maker           [f011]
                [f021                ]
Modelname       [f012                ]
Details         [f013                ]
Price           [f014      ]
Maxspeed        [f015       ]
Accel           [f016 ]
Tanksize        [f017 ]
Urban           [f018       ]
Mpgat56         [f019       ]
}

SCREEN
{

        Company Details
        ===============

Company Number  [f011]
Company Name    [f021                ]
Address         [f022                    ]
                [f023                    ]
                [f024                    ]
Postcode        [f025    ]
Phone           [f026            ]

Notes
[f028                                              ]
[f030                                              ]
}

TABLES
Stock
Models
Companies
Sales
Prices
Customers

ATTRIBUTES

f000 =*Stock.Registration
     = Sales.Registration, QUERYCLEAR, UPSHIFT, AUTONEXT, PICTURE = "AXXXXXA";
f001 =*Models.Model
     = Stock.Model, QUERYCLEAR, NOENTRY, NOUPDATE;
     = Prices.Model, QUERYCLEAR;
{ Read the commentary on the answer to find out why this join cannot be made }
{    = Customers.Lastmodel, QUERYCLEAR; }
f002 = Stock.Colour;
a    = Stock.Condition, AUTONEXT, UPSHIFT,
        INCLUDE  = ('X', 'V', 'G', 'A', 'P'),
        COMMENTS = "Xcellent, Very good, Good, Average, Poor";
f003 = Stock.Datebought;
f004 = Stock.Boughtfor;
f005 = Stock.Mileage;
f006 = Stock.Notes1;
f008 = Stock.Notes2;
c000 =*Customers.Number
     = Sales.Customer, QUERYCLEAR;
p003 = Sales.Soldfor;
p004 = Sales.Datesold,
        DEFAULT = TODAY, NOENTRY, NOUPDATE;
p005 = Sales.Terms, UPSHIFT, AUTONEXT,
    INCLUDE = ('CASH', 'ACCE', 'BARC', 'HIRE', 'CHEQ'),
    COMMENTS = "CASH, ACCEss, BARClaycard, HIRE-purchase, CHEQue";

{ These are implicitly no-entry fields }
p001 = Sales.Model;
p102 = Sales.Colour;
p    = Sales.Condition;
p103 = Sales.Datebought;
p104 = Sales.Boughtfor;
p105 = Sales.Mileage;
p106 = Sales.Notes1;
p108 = Sales.Notes2;

f011 = Models.Maker = Companies.Maker, QUERYCLEAR;
f012 = Models.Modelname;
f013 = Models.Details;
f014 = Models.Price;
f015 = Models.Maxspeed;
f016 = Models.Accel;
f017 = Models.Tanksize;
f018 = Models.Urban;
f019 = Models.Mpgat56;

f021 = Companies.Company;
f022 = Companies.Address1;
f023 = Companies.Address2;
f024 = Companies.Address3;
f025 = Companies.Postcode;
f026 = Companies.Phone;
f028 = Companies.Notes1;
f030 = Companies.Notes2;

c001 = Customers.Salut,
       COMMENTS = "Mr Mrs Miss Ms or blank",
       INCLUDE = ("Mr", "Mrs", "Miss", "Ms", NULL);
c002 = Customers.Firstname;
c003 = Customers.Surname, REQUIRED;
c004 = Customers.Address1, AUTONEXT, COMMENTS = "Enter address";
c005 = Customers.Address2, AUTONEXT, COMMENTS = "Enter address";
c006 = Customers.Address3, AUTONEXT, COMMENTS = "Enter address";
c007 = Customers.Postcode, UPSHIFT,  COMMENTS = "Enter post code",
       PICTURE = "AXXX #AA";
c008 = Customers.Phone, DOWNSHIFT,
       COMMENTS = "STD code, number, and extension";
c    = Customers.Enquiry, UPSHIFT, AUTONEXT, DEFAULT = 'S',
       COMMENTS = "Q enquiry, S sale, C contact",
       INCLUDE = ("Q", "C", "S");
c009 = Customers.Maxmoney, REVERSE,
       COMMENTS = "2000 to 100000, or blank",
       INCLUDE = (NULL, 2000 TO 100000);
{ Read the commentary to find out why
  Customers.Lastmodel is not joined to Models.Model }
c010 = Customers.Lastmodel;
c011 = Customers.Contactdate,
       DEFAULT = TODAY, FORMAT = "ddd, dd mmm yyyy", NOENTRY;

g001 = Prices.Year_made;
g002 = Prices.Lo_price, FORMAT = "###,###";
g003 = Prices.Hi_price, FORMAT = "###,###";

gmin = DISPLAYONLY TYPE DECIMAL, FORMAT = "###,###";
gmax = DISPLAYONLY TYPE DECIMAL, FORMAT = "###,###";
gavg = DISPLAYONLY TYPE DECIMAL, FORMAT = "###,###";

b1   = DISPLAYONLY TYPE CHAR, REVERSE;
b2   = DISPLAYONLY TYPE CHAR, REVERSE;
b    = DISPLAYONLY TYPE CHAR, REVERSE;

profit = DISPLAYONLY TYPE MONEY;
markup = DISPLAYONLY TYPE DECIMAL, FORMAT = "###.##";

END

INSTRUCTIONS

{ Master/detail relationships as before }
Companies MASTER OF Models
Models MASTER OF Prices
Models MASTER OF Stock

{ You may only change Sales and Customers }
BEFORE EDITADD EDITUPDATE OF Models Companies Prices Stock
    ABORT

{ You may not update Sales -- just add }
BEFORE EDITUPDATE OF Sales
    ABORT

{ You may only delete Stock records }
BEFORE REMOVE OF Sales Models Companies Customers Prices
    COMMENTS BELL REVERSE "You may not change this table"
    ABORT

{ Finish border of Sales screen }
AFTER DISPLAY OF SALES
    LET b1 = "            ABC Cars Ltd"

{ Show range of prices }
AFTER DISPLAY QUERY OF Prices
    LET gmin = MIN OF g002
    LET gmax = MAX OF g003
    LET gavg = (AVG OF g002 + AVG OF g003) / 2

{ Show the company what we made on the deal }
AFTER EDITADD OF Soldfor
    LET profit = p003 - f004
    LET markup = ((p003 -f004) / f004) * 100

{ Transfer data to Sales record }
AFTER EDITADD OF Sales.Registration
    LET p001 = f001
    LET p102 = f002
    LET p    = a
    LET p103 = f003
    LET p104 = f004
    LET p105 = f005
    LET p106 = f006
    LET p108 = f008

{ Do not let user edit transferred data }
BEFORE EDITADD OF Sales.Model
    NEXTFIELD = f000

BEFORE EDITADD OF Sales.Notes2
    NEXTFIELD = p005

END
Jonathan Leffler
@Jonathan- Cool!.. I noticed your book example doesn't use any AFTER ADD UPDATE control blocks. Would AFTER DISPLAY accomplish the same thing as AFTER ADD or UPDATE, since it basically used for changing DISPLAYONLY fields and cannot change table column values?.. Another question I have is: How come when say I go into update mode, some of my DISPLAYONLY fields get re-calculated, then decide to cancel the Update action, and the re-calculated DISPLAYONLY fileds dont revert back to the values when I first displayed the row to begin with, they stay with the same values when I invoked Update???
Frank Computer
Is the following perform instruction valid? 'IF NEXTFIELD = ABORT THEN BEGIN ... END' or 'IF ABORT THEN BEGIN ... END' I'm trying to control the displayonly fields when user cancels out any CRUD action.
Frank Computer