Creating hierarchical groups dinamically...
Hi,
My client has a tree of product groups and products inside the tree nodes.
He wants to have a report where groups would represent tree enlosure.
For example:
We have a product groups tree:
ALL
|
|------Alcohol
| |
| |-------Vodka
| |
| |-------Wine
|
|------Tobacco
| |
| |------Cigarettes
| |
| |------Cigar
|
|------Coffee
Each of the groups contains several products.
I need to create dynamically groups in report that would correspond to this
tree.
They need to conatin name of the group in the header and totals in the
footer.
It would look like this:
ALL
Alochol
--products
Vodka
--products
[Total by Vodka]
Wine
--products
[Total by Wine]
[Total by Alcohol]
Tobacco
--products
Cigarettes
--products
[Total by Cigarettes]
Cigar
--products
[Total by Cigar]
[Total by Tobacco]
Coffee
--products
[Total by Coffee]
[Total by ALL]
How can I create such a report?
Thanks,
MB.
My client has a tree of product groups and products inside the tree nodes.
He wants to have a report where groups would represent tree enlosure.
For example:
We have a product groups tree:
ALL
|
|------Alcohol
| |
| |-------Vodka
| |
| |-------Wine
|
|------Tobacco
| |
| |------Cigarettes
| |
| |------Cigar
|
|------Coffee
Each of the groups contains several products.
I need to create dynamically groups in report that would correspond to this
tree.
They need to conatin name of the group in the header and totals in the
footer.
It would look like this:
ALL
Alochol
--products
Vodka
--products
[Total by Vodka]
Wine
--products
[Total by Wine]
[Total by Alcohol]
Tobacco
--products
Cigarettes
--products
[Total by Cigarettes]
Cigar
--products
[Total by Cigar]
[Total by Tobacco]
Coffee
--products
[Total by Coffee]
[Total by ALL]
How can I create such a report?
Thanks,
MB.
This discussion has been closed.
Comments
create logical groups in the report. In this example it shows how to create
a group in code:
http://www.digital-metaphors.com/tips/DynamicReportCreation.zip
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
I need to create groups bands DYNAMICALLY AT RUN TIME.
Also the amount of groups enlosements into each other must be UNLIMITED.
The (report) groups bands must have the same hierarhy as the tree. (It is
being kept in the database in the the id - parent_id relation).
How do I generate groups in RAP? (Also in what event?) But I need to do it
after pipelines generation...?
How do I organize the (group) data if I need to create several groups
enclosed into each other? (Not just one group after another). Would that be
like this: 1,1,1,2,2,2,3,3,4,3,3,3,1,1 ?
How do I "order the data first by group and then by product"? If I don't
even have such convinient group field at all? (Just group tree table, with
"id" - "parent_id" relation)?
Is it still too confusing to understand?
Thanks,
MB.
table to order the data. Create a query like this and change the ORDER BY
clause at runtime to change the ordering of the data. Also, set the group
object's break name propery to match the ordering that you specify in the
query.
SELECT *
FROM ProductTreeTable
ORDER BY GroupCategory, ProductID
The link to a tip provided earlier is to a project which shows how to create
TppGroup objects at runtime. Get it working in Delphi code first, then port
it to RAP. When you move the code to RAP, you'll want to use the earliest
possible event, the global OnCreate event to create the group objects and
related report components in the layout for those group bands.
On a related note if your data is already in tree format, there is a
treeview component listed on our website to print the tree data:
http://www.choosepill.com/components/cpcrbtree.htm
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
Thanks for the help, I have just 2 questions left:
1.) How can I assign record to the specific group manually at runtime? Let's
say I have a set of records. I need to put them into one of the, let's say,
4 groups based on some field value. Do I override some kind of group
traversal method or something?
2.) How can I hide some of the groups bands? Let's say I have 2 groups where
1st is the master and 2nd is detail. When there is only one 2nd group I want
it to be hidden, so that only 1st groups would be shown. How can I do it?
Thanks,
MB.
it, then it checks the Group.Breakname value on the pipeline to see if it
should cause a group break. You can also control the group break by basing
the group on a static label and then coding the Group.OnGetBreakValue event
so that you can cause a break whenever you want to.
Create two group objects, one for the master and one for the detail instead
of using one group object and trying to make the first group printed the
master and the second the detail.
In order to not print the group bands, you have to traverse the data at
least once in order to know ahead of time that a particular group shouldn't
print its group bands. An alternative is to let the report generate this
one record group detail, but then free the draw commands for it. Are you
using new page groups? I'd say if you were using new page groups, then free
the draw commands for a one detail group. Basically, you have to use each
control's OnDrawCommandCreate event and store that in a new class of object
which has the group break value and the draw command. Then store a list of
groups that should have their group draw commands freed. Use the
Report.OnEndPage event to free the draw commands. Group.KeepTogether should
be false to allow you to free the draw commands. (Just thought of this)Then
if you aren't using new page groups, you could shift all the other draw
commands on the page up after you free the group draw commands. So, store
another value in the object with the draw command and group value and group
height in microns. When you change the drawcommand's Top property, use the
micron unit of measure. There are two conversion routines in ppUtils.pas
ppFromMMThousandths and ppToMMthousandths that you can use to convert report
units.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
But since I don't quite understand everything I would like to ask you to
clarify several things.
1.) By the following "then it checks the Group.Breakname value on the
pipeline to see if it should cause a group break. You can also control the
group break by basing the group on a static label" you mean that I need to
assign static label name to Group.Breakname property? So that it would not
depend from the pipeline?
2.) "coding the Group.OnGetBreakValue event so that you can cause a break
whenever you want to". How exactly do I need to use this event ? If I assign
different (or new) value to the BreakValue variable then the last one then
the groups breaks? Or the conditions for breaking are different?
3.) By the "An alternative is to let the report generate ..." words you mean
this is the other (2nd) way? Then could you please explain the first method
for hiding bands in more details? I'm afraid the second one is a bit hard
for me. I particualry don't understand how to store information about the
bands I need and don't need to hide, how to use 1st and 2nd traversal
(discern between them), and hide the bands (I guess it can be done easier
than in 2nd method because of your words: "particular group shouldn't print
its group bands".)
4.) If I'm wrong and it is only one method, then please explain the
following: how do I free the DrawCommand? What does that mean: "and store
that in a new class of object which has the group break value and the draw
command." ? What is "that"? What is "new class of object"?
How do I store "a list of groups that should have their group draw commands
freed"?
Thanks,
MB.
group break when you want, simply by changing the string value.
2. The TppGroup.OnGetBreakValue is the same thing as coding the group break
with a label. All the group needs is a string to compare to the last group
break value and it will break when the string is different than the last
record's group break value.
3. My suggestion is complicated (I haven't coded it, but it should work
based on similar techniques I've researched in the past), so lets put that
on the back burner for now as it requires more code than may be necessary.
Try to preprocess the data so that you only get the records in the dataset
that you want to print. That way you don't have to try to hide group bands.
Trying to hide output created by RB is generally more difficult than trying
to keep it from printing in the first place, though it is possible.
[quote]What is "new class of object"?[/quote] I simply meant a class, as in
a TObject descendent, and phrased it as if you would say 'category of
automobile.' Sorry for the confusion. The class I was thinking of would have
an object reference property to the draw command object created by RB and a
string property for the group break value to determine which group it
belonged to. You can free a draw command by falling aDrawCommand.Free.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com