Masterdata over two *different* pages

Hi all, former Rave Reports user now having to learn a new system. So far it's been not too painful, but I seem to have a problem I haven't seen addressed in the manual or in this forum.

I am printing a pretty specific form for the government. For argument's sake, let's call it an invoice. There can be multiple invoices associated with what I'll call a "Transaction".

As it's currently set, My Report has a Page 1 with a GroupHeader, Masterdata, and PageFooter.

I have 3 datasets: InvoiceHeader, InvoiceDetail, and InvoiceOther.

I also have a second page to this invoice.

The problem is that the 2nd page background and formatting is *different* than the 1st page.

First Page is:
GroupHeader (contains the information contained in InvoiceHeader - GroupHeader repeats when I hit a new invoice)
As much Invoice detail as will fit in the space provided (uses InvoiceDetail)
PageFooter (some summary data, mostly uses InvoiceOther, only prints on 1st page)

Second Page is:
Greatly reduced Header (only a few data fields, takes much less real estate)
Tons of Invoice Detail (the data should continue from where the first page left off)
No Footer at all.

When I try to print this, what happens is that the 1st page looks perfect, but if the detail is larger than the space provided, a second Page 1 prints, with the extra detail at the top (where the GroupHeader was on the 1st page). Then, assuming all the rest of my detail fit on that page, it prints Page 2 with all the masterdata again.

What I *want* to happen is for Page 1 to print as it is, but for the *rest* of the MasterData, use Page 2 and the formatting/background defined therein until I hit the end of the MasterData.

Is there any way to do this?

Thanks, I really appreciate your help in teaching me how to use this.

