Está en la página 1de 56

C# - APLICACIN DE ESCRITORIO, SISTEMAS DE VENTAS PARTE I - CREACIN DE LA BASE DATO

S
1. ENTORNO
SQL Server 2008 Visual Studio 2008
2. INTRODUCCIN
En el siguiente tutorial vamos a desarrollar un sistema de ventas usando el leng
uaje de programacin C# y como base de datos vamos a usar el SQL Server 2008 y tam
bien crearemos un reporte con Crystal Report. La base de datos que vamos a crear
es una base de datos con fines didcticos, dado que nos faltara crear mas tablas,
como la tabla cliente, categora, unidad de medida, etc pero si nos explayamos muc
ho nos quedara muy largo el tutorial. Ademas en el ejemplo no se explica como dis
minuir un stock, debido a que eso siempre se les pide a los alumnos universitari
o que investiguen como hacerlo, pero si quieren una ayudita lo pueden hacer crea
ndo Triggers en la base de datos.
3. DESARROLLO
En esta primera parte del tutorial vamos a crear la base de datos en SQL Server
2008, la base de datos se llamara BDTutorial 3.1. Diseo de la base de datos La ba
se de datos tendra las siguientes tablas: Venta, Producto y DetalleVenta

Ademas la columna "codigoVenta" de la tabla "Venta" tiene un valor de identidad,


eso quiere decir que su valor es auto incremental que comienza en uno e increme
nta de uno en uno.

Lo mismo sucedera con la columna "codigoProducto" de la tabla Producto


3.2. Creando los procedimientos almacenados

Segn Wikipedia un procedimiento almacenado (stored procedure en ingls) es un progr


ama (o procedimiento) el cual es almacenado fsicamente en una base de datos. Su i
mplementacin vara de un manejador de bases de datos a otro. La ventaja de un proce
dimiento almacenado es que al ser ejecutado, en respuesta a una peticin de usuari
o, es ejecutado directamente en el motor de bases de datos, el cual usualmente c
orre en un servidor separado. Como tal, posee acceso directo a los datos que nec
esita manipular y slo necesita enviar sus resultados de regreso al usuario, desha
cindose de la sobrecarga resultante de comunicar grandes cantidades de datos sali
entes y entrantes. 3.2.1. Procedimientos Almacenados para la tabla Producto /* --------------------------------------------------CREADO: POR :HENRY JOE WONG UR
QUIZA FECHA:22FEB2011 PROCEDIMIENTO ALMACENADO UTILIZADO PARA INSERTAR UN PRODUC
TO A LA BASE DE DATOS ---------------------------------------------------*/ CREA
TE PROC dbo.spI_Producto @codigoProducto int = Null OUTPUT, @nombre varchar(100)
= Null, @precio decimal(18, 2) = Null AS insert into Producto ( nombre, precio
) VALUES( @nombre, @precio ) --Obteniendo el codigo autogenerado de producto SET
@codigoProducto = @@IDENTITY; GO /* --------------------------------------------------CREADO: POR :HENRY JOE WONG URQUIZA FECHA:22FEB2011 PROCEDIMIENTO ALMACE
NADO UTILIZADO PARA ACTUALIZAR UN PROCEDUCTO A LA BASE DE DATOS ---------------------------------------------------

*/ CREATE PROC dbo.spU_Producto @codigoProducto int = Null, @nombre varchar(100)


= Null, @precio decimal(18, 2) = Null AS UPDATE Producto SET nombre = @nombre,
precio = @precio WHERE codigoProducto = @codigoProducto GO /* --------------------------------------------------CREADO: POR :HENRY JOE WONG URQUIZA FECHA:22FEB
2011 PROCEDIMIENTO ALMACENADO UTILIZADO PARA OBTENER TODOS LOS PRODUCTOS DE LA B
ASE DE DATOS ---------------------------------------------------*/ CREATE PROC d
bo.spF_Producto_All AS SELECT p.codigoProducto, p.nombre, p.precio FROM Producto
p ORDER BY P.nombre 3.2.2. Procedimientos Almacenados para la tabla Venta /* --------------------------------------------------CREADO: POR :HENRY JOE WONG URQ
UIZA FECHA:22FEB2011 PROCEDIMIENTO ALMACENADO UTILIZADO PARA INSERTAR UNA VENTA
A LA BASE DE DATOS ---------------------------------------------------*/ CREATE
PROC dbo.spI_Venta

@codigoVenta int = Null OUTPUT, @cliente varchar(100) = Null AS insert into Vent
a ( cliente, fecha ) VALUES( @cliente, GETDATE() ) --Obteniendo el codigo autoge
nerado de la venta SET @codigoVenta = @@IDENTITY GO /* --------------------------------------------------CREADO: POR :HENRY JOE WONG URQUIZA FECHA:22FEB2011 PR
OCEDIMIENTO ALMACENADO UTILIZADO PARA OBTENER EL REPORTE DE LA VENTA DE LA BASE
DE DATOS ---------------------------------------------------*/ CREATE PROCEDURE
dbo.spF_Venta_One @codigoVenta int AS SELECT v.codigoVenta AS CodigoVenta, v.cli
ente AS Cliente, v.fecha AS Fecha, d.codigoProducto AS CodigoProducto, p.nombre
AS Nombre, p.precio AS Precio, d.cantidad AS Cantidad, d.descuento AS Descuento,
p.precio*d.cantidad AS Parcial, ((p.precio*d.cantidad)-d.descuento) AS SubTotal
, ( SELECT SUM((dT.cantidad * pT.precio)-dT.descuento) AS TotalPagar FROM Detall
eVenta AS dT INNER JOIN Producto AS pT ON dT.codigoProducto = pT.codigoProducto

WHERE dT.codigoVenta=v.codigoVenta ) AS TotalPagar FROM Venta AS v INNER JOIN De


talleVenta AS d ON v.codigoVenta = d.codigoVenta INNER JOIN Producto AS p ON d.c
odigoProducto = p.codigoProducto WHERE v.codigoVenta=@codigoVenta ORDER BY Nombr
e GO /* ---------------------------------------------------CREADO: POR :HENRY JO
E WONG URQUIZA FECHA:22FEB2011 PROCEDIMIENTO ALMACENADO UTILIZADO PARA OBTENER T
ODAS LAS VENTAS DE LA BASE DE DATOS --------------------------------------------------*/ CREATE PROCEDURE dbo.spF_Venta_All AS SELECT v.codigoVenta AS CodigoVe
nta, v.cliente AS Cliente, v.fecha AS Fecha, d.codigoProducto AS CodigoProducto,
p.nombre AS Nombre, p.precio AS Precio, d.cantidad AS Cantidad, d.descuento AS
Descuento, p.precio*d.cantidad AS Parcial, ((p.precio*d.cantidad)-d.descuento) A
S SubTotal, ( SELECT SUM((dT.cantidad * pT.precio)-dT.descuento) AS TotalPagar F
ROM DetalleVenta AS dT INNER JOIN Producto AS pT ON dT.codigoProducto = pT.codig
oProducto WHERE dT.codigoVenta=v.codigoVenta ) AS TotalPagar FROM

