[EMAIL PROTECTED] wrote:
Ok, so instead of denormalising all of the above into one table (which is
possible, but not very practical), I can pass the results of each sql select as
a dictionary (which becomes a list of dictionaries). This list of dictionaries
is then the cursor which is passed to reportwriter.
A qualified 'yes'. The list of dicts is what the report writer will use as the
'cursor'. The reportwriter will iterate through the list, and based on the
definitions in the rfxml file, will print out various bands like
pageHeader/pageFooter, groupHeader/groupFooter, detail. Especially in the detail
band, there will be definitions that look like "self.Record['cname']".
self.Record is the current record being iterated over, and 'cname' is the field
name we want to print.
What I'm getting at is that each 'record' in your list of dict's should define
the same field names, even if the values of those fields don't really apply at
that 'level' - they should repeat so the report writer can deal with them.
For instance, take a standard customer/invoice/invoice line setup. You want the
customer info to print up top, along with invoice number and invoice date. You
want the invoice lines to print as the body. You want a separate page for each
invoice.
All that is defined in the rfxml file, using group expressions, group
headers/footers, along with the detail band and pageHeader/footer. Also, there
are report variables which I use to keep things like running totals but I won't
say more about report variables yet.
But in order for all this to work, the group expressions must be able to know
when the invoice number or customer changes so that the invoice can be totalled
and a new page started. This requires the 'denormalized' format shown below,
even though this is not how any sane person would actually store the info in the
backend database, and even though it is awfully redundant:
[{"custid": 23, "custname": "ABC Manufacturing",
"invnum": 123,
"item": "Sill Plate", "itemamt": 500, "qty": 10},
{"custid": 23, "custname": "ABC Manufacturing",
"invnum": 123,
"item": "Machine Screw", "itemamt": .04, "qty": 50000},
{"custid": 23, "custname": "ABC Manufacturing",
"invnum": 124,
"item": "Assembly B", "itemamt": 45.00, "qty": 20},
{"custid": 433, "custname": "Zwieble Industries",
"invnum": 928,
"item": "Hinge, Brass", "itemamt": 2.50, "qty": 50},
{"custid": 433, "custname": "Zwieble Industries",
"invnum": 928,
"item": "Hinge, Stainless", "itemamt": 3.10, "qty": 50},
{"custid": 433, "custname": "Zwieble Industries",
"invnum": 928,
"item": "Knob, Stainless", "itemamt": 1.75, "qty": 1000},
]
Obviously, you'd have additional fields too, such as customer address, etc. The
key is to give the report writer all the information it needs, in each an every
"record". So if you have a group on 'self.Record["custid"]', you need to make
sure the correct custid is in each and every record. Same for invnum, etc. And
because the page header will print on each new page, if you want the customer's
address to print in the page header you'll need to include those fields in every
record as well because you don't know ahead of time which record will be falling
on the new page.
This probably sounds very messy, and that we should just allow querying from
related cursors, but I've used this 'denormalized cursor' approach for years
using a tool that easily handles related cursors (Visual FoxPro). I've found it
to be simpler and much easier to maintain using the single denormalized cursor
approach.
As these reports are the key to the whole project, I'm going to start working on
them first.
Okay, but *please* understand that the report writer is in its infancy. We only
really started developing it this year. If you understand the implications of
that (you may have to struggle because of problems with the report writer, you
may have to update your reports over time as the reportwriter changes, etc.) and
you are willing to work with me to get the problems ironed out and to advance
the state of the report writer, then I'm stoked to be working with you!!
What I will do is:
1. create the database using embedded Firebird (this will be 2 main tables, with
about 20 tables for values to input into these 2 main tables (is there a term
for this?),
Do you mean the 2 main tables have a one-to-many (1:M) relationship with the 20
tables?
2. run AppWizardX (without any relationSpecs) and use the baseSQL override to
join FK's to the 2 main tables.
3. work out the sql/calculations necessary for the reports.
Cool, ask questions as you go.
I notice that the expanded format of the QuickReport uses the layout of the edit
page.
Yes, cute eh?
So obviously, once I create a page which looks like my report, I can use
that to print. Is this how I should proceed?
No, please don't. However, I'm going to be giving you a way to save the rfxml
that gets dynamically generated for that report. You'll be able to take that
rfxml and edit it to your needs, and save it as an actual file.
If so, how do I set the
datasource? What do I use for a data-aware label?
You'll be modifying the rfxml directly, so you'll see that you have all the
control you need to lay out your report. The other part of the puzzle you are
missing is an object that puts together your datasource and your rfxml, and
calls reportwriter and outputs the pdf. I've been busy this week but I hope to
have something pounded out real soon now, to demo the things I've talked about
in this message.
--
Paul McNett
http://paulmcnett.com
http://dabodev.com
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users