http://msdn.microsoft.com/es-es/library/ms225242(v=vs.80).aspx http://msdn.microsoft.com/es-es/library/ms227523(v=vs.80).aspx http://msdn.microsoft.com/es-es/library/ms227408(v=vs.80).aspx conectar a colecciones de objetos http://msdn.microsoft.com/es-es/library/ms227595(v=vs.80).aspx Tutorial: Conectar a colecciones de objetos: Introducción En este tutorial, creará una clase que es el tipo de cada objeto de la colección de objetos. La clase representará información del mercado de cotizaciones. Al crear un informe de Crystal, a esta clase Stock se accede a través del asistente de informes de forma parecida a una tabla de base de datos, pero en lugar de agregar columnas de tabla como campos que se desea mostrar, agregará propiedades. Cuando el informe se muestra por primera vez estará vacío. Se ha terminado el diseño del informe, pero no hay datos con los que llenarlo. A continuación, creará un método que genere una instancia de ArrayList y agregue varias instancias de Stock a la instancia de ArrayList. Cada instancia de Stock tiene sus propiedades definidas como valores exclusivos. El método devolverá entonces la instancia de ArrayList. Agregará esta información mediante programación en tiempo de diseño y de nuevo de manera dinámica en tiempo de ejecución. El ArrayList devuelto, una colección de objetos, se asignará a la propiedad SetDataSource del informe de Crystal. Cuando se muestre el informe, cada objeto de la colección de objetos ofrecerá una fila de detalle en el informe. Para empezar, creará la clase Stock Crear la clase Stock En esta sección, creará la clase Stock. La clase Stock contiene campos privados que se exponen como propiedades públicas: Symbol, Volume y Price. Para crear la clase Stock Nota Este procedimiento sólo funciona con un proyecto creado a partir de la Configuración de proyectos. La Configuración de proyectos contiene referencias específicas a espacios de nombres y configuración de códigos necesarios para este procedimiento, y éste no se podrá completar sin dicha configuración. Por lo tanto, antes de que empiece con este procedimiento, primero debe seguir los pasos deConfiguración de proyectos. 1. 2. En Explorador de soluciones, haga clic con el botón secundario en el nombre de sitio Web que está en negrita y, a continuación, haga clic enAgregar nuevo elemento. En el cuadro de diálogo Agregar nuevo elemento: En el campo Plantillas instaladas de Visual Studio, seleccione Clase. En el campo Nombre, escriba "Stock" y, a continuación, haga clic en Agregar. En el cuadro de diálogo que aparece, haga clic en Sí. Nota En Visual Studio 2005, todas las clases deben estar ubicadas en una carpeta App_Code si se desea que puedan ser utilizadas por todos. Al hacer clic en el botón Agregar, aparece un cuadro de alerta que le pregunta si desea colocar la clase en esta carpetaApp_Code. La clase Stock debe definirse como pública para que se pueda acceder a ella al crear el informe. Verifique que la clase que ha creado es pública. Si no lo es, agregue el modificador public a la firma de clase para exponer la clase al Crystal Report Designer incrustado. [Visual Basic] Public Class Stock End Class [C#] public class Stock { public Stock() { } } 1. Si la codificación se realiza en Visual Basic, agregue un constructor predeterminado. [Visual Basic] Sub New() End Sub 2. Dentro de la clase, agregue tres campos privados. [Visual Basic] Private _symbol As String Private _volume As Integer Private _price As Double [C#] private string _symbol; private double _price; private int _volume; A continuación, agregará tres propiedades públicas de lectura y escritura para encapsular los tres campos privados. 1. Cree una nueva propiedad denominada Symbol. [Visual Basic] Public Property Symbol() As String Get Return _symbol End Get Set(ByVal value As String) _symbol = value End Set End Property [C#] public string Symbol { get { return _symbol; } set { _symbol = value; } } 2. Cree una nueva propiedad denominada Price. [Visual Basic] Public Property Price() As Double Get Return _price End Get Set(ByVal value As Double) _price = value End Set End Property [C#] public double Price { get { return _price; } set { _price = value; } } 3. Cree una nueva propiedad denominada Volume. [Visual Basic] Public Property Volume() As Integer Get Return _volume End Get Set(ByVal value As Integer) _volume = value End Set End Property [C#] public int Volume { get { return _volume; } set { _volume = value; } } 4. Por último, cree un constructor nuevo que considere las tres propiedades públicas como argumentos. [Visual Basic] Sub New(ByVal symbol As String, ByVal volume As Integer, ByVal price As Double) _symbol = symbol _volume = volume _price = price End Sub [C#] public Stock (String symbol, int volume, double price) { _symbol = symbol; _volume = volume; _price = price; } 5. En el menú Crear, haga clic en Generar sitio Web. Si existen errores de generación, corríjalos ahora. Ahora podrá acceder a este objeto desde el Crystal Report Designer incrustado. Continúe con Conectar un informe al objeto Stock. Conectar un informe al objeto Stock En esta sección creará un nuevo informe de Crystal en el Crystal Report Designer incrustado y conectará el informe al objeto Stock. Para conectar un informe de Crystal al objeto Stock 1. 2. 3. 4. 5. Haga clic con el botón secundario en el nombre de proyecto y haga clic en Agregar nuevo elemento. En el cuadro de diálogo Agregar nuevo elemento, seleccione Crystal Report. En el campo Nombre, especifique "StockObjects.rpt" y, a continuación, haga clic en Agregar. En el cuadro de diálogo Galería de informes de Crystal, haga clic en Aceptar. En el cuadro de diálogo Asistente para la creación de informes estándar, expanda Datos del proyecto y el subnodo Objetos .NET. Aparecerá una lista de clases dentro del proyecto. Cada clase va precedida del espacio de nombres del proyecto. 6. 7. 8. 9. Expanda la clase Stock para ver un subnodo que se puede seleccionar. Haga clic en la flecha derecha para mover el subnodo de la clase Stock al panel Tablas seleccionadas y, a continuación, haga clic en Siguiente. Expanda Stock y haga clic en el símbolo >> para mover todas las columnas al panel Campos para mostrar y, a continuación, haga clic en Siguiente. Seleccione Symbol y haga clic en la flecha derecha para mover el campo al panel Agrupar por y, a continuación, haga clic en Finalizar. Continúe con Enlazar el informe. Enlazar el informe En Configuración de proyectos, va a colocar un control CrystalReportViewer en el formulario Web Forms o Windows Forms. En el procedimiento anterior, agregó un informe StockObjects al proyecto. En esta sección, enlazará el informe Stock Objects al Visor de informes de Crystal, establecerá el origen de datos del informe en una colección de objetos y rellenerá esta última mediante programación. Para crear una copia del informe StockObjects como informe no incrustado y enlazarla al control CrystalReportViewer 1. 2. Abra la clase Code-Behind predeterminada, Default.aspx.cs o Default.aspx.vb. Encima de la firma de clase, agregue una declaración "Imports" [Visual Basic] o "using" [C#] en la parte superior de la clase para el espacio de nombres System.Collections. [Visual Basic] Imports System.Collections [C#] using System.Collections; Nota Esta referencia le facilita acceso a la clase ArrayList. ArrayList implementa ICollection. Esto cualifica a ArrayListcomo uno de los tipos de clase que se pueden usar para crear una colección de objetos que reconozca Crystal Reports. 3. Agregue una nueva ArrayList de nivel de clase y asígnele el nombre stockValues. [Visual Basic] Private stockValues As ArrayList [C#] private ArrayList stockValues; 4. Agregue una nueva declaración de nivel de clase para la clase contenedora del informe ReportDocument, con el nombre de variablestockObjectsReport. Establezca su modificador de acceso como privado. [Visual Basic] Private stockObjectsReport As ReportDocument [C#] private ReportDocument StockObjectsReport; 5. En el método ConfigureCrystalReports() que creó en Configuración de proyectos, declare una variable de cadena, asígnele el nombrereportPath y una ruta de tiempo de ejecución al informe local. Pase el nombre del archivo de informe local como un parámetro de cadena en el método Server.MapPath(). El informe local se asigna a la ruta de archivo en tiempo de ejecución. [Visual Basic] Dim reportPath As String = Server.MapPath("StockObjects.rpt") [C#] string reportPath = Server.MapPath("StockObjects.rpt"); 6. Agregue dos saltos de línea y cree una instancia de la clase ReportDocument. [Visual Basic] stockObjectsReport = New ReportDocument() [C#] stockObjectsReport = new ReportDocument(); 7. En la línea siguiente, llame el método Load() de la instancia ReportDocument y páselo a la variable de cadena reportPath. [Visual Basic] stockObjectsReport.Load(reportPath) [C#] stockObjectsReport.Load(reportPath); Nota La clase ReportDocument forma parte del espacio de nombres CrystalDecisions.CrystalReports.Engine. Al crear una instancia de ReportDocument y cargar un informe, tendrá acceso al informe a través del SDK. 8. A continuación, establezca el origen de datos del informe en stockValues ArrayList. [Visual Basic] stockObjectsReport.SetDataSource(stockValues) [C#] stockObjectsReport.SetDataSource(stockValues); 9. Por último, enlace la propiedad ReportSource de CrystalReportViewer a la instancia de ReportDocument. [Visual Basic] myCrystalReportViewer.ReportSource = stockObjectsReport [C#] crystalReportViewer.ReportSource = stockObjectsReport; En este punto, el informe Stock Objects está enlazado al Visor de informes de Crystal y la página muestra el informe correcto; sin embargo, el informe está actualmente enlazado a un origen de datos vacío por lo que no dispone de información que mostrar. En la sección siguiente, rellenará mediante programación stockValues ArrayList con datos de muestra. Continúe con Rellenar la colección de objetos mediante programación. Rellenar la colección de objetos mediante programación En esta sección, agregará Session code a la clase de código subyacente ASPX. Si actualmente no hay ningún valor vigente en la sesión, se crearán valores predeterminados. Si hay valores en la sesión, éstos se asignarán a stockValues ArrayList. 1. 2. Haga clic con el botón secundario en el formulario Web del Explorador de soluciones y haga clic en Ver código. En la clase, agregue un nuevo método de ayuda de ámbito público sin valor de devolución, denominado PopulateStockValuesArrayList(). [Visual Basic] Public Sub PopulateStockValuesArrayList() End Sub [C#] public void PopulateStockValuesArrayList() { } 3. En el método PopulateStockValuesArrayList(), delante del código existente, cree un bloque condicional if/else que compruebe si existe un objeto Session denominado stockValues. [Visual Basic] If (Session("stockValues") Is Nothing) Then Else End If [C#] if(Session["stockValues"] == null) { } else { } 4. En el bloque If, cree una nueva instancia de ArrayList() [Visual Basic] stockValues = New ArrayList [C#] stockValues = new ArrayList(); 5. A continuación, utilice el constructor sobrecargado para la clase Stock y cree tres instancias de Stock. [Visual Basic] Dim s1 As Stock = New Stock("AWRK", 1200, 28.47) Dim s2 As Stock = New Stock("CTSO", 800, 128.69) Dim s3 As Stock = New Stock("LTWR", 1800, 12.95) [C#] Stock s1 = new Stock("AWRK",1200,28.47); Stock s2 = new Stock("CTSO",800,128.69); Stock s3 = new Stock("LTWR",1800,12.95); 6. Agregue estas tres instancias a stockValues. [Visual Basic] stockValues.Add(s1) stockValues.Add(s2) stockValues.Add(s3) [C#] stockValues.Add(s1); stockValues.Add(s2); stockValues.Add(s3); 7. Agregue a la sesión los stockValues ArrayList actualizados. [Visual Basic] Session("stockValues") = stockValues [C#] Session["stockValues"]=stockValues; 8. En el bloque Else, escriba una línea para asignar los valores actuales vigentes en la sesión a stockValues ArrayList. [Visual Basic] stockValues = Ctype(Session("stockValues"), ArrayList) [C#] stockValues = (ArrayList)Session["stockValues"]; 9. Por último, llame PopulateStockValuesArrayList() desde el método ConfigureCrystalReports(). Debe ser la primera línea de código que se ejecute en el método ConfigureCrystalReports(). [Visual Basic] PopulateStockValuesArrayList() [C#] PopulateStockValuesArrayList(); Para probar la carga del informe StockObjects 1. 2. 3. En el menú Crear, seleccione Generar solución. Si existen errores de generación, continúe y corríjalos ahora. En el menú Depurar, haga clic en Iniciar depuración. Nota Si es la primera vez que ha iniciado la depuración, aparecerá un cuadro de diálogo en el que se indica que el archivo Web.config se debe modificar. Haga clic en el botón Aceptar para habilitar la depuración. Si no aparecen errores de generación, se cargará la página Default.aspx en el explorador con los tres valores predeterminados. 4. Vuelva a Visual Studio y haga clic en Detener para salir del modo de depuración. Continúe con Rellenar dinámicamente la colección de objetos. Rellenar dinámicamente la colección de objetos En la sección anterior, rellenó la colección de objetos mediante programación. En esta sección, aprenderá a agregar información dinámicamente al origen de datos desde su sitio Web. Esta información se actualizará dinámicamente en el informe. Para agregar controles al formulario Web En esta sección, agregue los controles al formulario Web necesarios para actualizar dinámicamente la colección de objetos. 1. Abra el archivo Default.aspx en la vista Diseño. Nota Para abrir una página ASPX en la vista de diseño, primero abra el archivo y después, haga clic en el botón Diseño situado en la parte inferior del formulario. 2. 3. 4. 5. 6. 7. 8. 9. Haga clic en el control CrystalReportViewer para seleccionarlo. Presione la flecha izquierda del teclado para que aparezca un cursor que parpadea y, a continuación, presione Intro varias veces. En Cuadro de herramientas, arrastre un control TextBox al formulario Web. En el menú Propiedad, establezca el valor de ID en "symbol". Arrastre un segundo control TextBox en el formulario Web. Coloque el segundo TextBox debajo del primero. En el menú Propiedad, establezca el valor de ID en "price". Arrastre un tercer control TextBox en el formulario Web. Coloque el tercer TextBox debajo del segundo. En el menú Propiedad, establezca el valor de ID en "volume". Nota En este punto, puede resultar útil agregar texto junto a cada control TextBox para identificar el control correspondiente a cada parámetro. 10. A continuación, desde Cuadro de herramientas, arrastre un control Button en el formulario Web. Coloque el botón debajo de los tres controlesTextBox. 11. En el menú Propiedad: Establezca el ID del control Button en "addStockInformation". Establezca el texto de Button en "Add Stock Information". 12. Por último, haga doble clic en el botón "Add Stock Information". Al hacer doble clic en el control Button, se abrirá la clase Code-behind y se generará automáticamente un controlador de eventosaddStockInformation_Click(). Para agregar información a la colección En esta sección, escribirá el código para el controlador de eventos addStockInformation_Click() que agregará la información introducida en el formulario Web a la colección stockValues. 1. En el controlador de eventos addStockInformation_Click(), cree una nueva instancia de un objeto Stock. [Visual Basic] Dim temp As Stock = New Stock() [C#] Stock temp = new Stock(); 2. Dentro del método addStockInformation_Click(), cree un bloque try/catch. [Visual Basic] Try Catch ex As Exception End Try [C#] try { } catch { } La información introducida en un formulario Web es de tipo cadena. Debido a que dos de los campos de la clase Stock son numéricos, tendrá que escribir el código para convertir los valores de cadena del formulario Web en valores numéricos. El enunciado try/catch permite proteger la aplicación Web de interrupciones bruscas del sistema durante la conversión debido a errores de incompatibilidad de tipo. 3. En el bloque Try, asigne el valor del campo de símbolo en el formulario Web a la propiedad Symbol del objeto Stock. [Visual Basic] temp.Symbol = symbol.Text [C#] temp.Symbol = symbol.Text; 4. En la línea siguiente, asigne el valor del campo de precio en el formulario Web a la propiedad Price del objeto Stock. Convierta el valor del formulario Web en Double antes de la asignación. [Visual Basic] temp.Price = CType(price.Text, Double) [C#] temp.Price = Convert.ToDouble(price.Text); 5. A continuación, asigne el valor del campo de volumen en el formulario Web a la propiedad Volume del objeto Stock. Convierta el valor del formulario Web en un número entero antes de la asignación. [Visual Basic] temp.Volume = CType(volume.Text, Integer) [C#] temp.Volume = Convert.ToInt32(volume.Text); 6. Fuera del bloque try/catch, agregue el objeto Stock a stockValues ArrayList. [Visual Basic] stockValues.Add(temp) [C#] stockValues.Add(temp); 7. Actualice el valor stockValues actualmente vigente en la sesión. [Visual Basic] Session("stockValues") = stockValues [C#] Session["stockValues"] = stockValues; 8. Por último, llame al método ConfigureCrystalReports(). El informe se enlazará de nuevo a la colección de objetos stockValues actualizada. [Visual Basic] ConfigureCrystalReports() [C#] ConfigureCrystalReports(); 9. En el menú Crear, haga clic en Generar solución. Si existen errores de generación, corríjalos ahora. 10. En el menú Depurar, haga clic en Iniciar depuración. Si no aparecen errores de generación, se cargará la página Default.aspx en el explorador con los tres valores predeterminados. Para agregar valores adicionales, rellene los controles TextBox Controls como corresponda y haga clic en el botón Add Stock Information. El informe se actualizará dinámicamente. Al ejecutar el sitio Web, el informe se cargará en la ventana del explorador con los tres valores predeterminados que agregó mediante programación enRellenar la colección de objetos mediante programación. Encima del informe aparecen tres controles TextBox y un control Button. Mediante estos controles, puede actualizar dinámicamente la colección de objetos y ver el resultado de esta actualización reflejada en el informe. Continúe con Conclusión. Tutorial: Conectar a colecciones de objetos: Conclusión Ha creado una clase única para mantener los valores del mercado de cotizaciones, ha creado una instancia de la clase, ha rellenado una colección de objetos con datos y ha agregado de manera dinámica datos adicionales a través de un formulario Web. Después, ha creado un informe de Crystal con el control Crystal Report Designer que se conectó a la colección de objetos y generó dinámicamente un gráfico y resumen de cotizaciones. Las colecciones de objetos son orígenes de datos versátiles para los informes de Crystal. Con una colección de objetos, puede escribir una clase personalizada que rellena un objeto con datos mediante programación o dinámicamente. Las colecciones de objetos se pueden utilizar también para ampliar el número de orígenes de datos que se facilitan con una instalación predeterminada de Crystal Reports para Visual Studio permitiéndole escribir sus propios objetos de acceso a datos. Para aprender más sobre el uso de una colección de datos en un informe, continúe con Apéndice: Mejorar el informe. Continúe con Información de código de ejemplo. Generate a Report using Crystal Reports in Visual Studio 2010 Introduction I was searching the internet for Crystal reports in 2010 and I found in 2005, but was not able to find any particular tutorials for 2010. So I thought, let me take a chance to write it for some beginners like me who have not worked on Crystal Reports earlier. In this article, I will show you simple report creation process with screenshots. A picture is worth more than a thousand words, so I always believe in an article with screenshots. Let's start by creating a new website in VS2010. See the following screen: Figure 1 As per figure 1, create a new website in VS2010 and name it as per your choice. Now let me show you the database table structure. Figure 2 The above figure shows the db table structure. And the below figure (Figure 3) will show you some sample data in the table: Figure 3 If you want to run this sample project directly, then you can download the database script from the link at the top. Now we have to create an xsd file as a blank data source as we are going to use strong data type. Here I will divide this tutorial in 5 sub sections as mentioned below: Simple report using Crystal Reporting Tool Group report Chart report Sub report Cross tab report Simple Report using Crystal Report The below figure shows you the process to create an XSD file. For adding an XSD file, click on Solution Explorer -> Right Click on Project -> click on Add new Item and then it will show you the below screen. Figure 4 Click on the ok button, so it will ask for confirmation to put that file in App_Code folder. Just click ok and that file will open in the screen as a blank screen. Now we will add one blank datatable to that XSDfile. Just right click on the file and select Add -> Datatable. It will add one DataTable1 to the screen. Figure 5 shows how to add datatable to XSD file. Figure 5 Now datatable1 is added to XSD file. Now we will add data column to the datatable1 as per figure 6. Remember whatever fields (columns) we add here, it will be available to show on the report. So add column which you want to display in your reports one by one here. Figure 6 Remember to give the exact same name for data column as in database and also select data type which is the same as database, otherwise you will get an error for field and data type mismatch. Once we add all the required columns in datatable, then set property for the datacolumn as it has in database. The below figure will show you how to set property for data columns. Default datatype for all the columns is string here so if datatype is other than string then only change it manually. Just right click on the datacolumn in datatable and select property and from property window, select appropriatedatatype from DataType Dropdown for that datacolumn. Figure 7 That's it. XSD file creation has been done. Now we will move to create Crystal report design. Just click on the Solution Explorer -> Right click on the project name and select crystal reports. Name it as per your choice and hit the add button. Figure 8 will show you the creation process of Crystal reports. Figure 8 Click on the add button and one .rpt file will be added to the solution. And also, it will ask for the report creation type of how you want to create the report. Figure 9 will show you a screenshot. Figure 9 Just click ok button to proceed. It will lead you to figure 10: Figure 10 Under project data, expand ADO.NET Datasets and select DataTable1 and add to the selected table portion located at the right side of the windows using > button. Now click on the Finish button and it will show the next screen (Figure 11): Figure 11 Once report file is added, you can see Field Explorer on the left side near server explorer. Expand Database Fields, under that you will be able to find Datatable that we have created earlier. Just expand it and drag one by one filed from Field Explorer to the rpt file under detail section. Now the report design part is over. Now we have to fetch the data from database and bind it to dataset and then bind that dataset to the report viewer. Let's go step by step. First Drag a CrystalReportViewer control on aspx page from tool box as per below screen: Figure 12 Now we will fetch the data, pass data to the dataset and then add that dataset to the Crystal Report. Below is the C# code which will do the job: Collapse | Copy Code using using using using using CrystalDecisions.CrystalReports.Engine; CrystalDecisions.Shared; System.Data; System.Data.SqlClient; System.Configuration; Below is the final code for reports: Collapse | Copy Code protected void Page_Load(object sender, EventArgs e) { ReportDocument rptDoc = new ReportDocument(); dsSample ds = new dsSample(); // .xsd file name DataTable dt = new DataTable(); // Just set the name of data table dt.TableName = "Crystal Report Example"; dt = getAllOrders(); //This function is located below this function ds.Tables[0].Merge(dt); // Your .rpt file path will be below rptDoc.Load(Server.MapPath("../Reports/SimpleReports.rpt")); //set dataset to the report viewer. rptDoc.SetDataSource(ds); CrystalReportViewer1.ReportSource = rptDoc; } public DataTable getAllOrders() { //Connection string replace 'databaseservername' with your db server name string sqlCon = "User ID=sa;PWD=sa; server=databaseservername;INITIAL CATALOG=SampleDB;" + "PERSISTSECURITY INFO=FALSE;Connect Timeout=0"; SqlConnection Con = new SqlConnection(sqlCon); SqlCommand cmd = new SqlCommand(); DataSet ds = null; SqlDataAdapter adapter; try { Con.Open(); //Stored procedure calling. It is already in sample db. cmd.CommandText = "getAllOrders"; cmd.CommandType = CommandType.StoredProcedure; cmd.Connection = Con; ds = new DataSet(); adapter = new SqlDataAdapter(cmd); adapter.Fill(ds, "Users"); } catch (Exception ex) { throw new Exception(ex.Message); } finally { cmd.Dispose(); if (Con.State != ConnectionState.Closed) Con.Close(); } return ds.Tables[0]; } Now just save everything and run report. It will look like the below figure: Figure 13 Grouping in Crystal Report Here we will see only report design and rest of the things, you can refer from Section 1. Here we will groupCustomer, Product, Order and Quantity. For details, just go through Figure 14. Just add a report (.rpt) file to the solution. Select the appropriate dataset from popup window. Once it's done, then select grouping option like figure 14. Figure 14 Now, right click on the report, select Report -> Group Experts and the resulting window will look like figure 15: Figure 15 Now we want to group like Customer Name and Product name so first add Customer to the right Panel. Then move product name to the right panel like figure 16: Figure 16 This time Crystal report design will be different than the previous time. See figure 17. GroupHeaderSection1 and GroupHeaderSection2 are added to the report designer. Here Group #1 Name refers to Customer Name and Group #2 Name refers to Product Name. And also GroupFooterSection1 and GroupFooterSection2 are added below if you want to add something to group footer. Figure 17 Now under every group, we want to show the number of orders per customer and productwise, so for that, we have to add summary to the GroupFooterSection2. Refer to Figure 18. Figure 18 Right Click on the GroupFooterSection select Insert -> Summary. It will show you the next screen (Figure 19). And I have also added Order_ID and Product_Qty field to the detail (section 3) part. Figure 19 In summary window, select the column which you want to summarize in the first dropdown. Select Sum (First option) from the calculate drop down. Summary Location is already set to the report footer. So just click ok to place that summary field to the report. By default, Summary field is added to the Report Footer section so move it to the groupFooterSection2 if you want to group product wise, move it to the GroupFooterSection1 if you want to group Customer wise or keep it at original place if you want to sum all ordered products. I have moved to the FooterSection1 so it will show Customer Wise Total Quantity. Refer to Figure 20. Figure 20 Now save the report and run it finally. It looks like figure 21. Figure 21 Chart in Crystal Report Chart is the most important and visible part of the reporting tool. Crystal has very powerful feature to add chart in report. Let's see how to add chart in CR. Here also, we will see only designing of the chart for other thing. Please refer to Section 1. Here we will show customer wise product ordered quantity in chart. X portion will display Customer name and Y portion will display customers total ordered quantity. First add charts to the report design. Right click on the .rpt file and select Insert->Chart. Refer to figure 22. Figure 22 Once you add chart to the report, it will not show chart on the report file but with mouse pointer you can see one blank rectangle is moving. So just click on the Report header. It will open popup for chart style and other options. Refer to figure 23. Figure 23 Now from type tab, select type of the charts like bar chart, line chart, pie chart, etc. form the left side. Select sub type from the right pane like side by side chart, percentage bar chart, etc. I am not going into the detail of it. I am leaving it for you to practice work. And also select vertical or horizontal radio button from the below section if you want to change the chart style vertically or horizontally. Check Use depth effect check box if you need shadow effect on the graph. Refer to figure 23. Figure 24 As per figure 24, move to the next tab data. There are three boxes, available fields, on change of and show values. So move Customer Name from available fields to on changes of box, and move Product Quantity filed to the show value box and click ok. Now you can see chart is added to the report header section as per figure 25. Figure 25 Now, just save the report and run it. You can see a Report as a chart on the screen. Report Inside Report (Sub Report) Crystal reports provide reports inside report feature which are normally known as a subreport feature. Let me explain it in detail. Here also, we will design only sub report design. For rest of the things, refer to Section 1. Add new report to the solution. Then add Report->Group and select only Customer name because we want to design report for each customer and sub report product wise. So there will be only one group header inside theCustomergroup header as per figure 26. Figure 26 Now right click on Detail section and select Insert->Subreport. Refer to figure 27. Figure 27 Once we add subreport, it will show screen like figure 28. Figure 28 As per figure 28, by default, choose a Crystal Report in project is selected if you want to add report from the project, then otherwise select create a subreport with the report wizard. Once we select create a subreport with Report Wizard (3rd radio button), we have to click on the Report Wizard button to select report type and data source just do as Part - 1 first. Then click on ok button so like chart report it will show a moving rectangle around mouse, click on the detail section where you want to show subreport. Now to edit the sub report, refer to figure 29. Figure 29 Click on the edit subreport option and format the report as per your need. Here I will suggest add product name and product quantity or you can add chart also for sub report. When you click on the subreport button, it will open subreport designer, actually CR will create a separate .rpt file but it will remain hidden inside the main .rpt file so we can't see it.. Now run the report and you can see the result, report inside report like figure 30. Figure 30 Here number 1 is the main report and number 2 is the subreport it's showing title as Product wise. Cross Tab Report in Crystal Report First, let me make it clear as to what is a Cross tab report. Normally, we generate report row wise like first we show customer name, then product wise, etc. But suppose we want to see report as column wise like product name should be displayed as column in report, then cross tab report comes into the picture. See result of Cross Tab report in figure 31. Figure 31 Here also, I will show how to design cross tab report only, for rest of the things, refer to Section 1. First add .rpt file to the solution. Then add cross report to the Report Header section as per the below figure (Refer to figure 32). Remember we can add cross tab report only in Report header or report footer section. Figure 32 Once we click on cross tab report options, it will show moving rectangle around mouse pointer just place it to the report header section. As we click on header section, it will lead to the figure 33. Figure 33 As per the figure, move Customer name field to the Rows section, Product name we want to show as a Column so move it to the Columns fields, and we want to show product total so move it to the summarized fields. That's it. Just run the report and you can see the output as shown in figure 31. It's as simple as that. If you have any queries regarding any type of the above mentioned reports, please let me know by way of comments. I will try my level best to fulfill your request. Let's enjoy reporting!