This is a migrated thread and some comments may be shown as answers.

Sort of master/detail scenario and crosstale total recalculating

6 Answers 121 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
ciccio
Top achievements
Rank 1
ciccio asked on 16 Jun 2011, 05:58 PM
HI,

The question:
i would like have a list of "items" (Combobox or other object)  always visible and on selecting one or more item from the list i would like to see a report of data .What matter is that the second report be displayed just after selecting one or more items from the combobox ( or other object).
This is a scenario very close to a Drilldown one or a Master/details one, but in my scenario there is no Database relathionship between items and the report i want to be displayed. Lets say that the items are the names of  some tables on DB. The user  selects one or more of this table from combo (or other object) and a the report with data from this table is shown. This report has own parameters and one or more crostables to analyze the data.
If it is possible to keep on the same report (Area) the combobox and the the related data-report it will be  perfect. But also having the list and  the report in two separated area could be fine. The matter is that the list be always visible.

The History:
Working  with a crossTable: no problem to bind it to a datasourceObject from my DataLayer.So i have my data grouped and crossed as expected.
Next i added some parameter at design time (report.reportParameters object), here the problem. Using parameter (multivalues) the crossTable is rendered consequently(record are filtered) but not total and grand Total. The total fields show always the total calculated  at the time i  have bounded the datasource. 
In other words once you change parameter, the crosstab is re-rendered but not re-calculated.

To solve this i tougth to re-bind the datasource every time the parameters are modified. That is:

1- getting my data record list  from my DataLayer lets call it listDL
2- passing listDL to a businees object list (lest call it listBO) to work with data in memory
3- populate the parameters collections assigning listBO as datasource
4- executing LINQ queries on listBO using the parameters values.
5- rebind crossaTable datasource to listBO.

The report i am working on is an aggregate report, it shows several tables, them are different views on the same datasource.
That is: different LINQ queries on listBO . This is why i use ListBO: i don't  want call several time my DataLayer and i prefer to use ObjectDataSource then SqlDatasource planning to use this code with our MVVM model.

This was the idea and i started this way:
the first 3 steps are executed in the report constructor
the last 2 steps are executed in NeedDataSource routine
All seems working fine but :
at step 1 i have to pass a parameter (table name) at the method calling my DataLayer to retrieve the set of Data i needs.
let say this parameter is the name of a table Database.
The user have to be make able to choose table's name  from a list . The list of tables is retrieved by a call to  DataLayer .
The question is: where and how i can do this?
I can't add another parameter (for table name) ad design time because i can catch its value just in NeedDataSource routine, but the this value have to be cathced at step 1  (in the constructor ).
The only way i see is to pass the parameter to the constructor, but how can i do this?
The closest thing i could think is something like a subReport, but to manage a subReport with own Parameters UI seems too complex to me.
A easier solution could be to create a report for choosing the tables and then navigate at the crosstable report passing the choosen parameter.But i whould like to select the tables without navigate trought the windows.( User should select table very frequently)

I have no idea about to accomplish this


Thanks for reading



6 Answers, 1 is accepted

Sort by
0
Steve
Telerik team
answered on 21 Jun 2011, 12:00 PM
Hi ciccio,

Thank you for the detailed explanation of your scenario, but still it did not became apparent what is the exact problem you have encountered. If you want an aggregate function to be executed with specific scope e.g. the CrossTab, then you should take advantage of the Data Scope Related Functions.

Should you need further help, please provide us with a sample report which shows the exact problem and explain what you are trying to achieve. This way we would be able to advise you accordingly.

All the best,
Steve
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
ciccio
Top achievements
Rank 1
answered on 21 Jun 2011, 04:03 PM

Hello,
thank for following us.
I'll try to explain  my self better before to post some code.

the closest example i can do is the following:
imagine an user interface with 2 columns. In the first one the user can select an item, in the second one are displayed the details and the parameters to work on details.
The item in first column are name of databases's table and the data shown on the left are data of the selected table.
Those data are in a CrossTable . By the parameter the user can operate some filtering or grouping.

The History is a description of why we have some constraints.
1. Every tiem the user select an item form left list the crosstable's datasource have to be refreshed calling the datalayer
2. If the user select some  parameters on the rigth column the dasource is recalculated in memory (LINQ) and re-assigned to the crosstable.