Venta AS v INNER JOIN DetalleVenta AS d ON v.codigoVenta = d.codigoVenta INNER J


OIN Producto AS p ON d.codigoProducto = p.codigoProducto ORDER BY CodigoVenta, N
ombre 3.2.3. Procedimientos Almacenados para la tabla DetalleVenta /* --------------------------------------------------CREADO: POR :HENRY JOE WONG URQUIZA FEC
HA:22FEB2011 PROCEDIMIENTO ALMACENADO UTILIZADO PARA INSERTAR UN DETALLE DE VENT
A A LA BASE DE DATOS ---------------------------------------------------*/ CREAT
E PROC dbo.spI_DetalleVenta @codigoVenta int = Null, @codigoProducto int = Null,
@cantidad decimal(18, 2) = Null, @descuento decimal(18, 2) = Null AS insert int
o DetalleVenta ( codigoVenta, codigoProducto, cantidad, descuento ) VALUES( @cod
igoVenta, @codigoProducto, @cantidad, @descuento )
C# - APLICACIN DE ESCRITORIO, SISTEMAS DE VENTAS PARTE II - CREACIN DE LA CAPA DE
DATOS
1. ENTORNO
SQL Server 2008


Visual Studio 2008
2. INTRODUCCIN
2.1. Programacin por capas La programacin por capas es un estilo de programacin en
el que el objetivo primordial es la separacin de la lgica de negocios de la lgica d
e diseo. La ventaja principal de este estilo es que el desarrollo se puede llevar
a cabo en varios niveles y, en caso de que sobrevenga algn cambio, slo se ataca a
l nivel requerido sin tener que revisar entre cdigo mezclado. Un buen ejemplo de
este mtodo de programacin sera el modelo de interconexin de sistemas abiertos 2.2. P
rogramacin en tres capas Capa de presentacin: es la que ve el usuario (tambin se la
denomina "capa de usuario"), presenta el sistema al usuario, le comunica la inf
ormacin y captura la informacin del usuario en un mnimo de proceso (realiza un filt
rado previo para comprobar que no hay errores de formato). Esta capa se comunica
nicamente con la capa de negocio. Tambin es conocida como interfaz grfica y debe t
ener la caracterstica de ser "amigable" (entendible y fcil de usar) para el usuari
o. Capa de negocio: es donde residen los programas que se ejecutan, se reciben l
as peticiones del usuario y se envan las respuestas tras el proceso. Se denomina
capa de negocio (e incluso de lgica del negocio) porque es aqu donde se establecen
todas las reglas que deben cumplirse. Esta capa se comunica con la capa de pres
entacin, para recibir las solicitudes y presentar los resultados, y con la capa d
e datos, para solicitar al gestor de base de datos para almacenar o recuperar da
tos de l. Tambin se consideran aqu los programas de aplicacin. Capa de datos: es don
de residen los datos y es la encargada de acceder a los mismos. Est formada por u
no o ms gestores de bases de datos que realizan todo el almacenamiento de datos,
reciben solicitudes de almacenamiento o recuperacin de informacin desde la capa de
negocio.

3. DESARROLLO
3.1. Creando el proyecto Primero debemos de crear un proyecto con Visual Studio
2008, para eso abrimos el Visual Studio 2008 y nos vamos al men de "Archivo-->Nue
vo Proyecto". A nuestro proyecto le pondremos de nombre "SistemaVentas"
3.2. Agregando la Capa de Datos Debemos de agregar a nuestro proyecto la capa de
datos, para eso nos vamos al menu de "Archivo-->Agregar Nuevo Proyecto"
Y le pondremos como nombre "CapaDatos"

3.3. La clase Conexion Para agregar una clase en C# debemos hacer clic derecho e
n la Capa de Datos y seleccionar la opcin "Agregar-->Clase" y la clase que creamo
s se llamara "Conexion", que se encargara de guardar la cadena de conexin para po
der conectarnos con nuestra base de datos que esta en SQL Server 2008 y la cual
se llama BDTutorial.