Comments

  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    I can't work out what you are trying to explain
    are you talking about design pages or output pages?
    gov forms are usually 1 set design page of many fields on a pre printed forms with a number of copies required.
    or are you trying to control a multi design page report?
    like invoice,packing slip,billing copy.
    multi designpage reports require a datset be connected to the tfrxreportcomponent itself and
    controls the number of times the report is run (it cannot be the same dataset as any masterband)











  • edited January 2011
    Sorry Gord, I read and re-read my message trying to make sure it made sense. Apparently it didn't.

    The issue is this: I am *replicating* the form for a canada customs invoice. This form's first page is different from every other page that follows.

    All the invoice header/footer information goes on the first page, as well as whatever detail will fit between them.

    The second and subsequent pages are called "continuation sheets", and consist of a very small header (an abbreviated version of the first page) and a huge amount of detail (no footer).

    I'm using background images for the form(s), and have positioned my fields/bands on each page appropriately.

    However, it appears that page one wants to iterate through *all* the masterdata before it goes to page 2, at which point all the masterdata prints again on as many page 2s as are required. I want to iterate through whatever masterdata will fit on page 1, and then have it print the rest on page 2.

    Does that make more sense? Thanks very much for your reply.

    Edit: I should point out that page 1 and page 2 have *different* backgrounds.
  • edited January 2011
    Some creative work with child bands, printing the group header info in 2 different ones, enabling and disabling them as appropriate?
    I am not sure how the different backgrounds could be achieved. Loading background image at run-time?

    Can your software determine how much detail can be printed on page 1? If yes and assuming it is 15 items, a SELECT FIRST 15 * FROM TABLE (Firebird syntax) with one query, printing page 1 (report 1), then a SELECT SKIP 15 * FROM TABLE with another query for page 2+ (report 2).
    Then use the composite report feature to merge report 1 and 2 into a single report.
  • edited 11:22AM
    technisoft wrote: »
    Some creative work with child bands, printing the group header info in 2 different ones, enabling and disabling them as appropriate?
    I am not sure how the different backgrounds could be achieved. Loading background image at run-time?

    Can your software determine how much detail can be printed on page 1? If yes and assuming it is 15 items, a SELECT FIRST 15 * FROM TABLE (Firebird syntax) with one query, printing page 1 (report 1), then a SELECT SKIP 15 * FROM TABLE with another query for page 2+ (report 2).
    Then use the composite report feature to merge report 1 and 2 into a single report.

    Ah, I see. That's really unfortunate - it was great feature of Rave to be able to print a different first page from subsequent pages, and carry over the existing dataset cursor to the second page. There's really no other way of doing it?

    Do you think I could load the new background from a script in a OnBeforePrint script, say?

    This is a real problem. Need to think more on this. Thanks very much for your help.
  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    "The issue is this: I am *replicating* the form for a canada customs invoice. This form's first page is different from every other page that follows."
    what is the form number and i'll dl and take a look
    better yet zip and send the images you are using for positioning.
    Regards
    Gord K
    gord@fast-report.com


  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    it is not too dificult just re-think your situation.
    do not use groupheaders footers. and do not connect the databand on design page 1 to a dataset.
    control the dataset from code and set the rowcount property of the databand.
    use tables or queries in a master data relationship.
    the master dataset will be the dataset for the tfrxreport component. it will actually control the
    number of times the report is run as well as providing masterdata for the
    areas above and below the record detail area on design page 1, even though this is detail data
    use a master databand and set its rowcount property to the num of recs it can contain.
    code page
    var
    ds: TfrxDataSet;

    begin // at bottom of code page assuming record area can handle 12 recs
    ds := Report.GetDataset('frxDBDataSet2'); //the user name of the detaildataset
    // now set props for masterdata on design pages 1 and 2
    begin
    if ds.recordcount >12 then
    begin
    page2 .visible := true; //set designpage 2 visible
    masterdata1.rowcount := 12;
    masterdata1.dataset :='';
    masterdata2.dataset := 'frxDBDataSet2';
    end
    else
    begin
    page2 .visible := false// not enough records so dont need
    masterdata1.dataset := 'frxDBDataSet2';
    masterdata2.dataset :='';
    masterdata1.rowcount := 0;
    end;
    ds.first;// make sure on first record
    end;

    end.

    write code for the oap event of masterdata1
    if masterdata1.rowcount > 0 then ds.next;

    dont confuse the name of bands with data relationships bands are really just place holders on a design page

  • edited 11:22AM
    Thanks very much. I didn't understand a lot of that on first read-through, but I'll give it a go. Is this done using the script capability of fast-reports, or done using the Events of the Report component itself. FWIW, I'm coding using C++ Builder rather than Delphi, but ought to be able to translate.
    Is there a feature-request section on the website? I'd be a big fan of building "second page different from the first" into the engine itself.

    Thanks again, I'll let you know how it goes.
    Cheers,
    Ian

    gordk wrote: »
    it is not too dificult just re-think your situation.
    do not use groupheaders footers. and do not connect the databand on design page 1 to a dataset.
    control the dataset from code and set the rowcount property of the databand.
    use tables or queries in a master data relationship.
    the master dataset will be the dataset for the tfrxreport component. it will actually control the
    number of times the report is run as well as providing masterdata for the
    areas above and below the record detail area on design page 1, even though this is detail data
    use a master databand and set its rowcount property to the num of recs it can contain.
    code page
    var
    ds: TfrxDataSet;

    begin // at bottom of code page assuming record area can handle 12 recs
    ds := Report.GetDataset('frxDBDataSet2'); //the user name of the detaildataset
    // now set props for masterdata on design pages 1 and 2
    begin
    if ds.recordcount >12 then
    begin
    page2 .visible := true; //set designpage 2 visible
    masterdata1.rowcount := 12;
    masterdata1.dataset :='';
    masterdata2.dataset := 'frxDBDataSet2';
    end
    else
    begin
    page2 .visible := false// not enough records so dont need
    masterdata1.dataset := 'frxDBDataSet2';
    masterdata2.dataset :='';
    masterdata1.rowcount := 0;
    end;
    ds.first;// make sure on first record
    end;

    end.

    write code for the oap event of masterdata1
    if masterdata1.rowcount > 0 then ds.next;

    dont confuse the name of bands with data relationships bands are really just place holders on a design page
  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    the sample code i gave you and events mentioned are all in the report and script .
    design page 1
    probably
    page header for fixed position memos large height
    masterdataband1 set for fixed num of rows
    page footer for fixed position memos below area used by x num of masterdataband records

    design page 2
    probably known as the overrun page
    page header for fixed position memos smaller height
    masterdataband we connect to data set and let it control num of pages produced due to num recs
    page footer for fixed position memos below area used by masterdataband records.

    what most miss is that masterdataband, detaildataband do not have a masterdata relation to data only to each other as to which band comes first in processing, the data source properties of those bands then supply info as to which datasets are involved and their datarelationship.
    the best way to think of databand names in fr is datalevel1(masterdataband),
    datalevel2(detaildataband1) and so on

    what i suggest is to use a query to supply masterdata for the fixed memos,
    this will be the tfrxreport components dataset also (controls num times report is run)
    and is also the master for the query that supplies the detail records.

    BTW there is a demo in the binaries news group on multi design page reports
    and you never did tell me what form you were using.



  • edited 11:22AM
    gordk wrote: »
    the sample code i gave you and events mentioned are all in the report and script .
    design page 1
    probably
    page header for fixed position memos large height
    masterdataband1 set for fixed num of rows
    page footer for fixed position memos below area used by x num of masterdataband records

    design page 2
    probably known as the overrun page
    page header for fixed position memos smaller height
    masterdataband we connect to data set and let it control num of pages produced due to num recs
    page footer for fixed position memos below area used by masterdataband records.

    what most miss is that masterdataband, detaildataband do not have a masterdata relation to data only to each other as to which band comes first in processing, the data source properties of those bands then supply info as to which datasets are involved and their datarelationship.
    the best way to think of databand names in fr is datalevel1(masterdataband),
    datalevel2(detaildataband1) and so on

    what i suggest is to use a query to supply masterdata for the fixed memos,
    this will be the tfrxreport components dataset also (controls num times report is run)
    and is also the master for the query that supplies the detail records.

    BTW there is a demo in the binaries news group on multi design page reports
    and you never did tell me what form you were using.

    Sorry about that.
    The first page looks like this: http://www.noglobalborders.com/cusdocs/customs_invoice.pdf
    The second page looks like this: http://www.noglobalborders.com/cusdocs/cus...invoice_pg2.pdf

    I'm really sorry for being so obtuse, but I'm still not really certain I understand your instructions. I'll look for the demo in the binaries.

    Your description of Page 1 is how I have it set out now, with the page footer sized such that 4 records of the dataset are printed on Page 1.

    I use an invoice_header query for the data in the page_header, which is (as you suggest), also the master for the invoice_detail query.
    I use a third query (invoice_adjustments) for the data in the page_footer, which also uses the invoice_header query as the master.
    All of the queries are MySQL components that are on the same window that the frxReport is on. I am not using the data page of the fast-report.

    While I understand your script, I'm not sure what event I should attach it to (it has no declaration in your example).

    Clearly I am missing some fundamental understanding of how fast-report works. Perhaps the shift from the RAVE paradigm is beyond me.

    I do very much appreciate your patience.
  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    the main piece of the code for the dataset is placed in the empty
    begin

    end.
    block of the code page as was stated.
    it is the first script to be processed.
  • edited 11:22AM
    I tried to use some tricks.

    Depending on page number within a group (select ... from customers group by state) I choose which of two Childs should be visible. It work correctly, but as report is double pass I had to do something about the last State (TX), which tried to appear on THE FIRST page (with companies of AL). This script is not perfect, but it shows the location of the problem.


    The code at PageHeader1OnBeforePrint does its duty to change pagefooter on the Page1
    but it causes a critical error to FR engine. Be carefull as IT DESTROYS this report [img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> The problem is to avoid bad pointer operations, which is black magic for me[/img][img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> I do not use Delphi. My area is pure script of FR and SQL database - that's why I couldn't solve pointer operation error. Below there's PDF file to show what I got, and fr3 to how I did it. Mick PS. I'll be gratefull to know how to manage those Page1.Objects[/img]
  • edited 11:22AM
    Okay, I've spent a lot of time reading and re-reading this, reading the manual, and experimenting, and now I'm just getting errors. It won't let me set the DataSet to "", nor does it seem willing to let me set it to NULL, so I'm in a bit of a bind.

    Besides which, If I understand correctly, the main procedure checks to see if my detail set contains more than 4 records. If it does, then I'm going to be using page 2, so I should make it visible. I set the maximum number of rows to be printed on Page 1 to 4 (which is how many fit in there), but I set the dataset for the Page 1 databand to nothing? How does that work? I still need page 1 to print with 4 records, before continuing on to print the rest of them on page 2.

    I'm not even trying to create a true master/child relationship in the databases. I have two queries for the header and footer (each which return only 1 record), and a third for the data (which can contain many, all which relate to the one header record), and still can't make it work.

    Man, I've been programming successfully for 26 years in 5 different languages, so I don't think I'm stupid, but this really seems kluge-y.

    What am I missing, please?

    Here's what my code looks like:

    void MasterData1OnAfterPrint(TfrxComponent Sender)
    {
    TfrxDataSet ds;
    ds = Report.GetDataSet("InvoiceDetail");

    if (MasterData1.RowCount > 0)
    ds.Next();
    }


    {
    TfrxDataSet ds;

    ds = Report.GetDataSet("InvoiceDetail");

    if (ds.RecordCount > 4)
    {
    Page2.Visible = true;
    MasterData1.RowCount = 4;
    MasterData1.DataSet = NULL;
    MasterData2.DataSet = ds;
    }
    else
    {
    Page2.Visible = false;
    MasterData1.RowCount = 0;
    MasterData1.DataSet = ds;
    MasterData2.DataSet = NULL;
    }
    ds.First();
    }
    gordk wrote: »
    it is not too dificult just re-think your situation.
    do not use groupheaders footers. and do not connect the databand on design page 1 to a dataset.
    control the dataset from code and set the rowcount property of the databand.
    use tables or queries in a master data relationship.
    the master dataset will be the dataset for the tfrxreport component. it will actually control the
    number of times the report is run as well as providing masterdata for the
    areas above and below the record detail area on design page 1, even though this is detail data
    use a master databand and set its rowcount property to the num of recs it can contain.
    code page
    var
    ds: TfrxDataSet;

    begin // at bottom of code page assuming record area can handle 12 recs
    ds := Report.GetDataset('frxDBDataSet2'); //the user name of the detaildataset
    // now set props for masterdata on design pages 1 and 2
    begin
    if ds.recordcount >12 then
    begin
    page2 .visible := true; //set designpage 2 visible
    masterdata1.rowcount := 12;
    masterdata1.dataset :='';
    masterdata2.dataset := 'frxDBDataSet2';
    end
    else
    begin
    page2 .visible := false// not enough records so dont need
    masterdata1.dataset := 'frxDBDataSet2';
    masterdata2.dataset :='';
    masterdata1.rowcount := 0;
    end;
    ds.first;// make sure on first record
    end;

    end.

    write code for the oap event of masterdata1
    if masterdata1.rowcount > 0 then ds.next;

    dont confuse the name of bands with data relationships bands are really just place holders on a design page
  • edited 11:22AM
    Hello w0wbagger,

    If you find a minute of spare time then have a look at PDF file I enclosed here yesterday.
    Is it the result that you are looking for?

    I've spent over 2 hours testing that, please do not make think it was my lost time ;-)

    Mick
  • gordkgordk St.Catherines On. Canada.
    edited 11:22AM
    Sorry i got tied up on other buisness.
    here are the mods to the code. this is all in the report code page.
    var
    ds: TfrxDataSet;


    procedure Page1OnBeforePrint(Sender: TfrxComponent);
    begin
    if ds.recordcount > 4 then
    begin
    ds.first;
    masterdata1.rowcount := 4;
    masterdata2.rowcount := ds.recordcount - 4;
    page2.visible := true;
    end
    else
    begin
    page2.visible := false;
    masterdata1.rowcount := ds.recordcount;
    masterdata2.rowcount:= 0;
    end;
    end;

    procedure MasterData1OnAfterPrint(Sender: TfrxComponent);
    begin
    ds.next;
    end;

    procedure Page2OnBeforePrint(Sender: TfrxComponent);
    begin
    // not used was just here for testing
    end;


    procedure MasterData2OnAfterPrint(Sender: TfrxComponent);
    begin
    ds.next;
    end;

    begin
    ds := Report.GetDataset('Items'); //the user name of the detaildataset
    end.


  • edited 11:22AM
    GordK & W0wbagger,

    I've joined this forum just few days ago and maybe that's why I don't know enough about standards of comunication over here. But I do NOT understand why do you both keep on complicating this by writing more and more code and forcing DataSets to do some work :-(

    On Feb 2 2011, 09:46 PM I gave here my proposition how to solve the problem with 2 different PageHeader and PageFooter - I did attach PDF file to show the result of my succesfull tests. After all - I used less then 30 lines of pure FR script working ONLY with PageHeaderOnBeforePrint.

    Below is my solution, which needs only small corrects (pointer operation). I use ADOQuery2 (select * from Customers) to show better how PageHeader & PageFooter do work for me for different number of companies in each state.


    var LState :string;
    procedure PageHeader1OnBeforePrint(Sender: TfrxComponent);
    var PF :TfrxPageFooter;
    i :int;
    begin
    if Engine.FinalPass then begin
    Child1.Visible := <Page> = 1;
    Child2.Visible := not Child1.Visible;
    end;
    if Engine.FinalPass
    then if (<Page#> = 1)
    then begin
    Memo12.Memo.Text := LState;
    Memo13.Memo.Text := LState;
    end
    else begin
    Memo12.Memo.Text := <ADOQuery2."State">;
    Memo13.Memo.Text := <ADOQuery2."State">;
    end
    else if LState = ''
    then LState := <ADOQuery2."State">;
    // code below needs to be corrected due to bad pointer operations
    if Engine.FinalPass then with Page1 do for i:=0 to Objects.Count -1 do
    if Objects is TfrxPageFooter
    then if Child1.Visible
    then Page1.Objects.Items := Page2.Objects.Items[0]
    else Page1.Objects.Items := Page3.Objects.Items[0];
    end;


    Full report definition is within my post on Feb 2 2011, 09:46 PM.

    Is my solution really so bad that it is not worth to exchange any comments on it ?

    Mick
  • edited 11:22AM
    Mick, I looked at your PDF, and that's *exactly* what I want to do. I'll take a better look at your fr3 file. I've temporarily solved the problem by using two queries, one for the 1st 4 records, one for the rest, and two separate datasets, but of course, that's a bit kluge-y. Your solution looks like it might be more elegant. I also see that Gord has provided a bit more information as well, so my weekend looks like it's going to be busy. Thanks to you both for helping. I'm getting more comfortable with the engine - it's hard to wrap my head around the new engine when I'm so used to a different way of doing things.

    Mick.pl wrote: »
    I tried to use some tricks.

    Depending on page number within a group (select ... from customers group by state) I choose which of two Childs should be visible. It work correctly, but as report is double pass I had to do something about the last State (TX), which tried to appear on THE FIRST page (with companies of AL). This script is not perfect, but it shows the location of the problem.


    The code at PageHeader1OnBeforePrint does its duty to change pagefooter on the Page1
    but it causes a critical error to FR engine. Be carefull as IT DESTROYS this report [img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> The problem is to avoid bad pointer operations, which is black magic for me[/img][img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> I do not use Delphi. My area is pure script of FR and SQL database - that's why I couldn't solve pointer operation error. Below there's PDF file to show what I got, and fr3 to how I did it. Mick PS. I'll be gratefull to know how to manage those Page1.Objects[/img]

  • edited 11:22AM
    Hi guys,

    i retrieved the code of gordk, but i have a problem.
    I need to show 2 lines on the first page (masterdata1) and i want the rest of my lines (masterdata2) on the second page.
    For example:
    If i have 4 lines in total, my problem, on the second page, i have the first and the third lines, not the third and fourth.

    Hereis my code:

    var
    ds: TfrxDataSet;

    procedure Page1OnBeforePrint(Sender: TfrxComponent);
    begin
    if ds.recordcount > 2 then
    begin
    ds.first;
    MasterData1.rowcount := 2;
    MasterData2.rowcount := ds.recordcount - 2;
    //showmessage(MasterData1.rowcount) ;
    //showmessage(MasterData2.rowcount) ;
    page3.visible := true;
    page1.visible := true;
    end
    else
    begin
    page3.visible := false;
    page1.visible := true;
    MasterData1.rowcount := ds.recordcount;
    MasterData2.rowcount:= 0;
    end;
    end;

    procedure MasterData1OnAfterPrint(Sender: TfrxComponent);
    begin
    ds.next;
    //showmessage(ds.next);
    end;


    procedure MasterData2OnAfterPrint(Sender: TfrxComponent);
    begin
    ds.next;
    //masterData2.rowcount := ds.recordcount - 2;

    end;


    begin
    ds := Report.GetDataset('PERSO01'); //the user name of the detaildataset
    end.





    w0wbagger wrote: »
    Mick, I looked at your PDF, and that's *exactly* what I want to do. I'll take a better look at your fr3 file. I've temporarily solved the problem by using two queries, one for the 1st 4 records, one for the rest, and two separate datasets, but of course, that's a bit kluge-y. Your solution looks like it might be more elegant. I also see that Gord has provided a bit more information as well, so my weekend looks like it's going to be busy. Thanks to you both for helping. I'm getting more comfortable with the engine - it's hard to wrap my head around the new engine when I'm so used to a different way of doing things.

    w0wbagger wrote: »
    I tried to use some tricks.

    Depending on page number within a group (select ... from customers group by state) I choose which of two Childs should be visible. It work correctly, but as report is double pass I had to do something about the last State (TX), which tried to appear on THE FIRST page (with companies of AL). This script is not perfect, but it shows the location of the problem.


    The code at PageHeader1OnBeforePrint does its duty to change pagefooter on the Page1
    but it causes a critical error to FR engine. Be carefull as IT DESTROYS this report [img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> The problem is to avoid bad pointer operations, which is black magic for me[/img][img]style_emoticons/<#EMO_DIR#>/sad.gif" style="vertical-align:middle" emoid=":(" border="0" alt="sad.gif" /> I do not use Delphi. My area is pure script of FR and SQL database - that's why I couldn't solve pointer operation error. Below there's PDF file to show what I got, and fr3 to how I did it. Mick PS. I'll be gratefull to know how to manage those Page1.Objects[/img]

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.