Subject |
Re: Report group headers |
From |
charlie <tm@tc.com> |
Date |
Wed, 03 Jan 2024 09:37:17 -0500 |
Newsgroups |
dbase.getting-started |
Hi Mervyn... Wow I would have never figured that out. Thanks so much!!!!!!!
Mervyn Bick Wrote:
> On 2023/12/31 23:16, Mervyn Bick wrote:
>
> > I can't run your report without the two tables (collection and category)
> > so it would help if you post them here. If you don't want to make the
> > tables generally available perhaps you would email them to me at
> >
> > bickmeo at gmail dot com
> >
> > I did, however, notice one potential problem. The rowset must be
> > ordered primarily by the field used in the group1 groupBy property. This
> > field is 'category' but the rowset is ordered by ordr,sku You should
> > change that to ... order by category,ordr,sku
>
> I assumed that the grouping was by category in alphabetical order. Now
> that I've seen the tables I realise you have added a field to the
> category table to present the categories in priority order. This means
> that the JOINed rowset is correctly ordered by ordr,sku. In as much as
> ordr and category are paired in records it doesn't really matter which
> of the two is used in the group's groupBy property.
>
> The "missing rowset" message came about because you used the
> reportgroup's footerband onRender event, which is only triggered once at
> the end of the report, instead of the group1 footerband onRender event
> to trigger the footerband_onRender event handler.
>
> In the case of the group1 footerband, this.parent.parent is
> streamsource1 which does have the rowset as a property. In the case of
> the reportgroup footerband, this.parent.parent is the form which does
> not have the rowset as a property resulting in oStream.rowset causing an
> error.
>
> Attached is report_tree1.pdf which I use to help trace the parentage of
> objects when I need to move data from one object to another.
>
> You used the <H3> and </H3> HTML tags to format the text for the
> category name. I couldn't get Ken's code to add (Continued..) to the
> category name when the group1 headerband was repeated on a new page. I
> removed the HTML tags and used the text object's fontsize and fontbold
> properties to achieve the same "look" and now the (Continued..) works as
> expected. I've added code to display at the bottom of the page if a
> group carries over to a new page.
>
> The method of looping through the rowset to count the number of records
> in a group had a problem where the group headerband was repeated at the
> top of a new page by giving a false value for the next group. Instead
> of trying to fix the code I abandoned it and added a parameter driven
> query to count the records. Apart from being a simpler method, it also
> allows the number of items in a category to be easily displayed in the
> group headerband. You can, of course, remove the additional text from
> the headerband if you don't want it there.
>
> I've commented out the code in the FOOTERBAND_onRender event handler to
> start a group on a new page if there isn't enough space left on a page
> for the entire group. The code increases the report length from 5 to 7
> pages and leaves a LOT of white space on some pages. The code is,
> however, clearly marked so you can uncomment it if you wish.
>
> Mervyn.
> ** END HEADER -- do not remove this line
> //
> // Generated on 2024-01-03
> //
> local r
> r = new COLLECTIONREPORT()
> r.render()
>
> class COLLECTIONREPORT of REPORT
> set procedure to :ReportControls:REPORT.Co additive
> with (this)
> title = "Collection"
> metric = 3 // Inches
> autoSort = false
> endwith
>
> this.COINDATA1 = new DATABASE(this)
> with (this.COINDATA1)
> databaseName = "COINDATA"
> active= true
> endwith
>
> this.COUNT_CAT1 = new QUERY(this)
> with (this.COUNT_CAT1)
> left = 4.0
> database = form.coindata1
> sql = "select count(*) from collection where category = :category"
> params["category"] = ""
> active = true
> endwith
>
> this.CATEGORY1 = new QUERY(this)
> with (this.CATEGORY1)
> left = 4.0
> database = form.coindata1
> sql = "select * from collection inner join category on collection.category = category.cat order by ordr,sku"
> requestLive = false
> active = true
> endwith
>
> this.STREAMSOURCE1 = new STREAMSOURCE(this)
> this.STREAMSOURCE1.GROUP1 = new GROUP(this.STREAMSOURCE1)
> with (this.STREAMSOURCE1.GROUP1)
> groupBy = "ORDR"
> headerEveryFrame = true
> endwith
>
> with (this.STREAMSOURCE1.GROUP1.footerBand)
> onRender = class::FOOTERBAND_ONRENDER
> endwith
>
> with (this.STREAMSOURCE1.GROUP1.headerBand)
> preRender = class::HEADERBAND_PRERENDER
> onRender = class::HEADERBAND_ONRENDER
> height = 0.35
> endwith
>
> this.STREAMSOURCE1.GROUP1.headerBand.LINE1 = new LINE(this.STREAMSOURCE1.GROUP1.headerBand)
> with (this.STREAMSOURCE1.GROUP1.headerBand.LINE1)
> canRender = {||this.parent.context == 0}
> left = 0.0
> right = 6.5
> top = 0.0729
> bottom = 0.0729
> width = 1
> endwith
>
> this.STREAMSOURCE1.GROUP1.headerBand.TEXT1 = new TEXT(this.STREAMSOURCE1.GROUP1.headerBand)
> with (this.STREAMSOURCE1.GROUP1.headerBand.TEXT1)
> height = 0.2083
> left = 0.0
> top = 0.1354
> width = 0.8438
> prefixEnable = false
> colorNormal = "b+"
> text = "<H3>Category :</H3>"
> endwith
>
> this.STREAMSOURCE1.GROUP1.headerBand.TEXT2 = new TEXT(this.STREAMSOURCE1.GROUP1.headerBand)
> with (this.STREAMSOURCE1.GROUP1.headerBand.TEXT2)
> height = 0.2083
> left = 0.8958
> top = 0.1354
> width = 2.7813
> prefixEnable = false
> colorNormal = "b+"
> fontSize = 11.0
> fontBold = true
> text = {||this.parent.parent.parent.rowset.fields["CATEGORY"].value}
> endwith
>
> this.STREAMSOURCE1.GROUP1.headerBand.TEXT3 = new TEXT(this.STREAMSOURCE1.GROUP1.headerBand)
> with (this.STREAMSOURCE1.GROUP1.headerBand.TEXT3)
> canRender = class::TEXT3_CANRENDER
> height = 0.2083
> left = 3.8229
> top = 0.1354
> width = 0.5
> prefixEnable = false
> colorNormal = "b+"
> fontSize = 11.0
> text = "Items :"
> endwith
>
> this.STREAMSOURCE1.GROUP1.headerBand.TEXT4 = new TEXT(this.STREAMSOURCE1.GROUP1.headerBand)
> with (this.STREAMSOURCE1.GROUP1.headerBand.TEXT4)
> canRender = class::TEXT4_CANRENDER
> height = 0.2083
> left = 4.3438
> top = 0.1354
> width = 0.75
> prefixEnable = false
> colorNormal = "b+"
> fontSize = 11.0
> text = "Text4"
> endwith
>
> with (this.STREAMSOURCE1.detailBand)
> height = 0.1729
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTID1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTID1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 0.0
> top = 0.0
> width = 0.6146
> prefixEnable = false
> suppressIfBlank = true
> fontSize = 9.0
> text = "<H3>Date/Id</H3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTID1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTID1)
> height = 0.0
> left = 0.0
> top = 0.22
> width = 0.85
> variableHeight = true
> prefixEnable = false
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["ID"].value}
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTGRADE1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTGRADE1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 0.91
> top = 0.0
> width = 0.6146
> prefixEnable = false
> suppressIfBlank = true
> fontSize = 9.0
> text = "<H3>Grade</H3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTGRADE1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTGRADE1)
> height = 0.0
> left = 0.91
> top = 0.22
> width = 0.6146
> variableHeight = true
> prefixEnable = false
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["GRADE"].value}
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTBDATE1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTBDATE1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 1.73
> top = 0.0
> width = 0.9375
> prefixEnable = false
> suppressIfBlank = true
> fontSize = 9.0
> text = "<H3>Bdate</H3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTBDATE1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTBDATE1)
> height = 0.0
> left = 1.73
> top = 0.22
> width = 0.9375
> variableHeight = true
> prefixEnable = false
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["BDATE"].value}
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTQTY1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTQTY1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 2.8
> top = 0.0
> width = 0.4375
> prefixEnable = false
> alignHorizontal = 1 // Center
> suppressIfBlank = true
> fontSize = 9.0
> text = "<H3>Qty</H3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTQTY1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTQTY1)
> height = 0.0
> left = 2.8
> top = 0.22
> width = 0.4896
> variableHeight = true
> prefixEnable = false
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["QTY"].value}
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTESTV1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTESTV1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 3.43
> top = 0.0
> width = 0.625
> prefixEnable = false
> alignHorizontal = 2 // Right
> suppressIfBlank = true
> fontSize = 9.0
> text = "<h3>Est Val</h3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTESTV1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTESTV1)
> height = 0.0
> left = 3.43
> top = 0.22
> width = 0.6875
> variableHeight = true
> prefixEnable = false
> alignHorizontal = 2 // Right
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["ESTV"].value}
> endwith
>
> this.STREAMSOURCE1.detailBand.TITLETEXTDETAILS1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TITLETEXTDETAILS1)
> canRender = {||this.parent.firstOnFrame}
> height = 0.22
> left = 4.2
> top = 0.0
> width = 1.0
> prefixEnable = false
> suppressIfBlank = true
> fontSize = 9.0
> text = "<H3>Notes</H3>"
> endwith
>
> this.STREAMSOURCE1.detailBand.TEXTDETAILS1 = new TEXT(this.STREAMSOURCE1.detailBand)
> with (this.STREAMSOURCE1.detailBand.TEXTDETAILS1)
> height = 0.0
> left = 4.2
> top = 0.22
> width = 3.25
> variableHeight = true
> prefixEnable = false
> fontSize = 9.0
> text = {||this.form.CATEGORY1.rowset.fields["DETAILS"].value}
> endwith
>
> with (this.printer)
> duplex = 1 // None
> orientation = 1 // Portrait
> paperSource = 15
> paperSize = 1
> resolution = 0 // Default
> color = 2 // Color
> trueTypeFonts = 3 // Substitute
> endwith
>
> this.PAGETEMPLATE1 = new PAGETEMPLATE(this)
> with (this.PAGETEMPLATE1)
> height = 11.0
> width = 8.5
> marginTop = 0.1
> marginLeft = 0.0
> marginBottom = 0.1
> marginRight = 2.7875
> gridLineWidth = 0
> endwith
>
> this.PAGETEMPLATE1.STREAMFRAME1 = new STREAMFRAME(this.PAGETEMPLATE1)
> with (this.PAGETEMPLATE1.STREAMFRAME1)
> height = 9.0
> left = 0.3958
> top = 0.8958
> width = 7.5
> form.STREAMFRAME1 = form.pagetemplate1.streamframe1
> endwith
>
> this.PAGETEMPLATE1.TEXT1 = new TEXT(this.PAGETEMPLATE1)
> with (this.PAGETEMPLATE1.TEXT1)
> height = 0.3646
> left = 0.6146
> top = 0.1354
> width = 2.9896
> prefixEnable = false
> text = "<h1>My Collection</h1>"
> form.TEXT1 = form.pagetemplate1.text1
> endwith
>
> this.PAGETEMPLATE1.TEXT2 = new TEXT(this.PAGETEMPLATE1)
> with (this.PAGETEMPLATE1.TEXT2)
> height = 0.1563
> left = 0.61
> top = 0.57
> width = 2.1458
> prefixEnable = false
> text = {||Date()}
> form.TEXT2 = form.pagetemplate1.text2
> endwith
>
> this.PAGETEMPLATE1.PAGENUMBER1 = new PAGENUMBER(this.PAGETEMPLATE1)
> with (this.PAGETEMPLATE1.PAGENUMBER1)
> height = 0.3958
> left = 4.0624
> top = 10.198
> width = 0.3854
> alignVertical = 0 // Top
> alignHorizontal = 1 // Center
> fontSize = 10.0
> form.PAGENUMBER1 = form.pagetemplate1.pagenumber1
> endwith
>
> this.PAGETEMPLATE1.TEXT3 = new TEXT(this.PAGETEMPLATE1)
> with (this.PAGETEMPLATE1.TEXT3)
> height = 0.2083
> left = 0.6979
> top = 10.0417
> width = 3.7396
> prefixEnable = false
> colorNormal = "b+"
> text = "Text3"
> form.TEXT3 = form.pagetemplate1.text3
> endwith
>
> with (this.reportGroup.footerBand)
> height = 0.0
> endwith
>
> with (this.reportGroup.headerBand)
> expandable = true
> height = 0.0
> beginNewFrame = true
> endwith
>
> this.firstPageTemplate = this.form.pagetemplate1
> this.form.pagetemplate1.nextPageTemplate = this.form.pagetemplate1
> this.form.pagetemplate1.streamframe1.streamSource = this.form.streamsource1
> this.form.streamsource1.rowset = this.form.category1.rowset
>
> function FOOTERBAND_onRender()
> local oStream, nCount, nSpaceRemaining, nSpaceNeeded,cNextCategory
> oStream = this.parent.parent
> oStream.rowset.next() //Next record so we can get category for next group
> cNextCategory = oStream.rowset.fields["category"].value
> nCount = 0
> if not oStream.rowset.endofset
> this.parent.parent.parent.count_cat1.params['category'] = oStream.rowset.fields["category"].value
> this.parent.parent.parent.count_cat1.requery()
> nCount = this.parent.parent.parent.count_cat1.rowset.fields[1].value
> endif
> oStream.rowset.next(-1) //Back to last record of previous group so that report can continue where it left off
> nSpaceRemaining = this.streamframe.height - this.renderOffset
> nSpaceNeeded = 0.39+(nCount*0.21) //space for header, footer (which is 0) and rows
>
> //Uncomment the following section to force groups that are too long to fit in the
> //space available to start on a new page
> *--------------------
> // if nSpaceRemaining < nSpaceNeeded
> // this.parent.headerband.beginNewframe := true
> // else
> // this.parent.headerband.beginNewframe := false
> // endif
> *--------------------
> return
>
>
> function HEADERBAND_onRender()
> local nSpaceRemaining,nSpaceNeeded
> //Copy & paste direct from Ken's dBASE Reports book.
> *--------
> f = this.parent.parent.rowset.fields
> this.BreakField = f["category"].value.rightTrim()
> this.text2.text = {||this.parent.parent.parent.rowset.fields["CATEGORY"].value }
> *-------
> //Display notice at bottom of page if group continues on next page
> nSpaceRemaining = this.streamframe.height - this.renderOffset
> nSpaceNeeded = this.count*0.21 //header has already been rendered so space for footer (which is 0) and rows
> if nSpaceNeeded > nSpaceRemaining
> this.parent.parent.parent.pagetemplate1.text3.text = ;
> this.BreakField + ' continued on next page'
> else
> this.parent.parent.parent.pagetemplate1.text3.text = ''
> endif
> return
>
> function HEADERBAND_preRender()
> local oStream
> //Count records in group for display on headerband
> oStream = this.parent.parent
> this.parent.parent.parent.count_cat1.params['category'] = oStream.rowset.fields["category"].value
> this.parent.parent.parent.count_cat1.requery()
> this.count = this.parent.parent.parent.count_cat1.rowset.fields[1].value
> this.text4.text = ltrim(this.count+'') //Convert to text then left trim for better alignment
>
> //Copy & paste direct from Ken's dBASE Reports book to add (Continued..) to categrory name
> // check to see if custom property exists, if not create it:
> if type( "this.BreakField" ) == "U"
> this.BreakField = "XXX" // value not in table
> endif
> // this = headerBand
> // parent = group1
> // parent = streamSource1
> f = this.parent.parent.rowset.fields
> this.Text2.text := f["category"].value.rightTrim()
> if this.BreakField == f["category"].value.rightTrim()
> // add extra text: the word<
> // "(Continued ...)" in italics
> this.Text2.text += " <i>(Continued ...)</i>"
> this.count = 0 //Set to 0 so that if group is continued on next page
> //the onRender event handler doesn't set set the Continued
> //notice at the bottom of the new page.
> endif
> return
>
> function TEXT3_canRender()
> local lRet
> if 'Continued'$this.parent.text2.text
> lRet = false
> else
> lRet = true
> endif
> return lRet
>
>
> function TEXT4_canRender()
> local lRet
> if 'Continued'$this.parent.text2.text
> lRet = false
> else
> lRet = true
> endif
> return lRet
>
> endclass
>
|
|