La clase Conexion tendr el siguiente cdigo en C# using using using using System; S
ystem.Collections.Generic; System.Linq; System.Text;
//Desarrollado por Henry Joe Wong Urquiza namespace CapaDatos { public class Con
exion { //La base de datos se llama BDTutorial //La ubicacion de base de datos e
sta de modo local y en una instancia que se llama SQL2008 //Utiliza seguridad in
tegrada para conectarse a la base de datos public static string cn = "Data Sourc
e=.\\SQL2008;Initial Catalog=BDTutorial;Integrated Security=True"; } } 3.2. La c
lase Producto Esta clase se encarga de conectar la tabla Producto con C# using S
ystem; using System.Collections.Generic; using System.Text; //Impotaciones neces
arias

using System.Data; using System.Data.SqlClient; //Desarrollado por Henry Joe Won


g Urquiza namespace CapaDatos { public class Producto { private int var_codigoPr
oducto; private string var_nombre; private decimal var_precio; //Constructor vac
io public Producto() { } //Constructor con parametros public Producto( int codig
oProducto, string nombre, decimal precio ) { this.var_codigoProducto = codigoPro
ducto; this.var_nombre = nombre; this.var_precio = precio; } //Metodo utilizado
para insertar un Producto public string Insertar(Producto varProducto) { string
rpta = ""; SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la
cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Abrir la conexion
de la BD sqlCon.Open(); //3. Establecer el comando SqlCommand sqlCmd = new SqlC
ommand(); sqlCmd.Connection = sqlCon;

sqlCmd.CommandText = "spI_Producto"; sqlCmd.CommandType = CommandType.StoredProc


edure; //4. Agregar los parametros al comando //Establecemos los valores para el
parametro @codigoProducto del Procedimiento Almacenado SqlParameter sqlParcodig
oProducto = new SqlParameter(); sqlParcodigoProducto.ParameterName = "@codigoPro
ducto"; sqlParcodigoProducto.SqlDbType = SqlDbType.Int; //Le declaramos que el p
arametro es de salida, porque obtendremos el codigo generado por la base de dato
s sqlParcodigoProducto.Direction = ParameterDirection.Output; sqlCmd.Parameters.
Add(sqlParcodigoProducto); //Agregamos el parametro al comando //Establecemos lo
s valores para el parametro @nombre del Procedimiento Almacenado SqlParameter sq
lParnombre = new SqlParameter(); sqlParnombre.ParameterName = "@nombre"; sqlParn
ombre.SqlDbType = SqlDbType.VarChar; sqlParnombre.Size = 100; sqlParnombre.Value
= varProducto.nombre; sqlCmd.Parameters.Add(sqlParnombre); //Agregamos el param
etro al comando //Establecemos los valores para el parametro @precio del Procedi
miento Almacenado SqlParameter sqlParprecio = new SqlParameter(); sqlParprecio.P
arameterName = "@precio"; sqlParprecio.SqlDbType = SqlDbType.Decimal; sqlParprec
io.Precision=18; sqlParprecio.Scale=2; sqlParprecio.Value = varProducto.precio;
sqlCmd.Parameters.Add(sqlParprecio); //Agregamos el parametro al comando //5. Ej
ecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No se insert
o el producto de forma correcta"; } catch (Exception ex) { rpta = ex.Message; }
finally { //6. Cerramos la conexion con la BD

if (sqlCon.State == ConnectionState.Open) sqlCon.Close(); } return rpta; }


//Metodo utilizado para actualizar un Producto public string Actualizar(Producto
varProducto) { string rpta = ""; SqlConnection sqlCon = new SqlConnection(); tr
y { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn;
//2. Abrir la conexion de la BD sqlCon.Open(); //3. Establecer el comando SqlCo
mmand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon; sqlCmd.CommandText
= "spU_Producto"; sqlCmd.CommandType = CommandType.StoredProcedure; //4. Agregar
los parametros al comando //Establecemos los valores para el parametro @codigoP
roducto del Procedimiento Almacenado SqlParameter sqlParcodigoProducto = new Sql
Parameter(); sqlParcodigoProducto.ParameterName = "@codigoProducto"; sqlParcodig
oProducto.SqlDbType = SqlDbType.Int; sqlParcodigoProducto.Value = varProducto.co
digoProducto; sqlCmd.Parameters.Add(sqlParcodigoProducto); //Agregamos el parame
tro al comando //Establecemos los valores para el parametro @nombre del Procedim
iento Almacenado SqlParameter sqlParnombre = new SqlParameter(); sqlParnombre.Pa
rameterName = "@nombre"; sqlParnombre.SqlDbType = SqlDbType.VarChar; sqlParnombr
e.Size = 100; sqlParnombre.Value = varProducto.nombre; sqlCmd.Parameters.Add(sql
Parnombre); //Agregamos el parametro al comando //Establecemos los valores para
el parametro @precio del Procedimiento Almacenado SqlParameter sqlParprecio = ne
w SqlParameter(); sqlParprecio.ParameterName = "@precio"; sqlParprecio.SqlDbType
= SqlDbType.Decimal;

sqlParprecio.Precision = 18; sqlParprecio.Scale = 2; sqlParprecio.Value = varPro


ducto.precio; sqlCmd.Parameters.Add(sqlParprecio); //Agregamos el parametro al c
omando //5. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" :
"No se actualizo el producto de forma correcta"; } catch (Exception ex) { rpta
= ex.Message; } finally { //6. Cerramos la conexion con la BD if (sqlCon.State =
= ConnectionState.Open) sqlCon.Close(); } return rpta; } //Metodo utilizado para
obtener todos los productos de la base de datos public DataTable ObtenerProduct
o() { DataTable dtProducto = new DataTable("Producto"); SqlConnection sqlCon = n
ew SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.Connectio
nString = Conexion.cn; //2. Establecer el comando SqlCommand sqlCmd = new SqlCom
mand(); sqlCmd.Connection = sqlCon;//La conexion que va a usar el comando sqlCmd
.CommandText = "spF_Producto_All";//El comando a ejecutar sqlCmd.CommandType = C
ommandType.StoredProcedure;//Decirle al comando que va a ejecutar una sentencia
SQL //3. No hay parametros

//4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el D


ataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtProdu
cto);//Llenamos el DataTable } catch (Exception ex) { dtProducto = null; } retur
n dtProducto; } #region Metodos Get y Set public int codigoProducto { get { retu
rn var_codigoProducto; } set { var_codigoProducto = value; } } public string nom
bre { get { return var_nombre; } set { var_nombre = value; } } public decimal pr
ecio { get { return var_precio; } set { var_precio = value; } } #endregion } } 3
.3. Clase DetalleVenta Esta clase se encarga de conectar la tabla DetalleVenta c
on C# using System; using System.Collections.Generic; using System.Text; //Impot
aciones necesarias using System.Data; using System.Data.SqlClient; //Desarrollad
o por Henry Joe Wong Urquiza