We can't figure out how to realize a report  with the described layout . If there was a database relationship between the left item and details on the rigth  it was a simple Master/details scenario, but this not hte case.
We tried to use the  report on th erigth  as a subreport but since it has a toolbar with parameters it creates some problems- 
Is it  possibile to have a crosstable in the details pannel of the report and a list in another pannel in the same report? 
Or, there is a better way to get our goal?


 i attach some diagram to better explain all.

0
Steve
Telerik team
answered on 22 Jun 2011, 01:31 PM
Hi ciccio,

As far as we understand you want to use a Telerik Report as a "form" to create certain layout and allow interaction between items on the left side and right side. Unfortunately such a requirement is out of the scope of a reporting product (Understand the Why, What and How of Reporting Solutions) and you should move all the form and interactivity out in your actual application instead of as part of the report.
The SubReport item is simply a container that hosts a Telerik Report, it is the report viewers that have a toolbar and parameters area (if there is at least one visible report parameter).
In this line of thoughts, you can create any layout by using the provided report items. If you want two or more items in the report to depend on each other you can use Report Parameters and Filtering.
If you aim for interactivity all of the supported interactivity features are described in Adding Interactivity to Reports help articles.

Regards,
Steve
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
ciccio
Top achievements
Rank 1
answered on 23 Jun 2011, 03:45 PM
Hello,
thanks for reply. Now we have a more accurate vision about the context.
But  we still can't figure out how to solve our problem.
Trying to use a windowsForm to host the combobox itemList we got some other troubles.....
In reportviewer (on windows form)  is displayed the list of the report  (reportCatalog) . The user click on a reportcatalog link and navigate to the request report. The problem is to understand which report the reportviwer is showing. The listBox  from wich the user choose an item has to be shown just for one of the report. And so on....
We think thas we have a more generic problem and it can't be solved asking for specific solution-
So, more than some specific solution on how to do the things we would apreciate some guide line about how to achieve our goal.
May be we have had a bad start  designing our reporting architecture with telerik. So, if our goal is clear, the questions is: how whould you have did it...from the scratch? We are not asking for code or specific statements, just how would you build tha architecture?

The goal:
we want an user could choice  an item from a list, then we wont this item be the parameter to pass to  a datalayer method to get data and we wont pass the this data how datasource to a report. This last report has some built in parameter for grouping and/or filtering the Data. 

Thanks for supporting us for so much time.




0
ciccio
Top achievements
Rank 1
answered on 24 Jun 2011, 07:03 PM
Hello,
we have found a solution (a bad solution, but solution). The cascade parmaters seems fit  our needs,but we have sacrified a little piece of our architecture(this is the bad side).
Our mind was to get data from DataLayer by calling a datalayer method and passing a parameter. Then to keep this data in memory for gouping and filtering by built in parameters (data are hosted in a tablecross)-
the following has been our first try (we talked a lot about it early in this thread):
In the report constructor:

//Report constructor .....
InitializeComponent;
  
//Here  we get the Data from DataLayer and we do  a littel data processing  by Linq
 listCubeDistrXDay =
          from t in    daoDbStat.getCubeCardDistr("HardCodedTableName")           
          where t.nazione != null && t.tipoTessera != null && t.data != null
           select new mCubeDistrXday {  cardType= t.cardType, cont = t.cont, data = t.data, country= t.country};
  
 //Here we assign values to the built in parameters   attaching datasource      
           Report.ReportParameters["Pyear"].AvailableValues.DataSource = listCubeDistrXDay;
           Report.ReportParameters["Pday"].AvailableValues.DataSource = listCubeDistrXDay;
           Report.ReportParameters["PcardType"].AvailableValues.DataSource = listCubeDistrXDay;
  
// at this point the report is not yet renedered, but data are in memory (listCubeDistrXDay)

here we have two points:
1- How to pass the "HardCodedTableName" parameter dinamically? This parameter is a name choosen from a list (user interaction)
2- We also want that every time the cross table is modified by filtering or grouping the total and grand total are recalculated.
Filtering on a crossTable just "hide" te data and the toal and grand-total are always refered to the whole data set.

