Getting a Master-Detail report without design time datasource

Hi there.

I've been successfully using FRNet for some time now generating reports the following way:

* Design the reports with fixed table names / Column names
* Call the reports from C# assigning datatables to databands using:

the tables are all part of a dataset:
rep.RegisterData(ds)
for each databand:
db = (DataBand)rep.FindObject([NAME OF THE DATABAND]);
db.DataSource = rep.GetDataSource([NAME OF THE TABLE]);

now i have the taskt to add a master-detail report concerning 2 tables in that dataset...
one is related to the other by a id field
i have tried relating the two tables (Table A and B ) in the dataset by using

parentColumn = ds.Tables["A"].Columns["INDEXCOLUMN"];
childColumn = ds.Tables["B"].Columns["REF-INDEXCOLUMN"];
dataRel = new DataRelation("parent2Child", parentColumn, childColumn);
ds.Tables["B"].ParentRelations.Add(dataRel);

the big question now is how to go about creating the master-detail link in the report.
I have tried creating a nested databand inside the band for table A and link that databand to B, but using [B.COLUMNAME] in the report yields "B unknown in this context"

Any pointers on how to tackle this?

annot: the words in capitals are placeholders for internal names

Comments

  • edited 1:07AM
    Hello,
    wrote:
    using [B.COLUMNAME] in the report yields "B unknown in this context"
    Check that COLUMNAME exists in the B table. If you make a typo in the table/column name, you will get the compiler error.

    I recommend another (easier) way to create reports. You add a button (or menu item) in your application that calls the report designer:
        private void btnCreateNew_Click(object sender, EventArgs e)
        {
          // create report instance
          Report report = new Report();
    
          // register the dataset
          report.RegisterData(Your_DataSet);
    
          // design the report
          report.Design();
    
          // free resources used by report
          report.Dispose();
        }
    

    Run the application and click the button. Create a new report and save it to a file. Note that you work with actual dataset, and can preview the report immediately.
    To run an existing report:
          // create report instance
          Report report = new Report();
    
          // load the existing report
          report.Load("report.frx");
    
          // register the dataset
          report.RegisterData(Your_DataSet);
    
          // run the report
          report.Show();
    
          // free resources used by report
          report.Dispose();
    

    Using this approach, you have the following advantages:
    - you work with "live" data and can run the preview while designing a report;
    - this code is no longer needed:
    db = (DataBand)rep.FindObject([NAME OF THE DATABAND]);
    db.DataSource = rep.GetDataSource([NAME OF THE TABLE]);
    

    This approach was used to create demo reports. All reports in the demo.exe were created in run-time. In case if you don't need run-time designer, you may remove the designer button from the production version.
  • This is going to be kind of hard as we are talking about a web application data backend here which is, essentially, "headless". I'll re-check the table name though
  • Table-name and column-name verified, double checked and confirmed as existing. COuld it be a problem in registering the datasource?
  • edited 1:07AM
    Could you make a simple test project for me and send it to tz@fast-report.com?
  • I'll have a go at it when i have the time, but that's unfortunately not likely to be soon
  • I pinned down the main problem in this.

    the databand was called "OrderPositions" and the Table was called "ORDERPOSITIONS", which FRNet got mixed up.

    Now i get the data in the report, question now is how do i establish the master-detail relation?
    right now i get all entries from the detail table for each master row.

    Is there a way to do this in this scenario (see first post)?
  • As an addition: The notation "B.A.COLUMNAME_IN_A" is working in the nested Databand
  • edited 1:07AM
    First you need to establish a relation between two DataTable's, then register the DataSet in a report. In this case FastReport will create the relation automatically. So you need to do this:
    // first create the relation
    parentColumn = ds.Tables["A"].Columns["INDEXCOLUMN"];
    childColumn = ds.Tables["B"].Columns["REF-INDEXCOLUMN"];
    dataRel = new DataRelation("parent2Child", parentColumn, childColumn);
    ds.Tables["B"].ParentRelations.Add(dataRel);
    
    // then register the data
    rep.RegisterData(ds);
    db = (DataBand)rep.FindObject([NAME OF THE DATABAND]);
    db.DataSource = rep.GetDataSource([NAME OF THE TABLE]);
    
  • edited March 2010
    well yes, this is exactly what is happenig... this is the code as-is:
                    //insert table relation (to be used by FR.NET)
                    parentColumn = ds.Tables["POSITIONS"].Columns["AUFTRAGID"];
                    childColumn = ds.Tables["ORDERPOSITIONS"].Columns["AUFTRAGID"];
                    dataRel = new DataRelation("parent2Child", parentColumn, childColumn);
                    ds.Tables["ORDERPOSITIONS"].ParentRelations.Add(dataRel);
                    ds.Relations.Add(dataRel);
    

    and in a seperate library, but with a 1:1 passed-through ds:

    (this happens inside a xml-linq statement, but the [B.A.A_COLUMN] test shows that it is basically working:
                 rep.RegisterData(ds); //add runtime data
                
                //whip up data bindings
                    db = (DataBand)rep.FindObject(bandElem.Attribute("PositionsBand").Value);
                    db.DataSource = rep.GetDataSource(bandElem.Attribute("POSITIONS").Value);
                    db = (DataBand)rep.FindObject(bandElem.Attribute("OrderPositionsBand").Value);
                    db.DataSource = rep.GetDataSource(bandElem.Attribute("ORDERPOSITIONS").Value);
    
    (note that the original code does not carry actual strings but adds the right ones dynamically)

    still.. i get _all_ rows from the detail table but can access the master table in the nested databand. ( I get the correct related master entries to display in the nested "detail" databand)
  • edited 1:07AM
    Ok, I was able to reproduce this in a simple app.
          DataSourceBase parentDs = report.GetDataSource("Categories");
          DataSourceBase childDs = report.GetDataSource("Products");
          // enable both datasources
          parentDs.Enabled = true;
          childDs.Enabled = true;
          // enable the relation as well
          report.Dictionary.UpdateRelations();
          // bind databands to datasources
          (report.FindObject("Data1") as DataBand).DataSource = parentDs;
          (report.FindObject("Data2") as DataBand).DataSource = childDs;
    
  • the "report.Dictionary.UpdateRelations();" line fixed it. Thank you!
  • Magezi SagesseMagezi Sagesse DRCONGO
    edited 1:07AM
    AlexTZ wrote: »
    Ok, I was able to reproduce this in a simple app.
          DataSourceBase parentDs = report.GetDataSource("Categories");
          DataSourceBase childDs = report.GetDataSource("Products");
          // enable both datasources
          parentDs.Enabled = true;
          childDs.Enabled = true;
          // enable the relation as well
          report.Dictionary.UpdateRelations();
          // bind databands to datasources
          (report.FindObject("Data1") as DataBand).DataSource = parentDs;
          (report.FindObject("Data2") as DataBand).DataSource = childDs;
    
    Following what is above here is what I did:
     Dim colonneparent As DataColumn = Donnees.Tables("bons").Columns("bon")
                Dim colonnechild As DataColumn = Donnees.Tables("signataires").Columns("numero")
                Dim relationd As New DataRelation("relationop", colonneparent, colonnechild)
                Donnees.Tables("signataires").ParentRelations.Add(relationd)
    
    
                rapportcharge.RegisterData(Donnees)
    
                rapportcharge.Dictionary.UpdateRelations()
    
                rapportcharge.GetDataSource("bons").Enabled = True
                rapportcharge.GetDataSource("signataires").Enabled = True
    
                liste.DataSource = rapportcharge.GetDataSource("bons")
                signataires.DataSource = rapportcharge.GetDataSource("signataires")
    

    In vb.net but the probleme is with the method updateRelations; when I omit it data are being load in the correct order but all rows of the details datatable is are being show for every row of the master datatable; And When I put it data are being misordered (a value of the first row of master datatable is being printed on the second and so on) but the details rows that's appearing for each master row correspond to it.

    I don't understand how to deal with that methode. Is it good to create the relation on the datatable(code) in or directly using the datasource of the report(report )

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.