namespace CapaDatos { public class DetalleVenta { private int var_codigoVenta; p


rivate int var_codigoProducto; private decimal var_cantidad; private decimal var
_descuento; //Constructor vacio public DetalleVenta() { } //Constructor con para
metros public DetalleVenta( int codigoVenta , int codigoProducto , decimal canti
dad , decimal descuento ) { this.var_codigoVenta=codigoVenta; this.var_codigoPro
ducto=codigoProducto; this.var_cantidad=cantidad; this.var_descuento=descuento;
} //Metodo utilizado para insertar un DetalleVenta //Le pasamos la conexion y la
transaccion por referencia, debido a que esos datos lo obtenemos //de la clase
Venta y no deberiamos crear una nueva Conexion o una nueva Transaccion //sino la
creada por la clase Venta public string Insertar(DetalleVenta varDetalleVenta,
ref SqlConnection sqlCon, ref SqlTransaction sqlTra) { string rpta = ""; try { /
/1. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connectio
n = sqlCon; sqlCmd.Transaction = sqlTra; sqlCmd.CommandText = "spI_DetalleVenta"
;

sqlCmd.CommandType = CommandType.StoredProcedure; //4. Agregar los parametros al


comando //Establecemos los valores para el parametro @codigoVenta del Procedimi
ento Almacenado SqlParameter sqlParcodigoVenta = new SqlParameter(); sqlParcodig
oVenta.ParameterName = "@codigoVenta"; sqlParcodigoVenta.SqlDbType = SqlDbType.I
nt; sqlParcodigoVenta.Value = varDetalleVenta.codigoVenta; sqlCmd.Parameters.Add
(sqlParcodigoVenta); //Agregamos el parametro al comando //Establecemos los valo
res para el parametro @codigoProducto del Procedimiento Almacenado SqlParameter
sqlParcodigoProducto = new SqlParameter(); sqlParcodigoProducto.ParameterName =
"@codigoProducto"; sqlParcodigoProducto.SqlDbType = SqlDbType.Int; sqlParcodigoP
roducto.Size = 4; sqlParcodigoProducto.Value = varDetalleVenta.codigoProducto; s
qlCmd.Parameters.Add(sqlParcodigoProducto); //Agregamos el parametro al comando
//Establecemos los valores para el parametro @cantidad del Procedimiento Almacen
ado SqlParameter sqlParcantidad = new SqlParameter(); sqlParcantidad.ParameterNa
me = "@cantidad"; sqlParcantidad.SqlDbType = SqlDbType.Decimal; sqlParcantidad.P
recision = 18; sqlParcantidad.Scale = 2; sqlParcantidad.Value = varDetalleVenta.
cantidad; sqlCmd.Parameters.Add(sqlParcantidad); //Agregamos el parametro al com
ando //Establecemos los valores para el parametro @descuento del Procedimiento A
lmacenado SqlParameter sqlPardescuento = new SqlParameter(); sqlPardescuento.Par
ameterName = "@descuento"; sqlPardescuento.SqlDbType = SqlDbType.Decimal; sqlPar
cantidad.Precision = 18; sqlParcantidad.Scale = 2; sqlPardescuento.Value = varDe
talleVenta.descuento; sqlCmd.Parameters.Add(sqlPardescuento); //Agregamos el par
ametro al comando //5. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() ==
1 ? "OK" : "No se inserto el detalle de venta de forma correcta"; }

catch (Exception ex) { rpta = ex.Message; } return rpta; } #region Metodos Get y
Set public int codigoVenta { get { return var_codigoVenta; } set { var_codigoVe
nta = value; } } public int codigoProducto { get { return var_codigoProducto; }
set { var_codigoProducto = value; } } public decimal cantidad { get { return var
_cantidad; } set { var_cantidad = value; } } public decimal descuento { get { re
turn var_descuento; } set { var_descuento = value; } } #endregion } } 3.4. Clase
Venta Esta clase se encarga de conectar la tabla Venta con C# using System; usi
ng System.Collections.Generic; using System.Text; //Impotaciones necesarias usin
g System.Data; using System.Data.SqlClient; //Desarrollado por Henry Joe Wong Ur
quiza

namespace CapaDatos { public class Venta { private int var_codigoVenta; private


string var_cliente; private DateTime var_fecha; //Constructor vacio public Venta
() { } //Constructor con parametros public Venta(int codigoVenta,string cliente,
DateTime fecha) { this.var_codigoVenta=codigoVenta; this.var_cliente=cliente; th
is.var_fecha=fecha; } //Metodo utilizado para insertar un Venta public string In
sertar(Venta varVenta, List<DetalleVenta> detalles) { string rpta = ""; SqlConne
ction sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion
sqlCon.ConnectionString = Conexion.cn; //2. Abrir la conexion de la BD sqlCon.Op
en(); //3. Establecer la transaccion SqlTransaction sqlTra = sqlCon.BeginTransac
tion(); //4. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.
Connection = sqlCon; sqlCmd.Transaction = sqlTra; sqlCmd.CommandText = "spI_Vent
a"; sqlCmd.CommandType = CommandType.StoredProcedure; //5. Agregar los parametro
s al comando //Establecemos los valores para el parametro @codigoVenta del Proce
dimiento Almacenado

SqlParameter sqlParcodigoVenta = new SqlParameter(); sqlParcodigoVenta.Parameter


Name = "@codigoVenta"; sqlParcodigoVenta.SqlDbType = SqlDbType.Int; sqlParcodigo
Venta.Direction = ParameterDirection.Output; sqlCmd.Parameters.Add(sqlParcodigoV
enta); //Agregamos el parametro al comando //Establecemos los valores para el pa
rametro @cliente del Procedimiento Almacenado SqlParameter sqlParcliente = new S
qlParameter(); sqlParcliente.ParameterName = "@cliente"; sqlParcliente.SqlDbType
= SqlDbType.VarChar; sqlParcliente.Size = 100; sqlParcliente.Value = varVenta.c
liente; sqlCmd.Parameters.Add(sqlParcliente); //Agregamos el parametro al comand
o //6. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No
se inserto el detalle de venta de forma correcta"; if (rpta.Equals("OK")) { //Ob
tenemos el codigo de la venta que se genero por la base de datos this.codigoVent
a=Convert.ToInt32(sqlCmd.Parameters["@codigoV enta"].Value); foreach(DetalleVent
a det in detalles){ //Establecemos el codigo de la venta que se autogenero det.c
odigoVenta = this.codigoVenta; //Llamamos al metodo insertar de la clase Detalle
Venta //y le pasamos la conexion y la transaccion que debe de usar rpta = det.In
sertar(det, ref sqlCon, ref sqlTra); if (!rpta.Equals("OK")) { //Si ocurre un er
ror al insertar un detalle de venta salimos del for break; } } } if (rpta.Equals
("OK")) { //Se inserto todo los detalles y confirmamos la transaccion sqlTra.Com
mit(); } else {

//Algun detalle no se inserto y negamos la transaccion sqlTra.Rollback(); } } ca


tch (Exception ex) { rpta = ex.Message; } finally { //6. Cerramos la conexion co
n la BD if (sqlCon.State == ConnectionState.Open) sqlCon.Close(); } return rpta;
} //Obtenemos la venta por el codigo generado public DataTable ObtenerVenta(int
codigoVenta) { DataTable dtVenta = new DataTable("Venta"); SqlConnection sqlCon
= new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.Conne
ctionString = Conexion.cn; //2. Establecer el comando SqlCommand sqlCmd = new Sq
lCommand(); sqlCmd.Connection = sqlCon;//La conexion que va a usar el comando sq
lCmd.CommandText = "spF_Venta_One";//El comando a ejecutar sqlCmd.CommandType =
CommandType.StoredProcedure;//Decirle al comando que va a ejecutar una sentencia
SQL //3. Agregar los parametros al comando //Establecemos los valores para el p
arametro @codigoVenta del Procedimiento Almacenado SqlParameter sqlParcodigoVent
a = new SqlParameter(); sqlParcodigoVenta.ParameterName = "@codigoVenta"; sqlPar
codigoVenta.SqlDbType = SqlDbType.Int; sqlParcodigoVenta.Value = codigoVenta; sq
lCmd.Parameters.Add(sqlParcodigoVenta); //Agregamos el parametro al comando

//4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el D


ataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtVenta
);//Llenamos el DataTable } catch (Exception ex) { dtVenta = null; } return dtVe
nta; } //Obtener todas las ventas public DataTable ObtenerVenta() { DataTable dt
Venta = new DataTable("Venta"); SqlConnection sqlCon = new SqlConnection(); try
{ //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; /
/2. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connectio
n = sqlCon;//La conexion que va a usar el comando sqlCmd.CommandText = "spF_Vent
a_All";//El comando a ejecutar sqlCmd.CommandType = CommandType.StoredProcedure;
//Decirle al comando que va a ejecutar una sentencia SQL //3. No hay parametros
//4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el D
ataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtVenta
);//Llenamos el DataTable } catch (Exception ex) { dtVenta = null; } return dtVe
nta; } #region Metodos Get y Set public int codigoVenta