To solve the second point :
private void MyReport_NeedDataSource(object sender, EventArgs e) {
//Here we get the parameters values
           Telerik.Reporting.Processing.Report report = (Telerik.Reporting.Processing.Report)sender;
           IEnumerable kl;
           kl = (IEnumerable)report.Parameters["PcardType"].Value;
           List<string> ls = new List<string>();
           foreach (IEnumerable ie in kl)
           {
               ls.Add((string)ie);
           }
//Here we get the parameters values
           IEnumerable kd;
           report = (Telerik.Reporting.Processing.Report)sender;
           kd = (IEnumerable)report.Parameters["Pday"].Value;
           List<string> ld = new List<string>();
           foreach (IEnumerable ie in kd)
           {
               ld.Add((string)ie);
           }
//Here we get the parameters values
           IEnumerable kn;
           report = (Telerik.Reporting.Processing.Report)sender;
           kn = (IEnumerable)report.Parameters["Pna"].Value;
           List<string> ln = new List<string>();
           foreach (IEnumerable ie in kn)
           {
               ln.Add((string)ie);
           }
           
  //Here we use the in-memory Data to filtering and groping           
           var selectqryX =
            from tx in listCubeDistrXDay
            where tx.nazione != null && tx.tipoTessera != null && tx.data != null
            && ls.Contains(tx.tipoTessera) && ld.Contains(tx.data.Value.Day.ToString()) && ln.Contains(tx.na)
            select new { tx.na, cardType= tx.tipoTessera, cont = tx.cont, data = tx.data, country= tx.country};
             
          // on re.assigning the Datasource we get our tabll-cross recalculated 
             // with correct total and  grand totals. The total and grand total now is jus calculting the Data presents in Crosstable after filtering
            // or gruoping
         this.crosstab1.DataSource =selectqryX;           
            
       }

The point 1 still  was a problem-
No way to pass that parameter dinamically !!!! (a requirements was that the list form wich user could choice the item  were always visible.)

So we have tried with cascade parameters.:
- We have created a Model class sort of proxyDL:
public static class myDataFromDL{  
  
   public static List<mCubeDistrXday> ciccio { get; set; }
 (....) //some defintions.

// This method retunr data form DataLayer and do some data process by linq.
//==================================> passing Parameter dinamically

 

 

public static List<mCubeDistrXday> getData(string pname) {

 


var ll =
           from t in daoDbStat.getCubeTipoTesseraDataNazione(pname) 
           where t.nazione != null && t.tipoTessera != null && t.data != null
           select new mCubeDistrXday {cardType= t.cardType, cont = t.cont, data = t.data, country= t.country};
                     
          foreach (mCubeDistrXday k in ll) listCubeDistrXDay.Add(k);
    =======>ciccio = listCubeDistrXDay;  // Here the processed data are saved
           return listCubeDistrXDay;
  }
}
No code needs in the constructor now!

Now our Datasource is pointed to this object and getData is the member. Finally we can prepare the built in parameter
The "master" parameter is linked to a datasource to get the list of item the user could choice.
The other parameters are depending on Master parameter and are linked to myDataFromDL.getdata() datasource.
the parameter to pass to the method is the "Master" parameter.
Now the usr can see a report showing a list from wich to choice an item , the depending parameter and the crosstable  all in the same area. He can  grouping or filetering and see correct total and sub-total.

So we have what we wanted , but not how we wanted- Infact this solution has  a problem : every time the user change the parameter  a call is sent to DataBase. Our design was to sent a call to the database just when the "master" parameter was changed and  process filtering and grouping on data in memory as early  described in this reply.

We hope now the problem is more clear, we are sure there is a better way to do this and a way to do excatly what we have figured out. 
Thanks.











 





0
Steve
Telerik team
answered on 28 Jun 2011, 04:47 PM
Hello ciccio,

Depending parameters can be filtered both on the client and server and as per your inquiry, I assume that you want to do this on the client so that only a single request to the database is made. You should be aware that this would impose its memory toll as the whole datasource of the parameter would be pulled in and kept in memory in such case. More information about this setup is available in the How-To: Cascading Parameters with applied filtering on Report level help article.

Greetings,
Steve
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
General Discussions
Asked by
ciccio
Top achievements
Rank 1
Answers by
Steve
Telerik team
ciccio
Top achievements
Rank 1
Share this question
or