Explicaremos como crear un reporte Web en Crystal Report de tipo Master/Detail o Cabecera/Detalle. En este ejemplo tendremos en la cabecera una Orden de Compra con datos, como: Número de Orden, fecha en que fue realizada, cliente, medio de envío; y en el Detalle tendremos los productos que fueron pedidos en la Orden de Compra, así como su precio respectivo.
Necesitaremos la base de datos Northwind y Visual Studio 2005 ó 2008.
Paso 1.- En SLQ SERVER ejecutar el siguiente código:
USE NORTHWIND; GO CREATE PROC OrdenMaestro @OrderID INT AS SELECT Orders.OrderID, Customers.ContactName, Customers.Address, Customers.City, CONVERT(NVARCHAR(12),Orders.OrderDate,103)AS Date, Shippers.CompanyName, (Employees.LastName+', '+Employees.FirstName)AS FullName, CONVERT(NVARCHAR(12),Orders.RequiredDate,103)AS [Fecha Requerida] FROM Orders INNER JOIN Employees on Orders.EmployeeID = Employees.EmployeeID INNER JOIN Customers ON Customers.CustomerID = Orders.CustomerID INNER JOIN Shippers ON Shippers.ShipperID = Orders.ShipVia WHERE Orders.OrderID= @OrderID CREATE PROC OrdenMaestro @OrderID INT AS SELECT Orders.OrderID, Customers.ContactName, Customers.Address, Customers.City, CONVERT(NVARCHAR(12),Orders.OrderDate,103)AS Date, Shippers.CompanyName (Employees.LastName+', '+Employees.FirstName)AS FullName, CONVERT(NVARCHAR(12),Orders.RequiredDate,103)AS [Fecha Requerida] FROM Orders INNER JOIN Employees on Orders.EmployeeID = Employees.EmployeeID INNER JOIN Customers ON Customers.CustomerID = Orders.CustomerID INNER JOIN Shippers ON Shippers.ShipperID = Orders.ShipVia WHERE Orders.OrderID= @OrderID
Lo que hace el código SQL anterior es crear un Store Procedure que recibirá un número de orden determinado (parámetro de entrada) para así ver los datos de dicha orden.
.
Ahora el siguiente código crea un Store Procedure que mostrará los productos que fueron solicitados en la Orden.
USE NORTHWIND; GO CREATE PROC OrdenDetalle AS SELECT [Order Details].OrderID, Products.ProductName,Total=ROUND(([order details].UnitPrice*[order details].Quantity)-([order details].UnitPrice*[order details].Quantity)*[order details].Discount,2) ,[Order Details].Quantity,[Order Details].Discount FROM [Order Details] INNER JOIN Products ON [Order Details].ProductID = Products.ProductID
Paso 2.- Bien una vez creados los dos procedimientos almacenados, vamos al Visual Studio, y creamos un nuevo sitio Web.
Agregaremos un clase llamada “Conexion”:
Hacemos clic en “SI” cuando nos salga el siguiente mensaje:
En la clase Conexion.cs agregaremos el siguiente código:
public class Conexion
{
private string servidor = "NOMBREDETUSERVIDORSQL";
private string basededatos = "Northwind";
private string usuario = "TUUSUARIO";
private string password = "";
public string Usuario
{
get { return usuario; }
set { usuario = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public string Basededatos
{
get { return basededatos; }
set { basededatos = value; }
}
public string Servidor
{
get { return servidor; }
set { servidor = value; }
}
}
Paso 5.- Expandimos hasta OLEDB.
Paso 6.- Se abrirá la siguiente pantalla:
Paso 7.- Damos la información de nuestra conexión y damos clic en finalizar.Paso 8.- Ahora buscamos nuestro Store Procedure “OrdenMaestro” y lo ponemos en la derecha, al hacer esto nos aparecerá una ventana para darle un valor al parámetro, damos clic en aceptar y luego siguiente:
Paso 9.- Pasamos todos los campos que queremos que se muestren, en este caso pasaré todos, luego presionamos finalizar.
Bien se creará el reporte:
Paso 10.- Alargamos el espacio de “Detalles” y hacemos clic derecho y agregamos un Subinforme
Paso 11.- Cuando agreguemos el Subinforme se abrirá la siguiente ventana, agregamos un nombre y hacemos clic en: “Asistente de Informes”:
Paso 12.- Se abrirá una nueva ventana, en ésta buscaremos nuestro segundo Store Procedure llamado: “OrdenDetalle”:
Paso 13.- En el siguiente paso arrastramos a la derecha los campos que, queremos que se muestren y ponemos finalizar:
Paso 14. Hacemos clic en ACEPTAR y el SubInforme se agregará a nuestro reporte principal:
Paso 15.- Bien ahora tenemos que hacer algo muy importante:
Tenemos que enlazar los dos reportes, deben tener claro que cada uno de los Store Procedure tienen relación; es decir, la cabecera poseé un campo llamado OrdenID y el segundo Store Procedure también poseé dicho campo; necesitamos esto para mostrar los datos de la Orden y en el detalle tienen que mostrarse solamente los detalles de dicha orden. Entonces vamos a enlazar los reportes de la siguiente manera:
- Hagamos clic Derecho en el SubReport, y seleccionamos “Cambiar vínculos del subinforme”.
- Ahora buscamos el campo OrdenID de nuestro reporte principal y hacemos clic en el botón “>”, ponemos aceptar.
Paso 16.- Agregaremos un componente CrystalReportViewer, un label, textbox y un botón:
Paso 17.- Hagamos doble clic en el botón y agreguemos el siguiente código:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
//Referencias
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using CrystalDecisions.ReportSource;
public partial class _Default : System.Web.UI.Page
{
ParameterDiscreteValue OrdenIDDV = new ParameterDiscreteValue(); //parametro de entrada
Conexion con = new Conexion();
ReportDocument Report = new ReportDocument();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
string reportPath = Server.MapPath("OrdenReporte.rpt");
Report.Load(reportPath);
Report.DataSourceConnections[0].SetConnection(con.Servidor, con.Basededatos, con.Usuario, con.Password);
int OrdenID = int.Parse(TextBox1.Text);
OrdenIDDV.Value = OrdenID;
Report.SetParameterValue("@OrderID", OrdenIDDV);
CrystalReportViewer1.ReportSource = Report;
}
protected void Button1_Unload(object sender, EventArgs e)
{
Report.Dispose();
CrystalReportViewer1.Dispose();
}
Corremos la página:
Espero les sea útil les dejo el Proyecto.
Buen Día.








Muchas gracias por la informacion
hola ri#, una consulta a mi me sale error al momento de la carga del reporte :S, en estas dios lineas:
string reportPath = Server.MapPath(“Mi reporte.rpt”);
Report.Load(reportPath);
Parece error de referencias. Has agregado estas referencias?
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using CrystalDecisions.ReportSource;
si claro.. parece como si no encontrara el reporte dentro del proyecto.. me da un error SystemNullReferenceException, sin embargo agrege un dataset.. y si me cargo xD