{ get { return var_codigoVenta; } set { var_codigoVenta = value; } } public stri


ng cliente { get { return var_cliente; } set { var_cliente = value; } } public D
ateTime fecha { get { return var_fecha; } set { var_fecha = value; } } #endregio
n } }
4. RESUMEN
Al final deberamos tener las siguientes clases

C# - APLICACIN DE ESCRITORIO, SISTEMAS DE VENTAS PART III - CREACIN DE LA CAPA DE


NEGOCIOS
10:15 PM HENRY WONG 2 COMENTARIOS
"Si usa algn cdigo del siguiente tutorial, den el icono de ME GUSTA del Facebook q
ue se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y tambin
comentenos que tal les pareci el tutorial"
1. ENTORNO
Visual Studio 2008 SQL Server 2008
2. INTRODUCCIN
Ya vimos que en la Parte II del tutorial creamos la Capa de Dato de nuestro sist
ema, la cual es la encargada de comunicarse con la base de datos. Ahora nos toca
ra desarrollar la Capa de Negocios que es la capa en la cual se implementa la lgic
a del negocio de la empresa como obtener descuentos, aumentos, etc.
3. DESARROLLO
3.1. Creando el proyecto Ahora debemos de agregar a nuestro proyecto un proyecto
del tipo biblioteca de clases que se llamara "CapaNegocios"

3.2. Agregando al referencia con la Capa de Datos Debemos de establecer la comun


icacion entre la Capa de Negocios y la Capa de Datos. Para eso hacemos clic dere
cho en nuestro proyecto que se llama "CapaNegocios" y nos vamos a la opcion de "
Agregar Referencia"

Y de ah seleccionamos que se comunique con el proyecto que se llama "CapaDatos"

3.3. Clase NegProducto La clase "NegProducto" se encarga de comunicarse con la c


lase "Producto" de la capa de datos using System; using System.Collections.Gener
ic; using System.Linq; using System.Text; using System.Data; //Para que se comun
ique con la Capa de Datos

using CapaDatos; //Desarollado por Henry Joe Wong Urquiza namespace CapaNegocios
{ public class NegProducto { //Metodo que llama al metodo Insertar de la Capa d
e Datos //de la clase Producto public static string Insertar(string Nombre, deci
mal Precio) { Producto pro = new Producto(); pro.nombre = Nombre; pro.precio = P
recio; return pro.Insertar(pro); } //Metodo que llama al metodo Actualizar de la
Capa de Datos //de la clase Producto public static string Actualizar(int Codigo
Producto, string Nombre, decimal Precio) { Producto pro = new Producto(); pro.co
digoProducto = CodigoProducto; pro.nombre = Nombre; pro.precio = Precio; return
pro.Actualizar(pro); } //Metodo que se encarga de llamar al metodo ObtenerProduc
to //de la clase Producto public static DataTable ObtenerProducto() { return new
Producto().ObtenerProducto(); } } }
3.4. Clase NegDetalleVenta
La clase "NegDetalleVenta" se encarga de establecer los descuentos de los detall
es de venta. Si el subtotal supera los 50 soles, dolares, euros, etc se le aplic
a un descuento del 5% del detalle de la venta. Y eso se aplica en la Capa de Neg
ocios debido a que pertenece a la lgica de la empresa.

using System; using System.Collections.Generic; using System.Linq; using System.


Text; //Desarollado por Henry Joe Wong Urquiza namespace CapaNegocios { public c
lass NegDetalleVenta { //Metodo utilizado para obtener el descuento del detalle
de la venta //si la venta supera los 50 soles, dolares, euros, etc //se le hace
un descuento del 5% del detalle de la venta public static decimal ObtenerDescuen
to(decimal cantidad, decimal pu) { if ((cantidad * pu) > 50) { decimal porcentaj
e = Convert.ToDecimal(0.05); decimal descuento = ((cantidad * pu) * porcentaje);
return descuento; } else { return 0; } } } } 3.5. Clase NegVenta using System;
using System.Collections.Generic; using System.Linq; using System.Text; using Sy
stem.Data; //Para que se comunique con la Capa de Datos using CapaDatos; //Desar
ollado por Henry Joe Wong Urquiza namespace CapaNegocios { public class NegVenta
{ //Metodo que llama al metodo Insertar de la Capa de Datos

//de la clase Venta public static string Insertar(string cliente, DataTable dtDe
talles) { Venta venta = new Venta(); venta.cliente = cliente; List<DetalleVenta>
detalles=new List<DetalleVenta>(); foreach (DataRow row in dtDetalles.Rows) { D
etalleVenta detalle = new DetalleVenta(); detalle.codigoProducto = Convert.ToInt
32(row["codigoProducto"].ToString()); detalle.cantidad = Convert.ToDecimal(row["
cantidad"].ToString()); detalle.descuento = NegDetalleVenta.ObtenerDescuento(det
alle.cantidad, Convert.ToDecimal(row["PU"].ToString())); detalles.Add(detalle);
} return venta.Insertar(venta, detalles); } //Metodo que se encarga de llamar al
metodo ObtenerProducto //de la clase Venta public static DataTable ObtenerVenta
() { return new Venta().ObtenerVenta(); } //Metodo que se encarga de llamar al m
etodo ObtenerProducto //por codigo de la clase Venta public static DataTable Obt
enerVenta(int codigoVenta) { return new Venta().ObtenerVenta(codigoVenta); } } }
4. RESUMEN
Al final deberamos tener las siguientes clases

C# - APLICACIN DE ESCRITORIO, SISTEMAS DE VENTAS PART IV - CREACIN DE LA CAPA DE P


