I want to create a report with a specific layout based on a given model, but the dataset it will be based on will be dynamically created via the (application) UI.
I'd rather do this and supply a populated model to the report than to have a report will a gazillion parameters that are populated by the app and then have the report fetch the data all over again.
Q: Can I do this?
Q: If I can can some one give me an example (Pretty Please)
Q: Can I do this using TRDX files?
Q: Can I do this using *.cs reports?
Q: Can I be really pushy and as for examples of both (Pretty Please with Sugar on).
4 Answers, 1 is accepted
Telerik Reports are templates designed based on a specific data schema. Even if data is obtained from different sources, the schema must remain the same; otherwise, the report must be created at run-time after the data is analyzed.
In case the data schema will be the same, you can build custom data access layer in a separate assembly. This data ccess layer will contain the custom logic for retrieving and caching the data to avoid consecutive calls to the data storage. The data retrieval methods can be used in a report via Object/ Entity/ OpenAccess DataSource component.
To use these data source components in the integrated in VS Report Designer, you can add a reference to the external assembly.
To use these data source components in the Standalone Report Designer, you will have to extend the tool's configuration. Details how to extend the Standalone Designer are available in Extending Report Designer and the resources linked at the bottom of the article (ConfigureStandaloneDesigner.zip contains a video illustrating the settings for extending the tool).
The usage of custom data objects allows you to save from additional data source components by applying the data-binding approaches from How to use the ReportItem.DataObject property in expressions and How to Databind to Collection Properties. (check the video in DataModelsDataBinding.zip)
In case the data schema will change (the number and name of fields will not be the same), the report will have to be created at run-time in Visual Studio. The recommended approach is to get familiar with reports structure by creating sample report with the desired layout in VS Report Designer, and re-using the code generated in the report's Designer.cs(vb) file.
An example of a Table item created at run-time based on data is available in the Displaying Dynamically Generated Columns in Report forum thread.
Let us know if you have any further questions.
Regards,
Stef
Telerik
Stef,
I'm clearly far too stupid to use this.
I've got a report definition, which I've included below.
The report has an ObjectDataSource. You can see, from lines 144/145 that the ObjectDataSource is pointing to a model type (typeof(Genesis.UI.Reports.ViewModels.Standard.Incidents.SimpleIncidentReportVm)) and a method within the model ("Incidents")
My model looks like this ...
01.public class SimpleIncidentReportVm02.{03. List<Incident> incidents;04. public List<Incident> Incidents()05. {06. return incidents;07. }08. public void SetIncidents(IEnumerable<Incident> incidents)09. {10. this.incidents = incidents.ToList();11. }12.}When the report is run I can see my model being populates with 200+ rows.
The report displays showing no data.
If I put a breakpoint on line 93 of the report definition file, when the report is run the ObjectDataSource's DataSource is null and the DataMember is "".
The breakpoint at line 144 shows the ObjectDataSource being correctly set, but for the life of me I can't see any evidence of the actual data making it to the report.
Further, my report includes a Count of the rows included that always reports zero.
I feel sure that this must be much simpler that I'm making it. I'm going to have to ask if you can explain what I'm doing wrong in terms you'd use to explain it to a pre-schooler. :-(
001.partial class IncidentListReport002.{003. #region Component Designer generated code004. /// <summary>005. /// Required method for telerik Reporting designer support - do not modify006. /// the contents of this method with the code editor.007. /// </summary>008. private void InitializeComponent()009. {010. Telerik.Reporting.TableGroup tableGroup1 = new Telerik.Reporting.TableGroup();011. Telerik.Reporting.TableGroup tableGroup2 = new Telerik.Reporting.TableGroup();012. Telerik.Reporting.TableGroup tableGroup3 = new Telerik.Reporting.TableGroup();013. Telerik.Reporting.TableGroup tableGroup4 = new Telerik.Reporting.TableGroup();014. Telerik.Reporting.TableGroup tableGroup5 = new Telerik.Reporting.TableGroup();015. Telerik.Reporting.Drawing.StyleRule styleRule1 = new Telerik.Reporting.Drawing.StyleRule();016. Telerik.Reporting.Drawing.StyleRule styleRule2 = new Telerik.Reporting.Drawing.StyleRule();017. Telerik.Reporting.Drawing.StyleRule styleRule3 = new Telerik.Reporting.Drawing.StyleRule();018. Telerik.Reporting.Drawing.DescendantSelector descendantSelector1 = new Telerik.Reporting.Drawing.DescendantSelector();019. Telerik.Reporting.Drawing.StyleRule styleRule4 = new Telerik.Reporting.Drawing.StyleRule();020. Telerik.Reporting.Drawing.DescendantSelector descendantSelector2 = new Telerik.Reporting.Drawing.DescendantSelector();021. this.textBox1 = new Telerik.Reporting.TextBox();022. this.textBox2 = new Telerik.Reporting.TextBox();023. this.textBox3 = new Telerik.Reporting.TextBox();024. this.textBox4 = new Telerik.Reporting.TextBox();025. this.detailSection1 = new Telerik.Reporting.DetailSection();026. this.table1 = new Telerik.Reporting.Table();027. this.textBox5 = new Telerik.Reporting.TextBox();028. this.textBox6 = new Telerik.Reporting.TextBox();029. this.textBox7 = new Telerik.Reporting.TextBox();030. this.textBox8 = new Telerik.Reporting.TextBox();031. this.objectDataSource1 = new Telerik.Reporting.ObjectDataSource();032. this.textBox9 = new Telerik.Reporting.TextBox();033. this.pageHeaderSection1 = new Telerik.Reporting.PageHeaderSection();034. this.textBox10 = new Telerik.Reporting.TextBox();035. this.pageFooterSection1 = new Telerik.Reporting.PageFooterSection();036. this.textBox11 = new Telerik.Reporting.TextBox();037. ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();038. // 039. // textBox1040. // 041. this.textBox1.Name = "textBox1";042. this.textBox1.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(2D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));043. this.textBox1.StyleName = "Normal.TableHeader";044. this.textBox1.Value = "Id1";045. // 046. // textBox2047. // 048. this.textBox2.Name = "textBox2";049. this.textBox2.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(6.4185409545898438D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));050. this.textBox2.StyleName = "Normal.TableHeader";051. this.textBox2.Value = "Title";052. // 053. // textBox3054. // 055. this.textBox3.Name = "textBox3";056. this.textBox3.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(2.926041841506958D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));057. this.textBox3.StyleName = "Normal.TableHeader";058. this.textBox3.Value = "Occurence Date";059. // 060. // textBox4061. // 062. this.textBox4.Name = "textBox4";063. this.textBox4.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(3.5610413551330566D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));064. this.textBox4.StyleName = "Normal.TableHeader";065. this.textBox4.Value = "Due Date";066. // 067. // detailSection1068. // 069. this.detailSection1.Height = Telerik.Reporting.Drawing.Unit.Cm(1.1999998092651367D);070. this.detailSection1.Items.AddRange(new Telerik.Reporting.ReportItemBase[] {071. this.table1});072. this.detailSection1.Name = "detailSection1";073. // 074. // table1075. // 076. this.table1.Body.Columns.Add(new Telerik.Reporting.TableBodyColumn(Telerik.Reporting.Drawing.Unit.Cm(1.9999998807907105D)));077. this.table1.Body.Columns.Add(new Telerik.Reporting.TableBodyColumn(Telerik.Reporting.Drawing.Unit.Cm(6.4185409545898438D)));078. this.table1.Body.Columns.Add(new Telerik.Reporting.TableBodyColumn(Telerik.Reporting.Drawing.Unit.Cm(2.9260406494140625D)));079. this.table1.Body.Columns.Add(new Telerik.Reporting.TableBodyColumn(Telerik.Reporting.Drawing.Unit.Cm(3.5610406398773193D)));080. this.table1.Body.Rows.Add(new Telerik.Reporting.TableBodyRow(Telerik.Reporting.Drawing.Unit.Cm(0.5D)));081. this.table1.Body.SetCellContent(0, 0, this.textBox5);082. this.table1.Body.SetCellContent(0, 1, this.textBox6);083. this.table1.Body.SetCellContent(0, 2, this.textBox7);084. this.table1.Body.SetCellContent(0, 3, this.textBox8);085. tableGroup1.ReportItem = this.textBox1;086. tableGroup2.ReportItem = this.textBox2;087. tableGroup3.ReportItem = this.textBox3;088. tableGroup4.ReportItem = this.textBox4;089. this.table1.ColumnGroups.Add(tableGroup1);090. this.table1.ColumnGroups.Add(tableGroup2);091. this.table1.ColumnGroups.Add(tableGroup3);092. this.table1.ColumnGroups.Add(tableGroup4);093. this.table1.DataSource = this.objectDataSource1;094. this.table1.Items.AddRange(new Telerik.Reporting.ReportItemBase[] {095. this.textBox5,096. this.textBox6,097. this.textBox7,098. this.textBox8,099. this.textBox1,100. this.textBox2,101. this.textBox3,102. this.textBox4});103. this.table1.Location = new Telerik.Reporting.Drawing.PointU(Telerik.Reporting.Drawing.Unit.Cm(0D), Telerik.Reporting.Drawing.Unit.Cm(0D));104. this.table1.Name = "table1";105. this.table1.NoDataMessage = "=\"No Data\"";106. this.table1.NoDataStyle.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(128)))));107. this.table1.NoDataStyle.Font.Name = "Arial Black";108. tableGroup5.Groupings.Add(new Telerik.Reporting.Grouping(null));109. tableGroup5.Name = "Detail";110. this.table1.RowGroups.Add(tableGroup5);111. this.table1.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(14.905622482299805D), Telerik.Reporting.Drawing.Unit.Cm(1D));112. this.table1.StyleName = "Normal.TableNormal";113. // 114. // textBox5115. // 116. this.textBox5.Name = "textBox5";117. this.textBox5.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(2D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));118. this.textBox5.StyleName = "Normal.TableBody";119. this.textBox5.Value = "= Fields.Id";120. // 121. // textBox6122. // 123. this.textBox6.Name = "textBox6";124. this.textBox6.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(6.4185409545898438D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));125. this.textBox6.StyleName = "Normal.TableBody";126. this.textBox6.Value = "= Fields.Title";127. // 128. // textBox7129. // 130. this.textBox7.Name = "textBox7";131. this.textBox7.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(2.926041841506958D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));132. this.textBox7.StyleName = "Normal.TableBody";133. this.textBox7.Value = "= Fields.OccurenceDate";134. // 135. // textBox8136. // 137. this.textBox8.Name = "textBox8";138. this.textBox8.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(3.5610413551330566D), Telerik.Reporting.Drawing.Unit.Cm(0.5D));139. this.textBox8.StyleName = "Normal.TableBody";140. this.textBox8.Value = "= Fields.DueDate";141. // 142. // objectDataSource1143. // 144. this.objectDataSource1.DataMember = "Incidents";145. this.objectDataSource1.DataSource = typeof(Genesis.UI.Reports.ViewModels.Standard.Incidents.SimpleIncidentReportVm);146. this.objectDataSource1.Name = "Incidents";147. // 148. // textBox9149. // 150. this.textBox9.Name = "ReportNameTextBox";151. this.textBox9.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(15D), Telerik.Reporting.Drawing.Unit.Cm(0.89999997615814209D));152. this.textBox9.Style.Font.Bold = true;153. this.textBox9.Style.Font.Name = "Segoe UI";154. this.textBox9.Style.Font.Size = Telerik.Reporting.Drawing.Unit.Point(14D);155. this.textBox9.Value = "Incident List Report";156. // 157. // pageHeaderSection1158. // 159. this.pageHeaderSection1.Height = Telerik.Reporting.Drawing.Unit.Cm(1.2000000476837158D);160. this.pageHeaderSection1.Items.AddRange(new Telerik.Reporting.ReportItemBase[] {161. this.textBox9});162. this.pageHeaderSection1.Name = "pageHeaderSection1";163. // 164. // textBox10165. // 166. this.textBox10.Location = new Telerik.Reporting.Drawing.PointU(Telerik.Reporting.Drawing.Unit.Cm(10.905622482299805D), Telerik.Reporting.Drawing.Unit.Cm(0.00010012308484874666D));167. this.textBox10.Name = "ReportPageNumberTextBox";168. this.textBox10.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(4D), Telerik.Reporting.Drawing.Unit.Cm(1D));169. this.textBox10.Style.Font.Name = "Segoe UI";170. this.textBox10.Value = "Page: {PageNumber}";171. // 172. // pageFooterSection1173. // 174. this.pageFooterSection1.Height = Telerik.Reporting.Drawing.Unit.Cm(1.0999997854232788D);175. this.pageFooterSection1.Items.AddRange(new Telerik.Reporting.ReportItemBase[] {176. this.textBox10,177. this.textBox11});178. this.pageFooterSection1.Name = "pageFooterSection1";179. // 180. // textBox11181. // 182. this.textBox11.Location = new Telerik.Reporting.Drawing.PointU(Telerik.Reporting.Drawing.Unit.Cm(0D), Telerik.Reporting.Drawing.Unit.Cm(0.00010012308484874666D));183. this.textBox11.Name = "textBox11";184. this.textBox11.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Cm(3D), Telerik.Reporting.Drawing.Unit.Cm(0.99999988079071045D));185. this.textBox11.Value = "Count: {Count()}";186. // 187. // IncidentListReport188. // 189. this.Items.AddRange(new Telerik.Reporting.ReportItemBase[] {190. this.detailSection1,191. this.pageHeaderSection1,192. this.pageFooterSection1});193. this.Name = "IncidentListReport";194. this.PageSettings.Margins = new Telerik.Reporting.Drawing.MarginsU(Telerik.Reporting.Drawing.Unit.Mm(25.399999618530273D), Telerik.Reporting.Drawing.Unit.Mm(25.399999618530273D), Telerik.Reporting.Drawing.Unit.Mm(25.399999618530273D), Telerik.Reporting.Drawing.Unit.Mm(25.399999618530273D));195. this.PageSettings.PaperKind = System.Drawing.Printing.PaperKind.A4;196. styleRule1.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {197. new Telerik.Reporting.Drawing.TypeSelector(typeof(Telerik.Reporting.TextItemBase)),198. new Telerik.Reporting.Drawing.TypeSelector(typeof(Telerik.Reporting.HtmlTextBox))});199. styleRule1.Style.Padding.Left = Telerik.Reporting.Drawing.Unit.Point(2D);200. styleRule1.Style.Padding.Right = Telerik.Reporting.Drawing.Unit.Point(2D);201. styleRule2.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {202. new Telerik.Reporting.Drawing.StyleSelector(typeof(Telerik.Reporting.Table), "Normal.TableNormal")});203. styleRule2.Style.BorderColor.Default = System.Drawing.Color.Black;204. styleRule2.Style.BorderStyle.Default = Telerik.Reporting.Drawing.BorderType.Solid;205. styleRule2.Style.BorderWidth.Default = Telerik.Reporting.Drawing.Unit.Pixel(1D);206. styleRule2.Style.Color = System.Drawing.Color.Black;207. styleRule2.Style.Font.Name = "Tahoma";208. styleRule2.Style.Font.Size = Telerik.Reporting.Drawing.Unit.Point(9D);209. descendantSelector1.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {210. new Telerik.Reporting.Drawing.TypeSelector(typeof(Telerik.Reporting.Table)),211. new Telerik.Reporting.Drawing.StyleSelector(typeof(Telerik.Reporting.ReportItem), "Normal.TableHeader")});212. styleRule3.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {213. descendantSelector1});214. styleRule3.Style.BorderColor.Default = System.Drawing.Color.Black;215. styleRule3.Style.BorderStyle.Default = Telerik.Reporting.Drawing.BorderType.Solid;216. styleRule3.Style.BorderWidth.Default = Telerik.Reporting.Drawing.Unit.Pixel(1D);217. styleRule3.Style.Font.Name = "Tahoma";218. styleRule3.Style.Font.Size = Telerik.Reporting.Drawing.Unit.Point(10D);219. styleRule3.Style.VerticalAlign = Telerik.Reporting.Drawing.VerticalAlign.Middle;220. descendantSelector2.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {221. new Telerik.Reporting.Drawing.TypeSelector(typeof(Telerik.Reporting.Table)),222. new Telerik.Reporting.Drawing.StyleSelector(typeof(Telerik.Reporting.ReportItem), "Normal.TableBody")});223. styleRule4.Selectors.AddRange(new Telerik.Reporting.Drawing.ISelector[] {224. descendantSelector2});225. styleRule4.Style.BorderColor.Default = System.Drawing.Color.Black;226. styleRule4.Style.BorderStyle.Default = Telerik.Reporting.Drawing.BorderType.Solid;227. styleRule4.Style.BorderWidth.Default = Telerik.Reporting.Drawing.Unit.Pixel(1D);228. styleRule4.Style.Font.Name = "Tahoma";229. styleRule4.Style.Font.Size = Telerik.Reporting.Drawing.Unit.Point(9D);230. this.StyleSheet.AddRange(new Telerik.Reporting.Drawing.StyleRule[] {231. styleRule1,232. styleRule2,233. styleRule3,234. styleRule4});235. this.Width = Telerik.Reporting.Drawing.Unit.Cm(15D);236. ((System.ComponentModel.ISupportInitialize)(this)).EndInit();237. 238. }239. #endregion240. 241. private Telerik.Reporting.DetailSection detailSection1;242. private Telerik.Reporting.Table table1;243. private Telerik.Reporting.TextBox textBox5;244. private Telerik.Reporting.TextBox textBox6;245. private Telerik.Reporting.TextBox textBox7;246. private Telerik.Reporting.TextBox textBox8;247. private Telerik.Reporting.TextBox textBox1;248. private Telerik.Reporting.TextBox textBox2;249. private Telerik.Reporting.TextBox textBox3;250. private Telerik.Reporting.TextBox textBox4;251. private Telerik.Reporting.ObjectDataSource objectDataSource1;252. private Telerik.Reporting.TextBox textBox9;253. private Telerik.Reporting.PageHeaderSection pageHeaderSection1;254. private Telerik.Reporting.TextBox textBox10;255. private Telerik.Reporting.PageFooterSection pageFooterSection1;256. private Telerik.Reporting.TextBox textBox11;257.}
I've also tried explicitly setting the datasource for the table to the ObjectDataSource on the report, to no avail.
;-(
When you use an ObjectDatasource component the data source is specified by its type's name or assembly qualified name, and optionally a specififc data retrieval method. The reporting engine uses this information to create an object via Reflection, and then uses the specified data retrieval method.
For example, if we add a default constructor in which the Incidents collection is loaded, the report will load successfully the data:
public class SimpleIncidentReportVm { List<Incident> incidents; public List<Incident> Incidents() { return incidents; } public SimpleIncidentReportVm() { incidents = new List<Incident>(); incidents.Add(new Incident { Id = 1, Title = "test1", DueDate = DateTime.Today, OccurenceDate = DateTime.Today }); incidents.Add(new Incident { Id = 2, Title = "test2", DueDate = DateTime.Today, OccurenceDate = DateTime.Today }); } ............... }If data cannot be initialized as illustrated above, you can use directly a data object instance at run-time without wrapping it in a data source as follows:
//data objectvar data = GetData();//create a report instancevar report = new IncidentListReport();//set the Table.DataSourcevar table = report.Items.Find("table1",true)[0] as Telerik.Reporting.Table;table.DataSource = data;//any item can be accessed herevar tb= report.Items.Find("textBox11",true)[0] as Telerik.Reporting.TextBox;tb.Value = data.SomeStringProperty;//display the reportreportViewer1.ReportSource = new InstanceReportSource { Reportdocument = report};About the count of rows displayed by the Table item, you can use Data functions:
- if the count must be displayed in the PageFooterSection, you can use the PageExec data function to get the count of rows per page;
- If the count can be displayed at the end of the Table item, you can use the Exec data function with the scope of the Table item.
I hope this information helps you.
Regards,
Stef
Telerik