RESENTACIN
10:27 AM HENRY WONG NO HAY COMENTARIOS
"Si usa algn cdigo del siguiente tutorial, den el icono de ME GUSTA del Facebook q
ue se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y tambin
comentenos que tal les pareci el tutorial"
1. ENTORNO
SQL Server 2008 Visual Studio 2008
2. INTRODUCCIN
En el tutorial en la Parte II y en la Parte III hemos creado la capa de datos y
la capa de negocios respectivamente de nuestra aplicacin, ahora solo nos falta cr
ear nuestra capa de presentacion. La capa de presentacion puede ser una aplicaci
on del tipo escritorio, web, etc. Es por eso que se utiliza la programacion en c
apas, debido a que no importa que cambiamos hagamos en alguna capa no se sentira
en las otras de manera brusca.

3. DESARROLLO
3.1. Creando el Proyecto Ahora debemos de agregar a nuestro proyecto un proyecto
del tipo biblioteca de clases que se llamara "CapaPresentacion". No olvidar que
debemos de ir a "Archivo-->Agregar-->Nuevo Proyecto"
3.2. Agregando la referencia con la Capa de Negocios Debemos de establecer la co
municacion entre la Capa de Presentacin y la Capa de Negocios. Para eso hacemos c
lic derecho en nuestro proyecto que se llama "CapaPresentacion" y nos vamos a la
opcion de "Agregar Referencia"

Y de ah seleccionamos que se comunica con la Capa de Negocios

3.3. Formulario frmMantenimientoProducto En este formulario vamos a realizar un


mantenimiento a la tabla Producto de nuestra Base de Datos que se llama BDTutori
al y que esta diseada en SQL Server 2008. A mantenimiento me refiero a los proces
os de insercin, actualizacin y consulta de datos de la tabla Producto. Debemos de
disear el siguiente formulario

En el cual el componente dgvProducto tiene los siguientes valores de propiedades


: AllowUserToAddRows = False AllowUserToDeleteRows = False MultiSelect = False R
eadOnly = True SelectionMode = FullRowSelect
Y como columnas tiene codigoProducto o DataPropertyName = codigoProducto o Heade
rText = codigoProducto o Visible = False Nombre

o o o
DataPropertyName = nombre HeaderText = Nombre Visible = True
Precio o DataPropertyName = precio o HeaderText = Precio o Visible = True
En la otra pestaa del tabControl tenemos los siguientes componentes:
Y su cdigo fuente del formulario seria using using using using using System; Syst
em.Collections.Generic; System.ComponentModel; System.Data; System.Drawing;

using System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse


con la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urq
uiza namespace CapaPresentacion { public partial class frmMantenimientoProducto
: Form { //Variable que nos indica si vamos a insertar un nuevo producto private
bool nuevo = false; //Variable que nos indica si vamos a modificar un producto
private bool modificar = false; //Constructor del formulario public frmMantenimi
entoProducto() { InitializeComponent(); } //Evento que se lanza cuando se va a m
ostrar el formulario private void frmMantenimientoProducto_Load(object sender, E
ventArgs e) { //Para ubicar al formulario en la parte superior del contenedor th
is.Top = 0; this.Left = 0; //Le decimos al DataGridView que no auto genere las c
olumnas this.dgvProductos.AutoGenerateColumns = false; //Llenamos el DataGridVie
w con la informacion de todos nuestros //productos this.dgvProductos.DataSource
= NegProducto.ObtenerProducto(); //Deshabilita los controles this.habilitar(fals
e); //Establece los botones this.botones(); } //Para mostrar mensaje de confirma
cion private void mOK(string men) { MessageBox.Show(men, "MENSAJE", MessageBoxBu
ttons.OK, MessageBoxIcon.Information); } //Para mostrar mensaje de error private
void mError(string men) {

MessageBox.Show(men, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } //L


impia los controles del formulario private void limpiar() { this.txtNombre.Text
= string.Empty; this.nudPrecio.Value = 0; } //Habilita los controles de los form
ularios private void habilitar(bool valor) { this.txtNombre.ReadOnly = !valor; t
his.nudPrecio.Enabled = valor; } //Habilita los botones private void botones() {
if (this.nuevo || this.modificar) { this.habilitar(true); this.btnNuevo.Enabled
= false; this.btnGuardar.Enabled = true; this.btnModificar.Enabled = false; thi
s.btnCancelar.Enabled = true; } else { this.habilitar(false); this.btnNuevo.Enab
led = true; this.btnGuardar.Enabled = false; this.btnModificar.Enabled = true; t
his.btnCancelar.Enabled = false; } } //Evento clic del boton btnNuevo private vo
id btnNuevo_Click(object sender, EventArgs e) { this.nuevo=true; this.modificar=
false; this.botones(); this.limpiar(); this.txtCodigo.Text = string.Empty; this.
txtNombre.Focus(); } //Evento clic del boton btnGuardar

private void btnGuardar_Click(object sender, EventArgs e) { //La variable que al


macena si se inserto o se modifico la tabla string rpta = ""; if(this.nuevo) { /
/Vamos a insertar un producto rpta=NegProducto.Insertar(this.txtNombre.Text.Trim
().ToUpper() , this.nudPrecio.Value); }else { //Vamos a modificar un producto rp
ta=NegProducto.Actualizar(Convert.ToInt32(this.txtCodigo.Tex t), this.txtNombre.
Text.Trim().ToUpper(), this.nudPrecio.Value); } //Si la respuesta fue OK, fue po
rque se modifico o inserto el Producto //de forma correcta if (rpta.Equals("OK")
) { if (this.nuevo) { this.mOK("Se inserto de forma correcta al Producto"); } el
se { this.mOK("Se actualizo de forma correcta al Producto"); } } else { //Mostra
mos el mensaje de error this.mError(rpta); } this.nuevo=false; this.modificar=fa
lse; this.botones(); this.limpiar(); this.dgvProductos.DataSource = NegProducto.
ObtenerProducto(); this.txtCodigo.Text=""; }

//Evento clic del boton btnModificar private void btnModificar_Click(object send


er, EventArgs e) { //Si no ha seleccionado un producto no puede modificar if(!th
is.txtCodigo.Text.Equals("")) { this.modificar=true; this.botones(); } else { th
is.mError("Debe de buscar un producto para Modificar"); } } //Evento clic del bo
ton btnCancelar private void btnCancelar_Click(object sender, EventArgs e) { thi
s.nuevo=false; this.modificar=false; this.botones(); this.limpiar(); this.txtCod
igo.Text=string.Empty; } //Evento double clic del DataGridView de Productos priv
ate void dgvProductos_DoubleClick(object sender, EventArgs e) { this.txtCodigo.T
ext = Convert.ToString(this.dgvProductos.CurrentRow.Cells["codigoProducto"]. Val
ue); this.txtNombre.Text = Convert.ToString(this.dgvProductos.CurrentRow.Cells["
nombre"].Value); this.nudPrecio.Value = Convert.ToDecimal(this.dgvProductos.Curr
entRow.Cells["precio"].Value); this.tabControl.SelectedIndex = 1; } } } 3.4. For
mulario frmSeleccionarProducto Es un formulario del tipo modal que nos permitir s
eleccionar un producto de nuestra base de datos para registrar la venta. Y tiene
el siguiente diseo

En el cual el componente dgvProducto tiene los siguientes valores de propiedades


:

AllowUserToAddRows = False AllowUserToDeleteRows = False MultiSelect = False Rea
dOnly = True SelectionMode = FullRowSelect

Y como columnas tiene

codigoProducto o DataPropertyName = codigoProducto o HeaderText = codigoProducto


o Visible = False Nombre o DataPropertyName = nombre o HeaderText = Nombre o Vi
sible = True Precio o DataPropertyName = precio o HeaderText = Precio o Visible
= True

Y como cdigo fuente tiene lo siguiente using System; using System.Collections.Gen


eric; using System.ComponentModel; using System.Data; using System.Drawing; usin
g System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse con
la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urquiza
namespace CapaPresentacion { public partial class frmSeleccionarProducto : Form
{ //El formulario padre private frmRegistrarVenta frame; //El constructor del f
ormulario public frmSeleccionarProducto() { InitializeComponent(); } //Establece
los valores del formulario padre public void estableceFormulario(frmRegistrarVe
nta frame) { this.frame = frame; } //Evento que se ejecuta cuando se muestra el
formulario

private void frmSeleccionarProducto_Load(object sender, EventArgs e) { //Que no


se genere las columnas de forma automatica this.dgvProducto.AutoGenerateColumns
= false; //Obtiene todos los productos y lo asigana al DataGridView this.dgvProd
ucto.DataSource = NegProducto.ObtenerProducto(); } //Evento double clic del Data
GridView private void dgvProducto_DoubleClick(object sender, EventArgs e) { //Es
tableciendo los datos a las cajas de texto del formulario padre this.frame.codig
oProductoSeleccionado = Convert.ToInt32(this.dgvProducto.CurrentRow.Cells["codig
oProducto"].Va lue); this.frame.txtProducto.Text = Convert.ToString(this.dgvProd
ucto.CurrentRow.Cells["nombre"].Value); this.frame.txtPrecio.Text = Convert.ToSt
ring(this.dgvProducto.CurrentRow.Cells["precio"].Value); //Cerrando el formulari
o this.Hide(); } } } 3.5. Formulario frmRegistrarVenta Este formulario es la par
te principal del sistema en cual se registra la venta. Tener en cuenta que si el
detalle de la venta es mayor a 50 soles, dolares, euros, etc se le aplica un de
scuento del 5% del sub total de la venta. Debemos realizar el siguiente diseo del
formulario

En cual la accesibilidad de los controles txtProducto y txtPrecio es del tipoInt


ernal y tiene la propiedad ReadOnly en True. Y ademas el componente dgvDetalle t
iene los siguientes valores de propiedades: AllowUserToAddRows = False AllowUser
ToDeleteRows = False MultiSelect = False ReadOnly = True SelectionMode = FullRow
Select
Y como columnas tiene codigoProducto o DataPropertyName = codigoProducto o Heade
rText = codigoProducto o Visible = False


Producto o DataPropertyName = Producto o HeaderText = Producto o Visible = True
Cantidad o DataPropertyName = cantidad o HeaderText = Cantidad o Visible = True
PU o o o DataPropertyName = PU HeaderText = PU Visible = True

Descuento o DataPropertyName = Descuento o HeaderText = Descuento o Visible = Tr


ue SubTotal o DataPropertyName = subTotal o HeaderText = SubTotal o Visible = Tr
ue

Y como cdigo fuente tiene lo siguiente: using System; using System.Collections.Ge


neric; using System.ComponentModel; using System.Data; using System.Drawing; usi
ng System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse con
la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urquiz
a namespace CapaPresentacion { public partial class frmRegistrarVenta : Form { /
/DataTable que se encargara de guardar el detalle de la venta //de forma tempora
l private DataTable dtDetalle; //Codigo del producto seleccionado internal int c
odigoProductoSeleccionado = -1; //Variable que almacena el total de la venta pri
vate decimal totalPagar = 0;

//El constructor de la clase public frmRegistrarVenta() { InitializeComponent();


} //Metodo que se ejecuta al cargar el formulario private void frmRegistrarVent
a_Load(object sender, EventArgs e) { this.Top = 0; this.Left = 0; this.crearTabl
a(); this.WindowState = FormWindowState.Maximized; } //Limpia todos los controle
s del formulario private void limpiarControles() { this.txtCliente.Text = string
.Empty; this.codigoProductoSeleccionado = -1; this.txtProducto.Text = string.Emp
ty; this.txtPrecio.Text = string.Empty; this.nudCantidad.Value = 1; this.crearTa
bla(); this.lblTotalPagar.Text = "Total Pagar: S/. 0.00"; } //Crea la tabla de D
etalle private void crearTabla() { //Crea la tabla con el nombre de Detalle this
.dtDetalle = new DataTable("Detalle"); //Agrega las columnas que tendra la tabla
this.dtDetalle.Columns.Add("codigoProducto", System.Type.GetType("System.Int32"
)); this.dtDetalle.Columns.Add("Producto", System.Type.GetType("System.String"))
; this.dtDetalle.Columns.Add("cantidad", System.Type.GetType("System.Decimal"));
this.dtDetalle.Columns.Add("PU", System.Type.GetType("System.Decimal")); this.d
tDetalle.Columns.Add("Descuento", System.Type.GetType("System.Decimal")); this.d
tDetalle.Columns.Add("subTotal", System.Type.GetType("System.Decimal")); //Relac
ionamos nuestro datagridview con nuestro datatable this.dgvDetalle.DataSource =
this.dtDetalle;

} //Para mostrar mensaje de error private void mError(string mensaje) { MessageB


ox.Show(this, mensaje, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Warning); }
//Para mostrar mensaje de confirmacin private void mOk(string mensaje) { Message
Box.Show(this, mensaje, "MENSAJE", MessageBoxButtons.OK, MessageBoxIcon.Informat
ion); } //Evento del clic del boton btnBuscar private void btnBuscar_Click(objec
t sender, EventArgs e) { //Creamos una variable del tipo del formulario que dese
amos abrir frmSeleccionarProducto frame = new frmSeleccionarProducto(); //Le pas
amos como datos la informacin de nuestro formulario frame.estableceFormulario(thi
s); //Mostrar el formulario que tiene los productos que hemos seleccionado frame
.ShowDialog(); } //Evento clic del boton agregar private void btnAgregar_Click(o
bject sender, EventArgs e) { //Valida que hemos seleccionado algun producto if (
this.codigoProductoSeleccionado == -1) { this.mError("No ha seleccionado aun nin
gun producto"); } else { //Variable que va a indicar si podemos registrar el det
alle bool registrar = true; foreach (DataRow row in dtDetalle.Rows) { if (Conver
t.ToInt32(row["codigoProducto"]) == this.codigoProductoSeleccionado) { registrar
= false; this.mError("Ya se encuentra el producto en el detalle"); } }

//Si podemos registrar el producto en el detalle if (registrar) { //Calculamos e


l sub total del detalle sin descuento decimal subTotal = Convert.ToDecimal(this.
txtPrecio.Text) * nudCantidad.Value; //Obtenemos el descuento decimal descuento
= NegDetalleVenta.ObtenerDescuento( nudCantidad.Value, Convert.ToDecimal(this.tx
tPrecio.Text)); //Actualizamos el sub total con el descuento correspondiente sub
Total = subTotal - descuento; //Aumentamos el total a pagar this.totalPagar += s
ubTotal; this.lblTotalPagar.Text = "Total Pagar: S/." + totalPagar.ToString("#0.
00#"); //Agregamos al fila a nuestro datatable DataRow row = this.dtDetalle.NewR
ow(); row["codigoProducto"] = this.codigoProductoSeleccionado; row["Producto"] =
this.txtProducto.Text; row["cantidad"] = this.nudCantidad.Value; row["PU"] = th
is.txtPrecio.Text ; row["Descuento"] = descuento; row["subTotal"] = subTotal; th
is.dtDetalle.Rows.Add(row); } } } //Evento click del boton quitar private void b
tnQuitar_Click(object sender, EventArgs e) { try { //Indice dila actualmente sel
eccionado y que vamos a eliminar int indiceFila = this.dgvDetalle.CurrentCell.Ro
wIndex; //Fila que vamos a eliminar DataRow row = this.dtDetalle.Rows[indiceFila
]; //Disminuimos el total a pagar this.totalPagar = this.totalPagar Convert.ToDe
cimal(row["subTotal"].ToString()); this.lblTotalPagar.Text = "Total Pagar: S/."
+ totalPagar.ToString("#0.00#"); //Removemos la fila this.dtDetalle.Rows.Remove(
row); } catch (Exception ex)

{ mError("No hay fila para remover"); } } private void btnGuardar_Click(object s


ender, EventArgs e) { //Debe de tener por almenos un detalle para poder registra
r if (this.dtDetalle.Rows.Count > 0) { string rpta = NegVenta.Insertar(this.txtC
liente.Text, this.dtDetalle); if (rpta.Equals("OK")) { mOk("Se inserto de manera
correcta la venta"); this.limpiarControles(); } else { mError(rpta); } } else {
mError("No agregado ningun detalle"); } }
} }
C# - APLICACIN DE ESCRITORIO, SISTEMAS DE VENTAS PART V - CREACIN DE REPORTE (CRYS
TAL REPORT)
4:30 PM HENRY WONG NO HAY COMENTARIOS
"Si usa algn cdigo del siguiente tutorial, den el icono de ME GUSTA del Facebook q
ue se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y tambin
comentenos que tal les pareci el tutorial"
1. ENTORNO


SQL Server 2008 Visual Studio 2008
2. INTRODUCCIN
Continuando con el tutorial del sistemas de ventas con C#, ahora crearemos el re
porte con Crystal Report que nos mostrara el documento creado producto de la ven
ta que hemos realizado. Como este es un tutorial con un fin didctico, para crear
el reporte nosotros escribiremos el cdigo auto generado por la insercin de la vent
a, aunque lo ideal seria que desde la capa de negocios obtengamos el cdigo que se
genero y se muestre el reporte de forma automtica.
3. DESARROLLO
3.1. Diseo del formulario Ahora debemos de modificar nuestro formulario que hemos
creado anteriormente que se llamaba frmRegistrarVenta. Si recordamos este formu
lario tenia un Tab Control con dos pestaas, una que se llamaba Registrar y otro q
ue se llama Reporte. Y justo en esta ultima pestaa es donde vamos a poner nuestro
reporte. Para poder mostrar los reportes en C#, debemos de agregar un component
e que se llama CrystalReportViewer que se encuentra en nuestro cuadro de herrami
entas en el grupo de Informe

Y luego en nuestro formulario hacemos el siguiente diseo

3.2. Creando nuestro DataSet Para poder crear un reporte para Crystal Reporte, l
o primero que se tiene que hacer es crear un DataSet en donde se almacenara todo
nuestro datos de la consulta y nos servira para llenar nuestro reporte y para e
so les prepare el siguiente video para que puedan crear un DataSet de la manera
mas rpida y sencilla.
3.3. Creando nuestro Reporte en Crystal Report Ahora debemos de disear nuestro re
porte con la informacin que obtenemos de nuestro DataSet que hemos creado anterio
rmente, para eso tambin les prepare otro vdeo.
El reporte al final debera tener el siguiente diseo
3.4. Cdigo Fuente Ahora nos vamos a ir al evento clic del botn "btnReporte" de nue
stro formulario "frmRegistrarVenta" y pondremos el siguiente cdigo fuente private
void btnReporte_Click(object sender, EventArgs e) { try

{ //Creamos el documento CrystalDecisions.CrystalReports.Engine.ReportDocument r


pt=new CrystalDecisions.CrystalReports.Engine.ReportDocument(); //Obtenemos el d
ocumento que se encuentra en nustra carpeta bin\debug\crReporte.rpt rpt.Load( Ap
plication.StartupPath + "\\crReporte.rpt"); //Lleanamos el reporte con la inform
acin que obtenemos de la base de datos rpt.SetDataSource(NegVenta.ObtenerVenta(Co
nvert.ToInt32(this.txtCo digoVenta.Text))); //Establecemos los datos al reporte
this.crvReporte.ReportSource=rpt; //Refrescamos nuestro reporte this.crvReporte.
RefreshReport(); } catch (Exception ex) { } }

También podría gustarte