Vous êtes sur la page 1sur 60

Desarrollo Aplicacin N-Capas para Windows Mobile ( I )

Hola a tod@s nuevamente, el ttulo de este post me lo han pedido que lo explique muchas veces, me preguntan si es posible desarrollar una aplicacin para dispositivos mviles por capas y la respuesta es S.

A continuacin voy a explicar como es la arquitectura de una aplicacin de NCapas, al decir N-Capas, podemos pensar en 2, 3, 4, o ms capas, ya depende de organicemos nuestro trabajo y lo que necesitamos desarrollar.

En primera instancia un desarrollo con una arquitectura por capas tenemos que concientizarnos de partir las diferentes funcionalidades que deseemos realizar en nuestro desarrollo en varias partes y ubicarlos dentro de una de las capas que hayamos definido dentro de nuestra arquitectura.

Particularmente, yo me baso en el siguiente esquema para los desarrollos por capas de mis aplicaciones:

Capa de Presentacin
Como podemos observar de arriba hacia abajo tenemos una serie de capas, en donde la capa inicial es la capa de presentacin o de interface de usuario,

esta capa esta conformada por los formularios de la aplicacin Windows o por las pginas .aspx o web forms de una aplicacin ASP.NET. En cuanto al tema de las aplicaciones para dispositivos mviles nuestra capa de Presentacin ser tambin nuestra aplicacin Windows Mobile. Esta capa hablando en trminos de desarrollo con Visual Studio, es el proyecto de tipo Windows Application, o Web Application, o aplicacin Windows para Windows Mobile. Para el caso de una aplicacin que es un Web Service o un Servicio de Windows Communication Foundation (WCF), esta capa seria el servicio como tal que es quien expone al mundo los mtodos a consumir o a utilizar por las aplicaciones que consuman dichos servicios.

Capa de Negocio
Esta capa es la segunda en la estructura de la imagen, en esta capa es donde debemos colocar el cdigo de nuestra aplicacin que se encargue de realizar las operaciones inherentes al negocio o tipo de aplicacin que estemos desarrollando. Algunos se preguntarn, pero cuales son esas tareas del negocio? esto a veces es un poco subjetivo y algunos no alcanzamos a descubrir lnea que nos permite saber que es lo que debe ir en esta capa. Bueno, vamos a tratar de aclarar este punto, en esta capa se definen las operaciones o clculos que se necesiten realizar para las operaciones de nuestra aplicacin. En esta capa se arman las interfaces para llamar los diferentes mtodos que devuelven datos a nuestra aplicacin, porque esta es la capa con al cual interactuaremos desde la capa de Presentacin. Esto quiere decir que desde la presentacin no estaremos en contacto directo con la capa que maneja los datos de nuestro repositorio de datos. Esta capa tambin es la encargada de solicitar los datos a la capa del manejo de los datos y los entrega a la capa de Presentacin.

Recuerden en esta capa si necesitamos realizar alguna operacin como el calculo de un total, un promedio, etc., aqu es donde debemos realizar esa operacin y devolverla a la capa de presentacin. Espero que en el ejemplo esto lo pueda explicar mucho mejor y sea mas claro para todos. En nuestra solucin de Visual Studio esta capa es un proyecto de tipo librera de clases que agrupa todas las clases necesarias.

Capa de Manejo de Datos


Esta es una de las capas mas importantes, esta capa es la encargada de la creacin de los diferentes querys o consultas a la base de datos para obtener los datos que necesitamos en nuestra aplicacin. Esta capa tambin es la encargada de convertir los datos que devuelve la capa que interacta con nuestra base de datos, o sea un datatable, un datareader o un dataset, en una lista genrica o una coleccin de objetos de tipo entidad como veremos mas adelante en una de las capas ( la capa transversal). Esta capa esta representada por un proyecto de tipo librera de clases dentro de nuestra solucin de Visual Studio.

Capa de Acceso a Datos


Esta capa es un proyecto de tipo librera de clases en nuestra solucin de Visual Studio, en esta capa vamos a tener una clase que se conecte a la base de datos que vayamos a utilizar y se encarga de realizar todas las operaciones contra la base de datos seleccionada como repositorio de datos de nuestra solucin. La importancia de esta capa radica en que si cambian el motor de base de datos el impacto en nuestra aplicacin va a ser mnimo pues solo hay que modificar o corregir esta capa para el acceso y conexin a la nueva base de datos.

Capa de Infraestructura Transversal

En esta capa vamos a definir las clases de tipo entidad en la cual vamos a transportar los datos entre las diferentes capas de nuestra solucin. Las clase de tipo entidad son una copia de la estructura de nuestras tablas de la base de datos a utilizar, o de acuerdo a las necesidades que tengamos. Por ejemplo los resultados que necesitamos para un reporte impreso por lo general son muy variables y toca crear una entidad nica para ellos.

Bueno esto no es una ley, como dije antes todo depende de nuestro proyecto y de la manera que queramos hacer las cosas, muchas veces las primeras dos capas se unen y quedan en una sola, todo depende de cada uno de nosotros.

Bueno por hoy, hasta aqu, pronto haremos un ejemplo de una aplicacin usando esta metodologa. Hasta la prxima! Enjoy develop! Etiquetas: BogotaDotNet, Compact Framework, Desarrollo por Capas, PPC, Requisitos Desarrollo, VB.NET, VS2005, VS2008, WinCE, Windows CE, Windows Mobile publicadas por Roberto Alvarado @ 3:26 PM Vnculos a esta publicacin
SBADO, JULIO 31, 2010

Operaciones CRUD con SQL Mobile y ADO.NET en Windows Mobile


Hola a tod@s, hoy quiero explicarles como utilizar ADO.NET en Windows Mobile contra una base de datos SQL Mobile. Este artculo va a ser un poco largo, pero quiero responder aqu muchas de las preguntas que me hacen en los foros donde participo: Cmo creo una base de datos SQL Mobile, cmo inserto registros en esa base de datos, como elimino registros de esa base de datos, como edito o modifico la informacin, como muestro la informacin en una grilla?

A muchos les parecer mucho mas fcil trabajar con el control enlazado a datos de Windows Mobile BindingSource, pero considero que no se tiene todo el control que uno debe tener con los datos con este control. Sin embargo como dice un refrn aqu en Colombia Entre gustos no hay disgustos, los que desean hacerlo lo utilizan y cuando una consulta hay que cambiarla se enfrentan a inconvenientes para poder crearla como se necesita. Estos son mis puntos de vista y todos pensamos y hacemos las cosas diferentes, as que no tomen esto como una regla en sus desarrollos.

Este artculo va a tratar de utilizar todas las funciones necesarias de ADO.NET para Windows Mobile a partir del cdigo.

Definicin Estructura Tabla


Bueno, entonces empecemos con este tema, lo primero que vamos a hacer es definir una estructura de una tabla a la cual vamos a aplicar las operaciones del CRUD (Create, Remove, Update, Display) por sus siglas en ingls. Nuestra tabla es una tabla de contactos personales la cual va a contener las siguientes columnas: Id, entero, auto numrico y llave de la tabla Nombre, nvarchar de 150 caracteres de longitud Direccion, NVarchar de 150 caracteres de longitud Telefono, NVarchar de 10 caracteres de longitud Celular, Nvarchar de 10 caracteres de longitud

Habiendo definido nuestra tabla o nuestras tablas, vamos a recordar como crear por cdigo la base de datos en la PDA, y luego como aplicar los diferentes mtodos de ADO.NET para el manejo de los datos.

Creacin del Proyecto a desarrollar


Empecemos, abrimos nuestro ambiente de desarrollo Visual Studio 2008, para esto y seleccionamos crear un nuevo proyecto:

No muestra la pantalla de seleccionar el tipo de proyecto a crear:

En esta pantalla seleccionamos el lenguaje sobre el cual vamos a trabajar, tambin el tipo de proyecto a desarrollar, como vemos en la imagen seleccionamos Smart Device, que es el tipo de proyecto para Windows Mobile. Adems le asignamos un nombre al proyecto, pueden observar en la imagen que en las plantillas solo aparece una como Proyecto de Smart Device, en el

siguiente paso vamos a seleccionar ya el tipo de proyecto dentro de esta plantilla.

Al presionar el botn Aceptar nos muestra la siguiente pantalla :

En la parte superior y esto solo es a partir de Visual Studio 2008, nos permite seleccionar la plataforma de destino ( Platform Target) y la versin del .NET Compact Framework para el cual vamos a desarrollar. Luego de haber seleccionado estos datos vamos seleccionar el tipo de aplicacin a desarrollar, como vamos a crear una aplicacin para windows mobile, debemos seleccionar la plantilla de Aplicacin de Dispositivo.

De acuerdo a los diferentes SDK de Windows Mobile instalados en nuestro PC

de desarrollo, esta lista puede tener las opciones que aparecen o menos, en mi caso tengo instalados los SDK de Windows Mobile versin 2003, 5 y 6 Professional y Standard (antes llamado smart phone). Vamos a seleccionar la plataforma Windows Mobile 6 Profesional SDK.

Para el caso de la versin del CF.NET sobre la cual vamos a desarrollar, vamos a seleccionar la versin 3.5, y le damos clic al botn de Aceptar de esta pantalla para que nos abra nuestro ambiente de desarrollo y el formulario para empezar a desarrollar nuestra aplicacin.

Como podemos apreciar en la imagen el formulario creado por default en su parte superior derecha tiene una equis X, esto significa que se va a minimizar el formulario al presionarla, no se va a cerrar la aplicacin como deseamos, para esto vamos a ir al panel de propiedades y vamos a cambiar la propiedad MinimizeBox a False.

Con esto nuestro formulario muestra un botn de OK, que si permite cerrar la aplicacin cuando hagamos clic sobre el.

Despus de haber configurado nuestro formulario, lo primero que debemos hacer es adicionar a nuestra solucin la referencia al espacio de nombres que maneja las bases de datos SQL Mobile, por defecto esta referencia no viene en los proyectos.

Para adicionar la referencia hacemos clic derecho sobre References y nos muestra la lista de todos los assemblies que podemos utilizar en nuestro desarollo.

Y ubicamos en la lista System.Data.SqlServerCe, lo seleccionamos y presionamos el botn de Aceptar de la ventana:

Con esto este Espacio de nombre ya queda incluido en las referencias:

Hacemos doble clic sobre el formulario para que se abra la ventana de cdigo en el evento load de la forma, aqu vamos a verificar que exista la base de datos .sdf, que es la extensin de los archivos de SQL Mobile. Para esto necesitamos incluir el using de System.IO al principio de la clase que maneja el formulario, para poder hacer uso de la funcin que verifica si un archivo existe o no en el sistema de archivos de Windows Mobile. Adems necesitamos los using de System.Configuration y System.Reflection, para obtener la ruta en la cual se encuentra el ejecutable de la aplciacin y verificar que el archivo .sdf se encuentre en esa misma ruta. Por ultimo necesitamos el using de System.Data.SqlServerCe, para poder tener acceso al proveedor de datos y realizar las operaciones necesarias sobre la base de datos.

Verificar si el archivo .sdf existe

using System.IO; using System.Configuration; using System.Reflection; using System.Data.SqlServerCe; namespace CRUDWMCS { public partial class Form1 : Form { // Obtengo por Reflexion la ruta completa del archivo .exe String nombreExe = Assembly.GetExecutingAssembly().GetName().CodeBase; String ruta = String.Empty; public Form1() { InitializeComponent();

} private void Form1_Load(object sender, EventArgs e) { // Obtengo la ruta del archivo .exe ruta = nombreExe.Substring(0, nombreExe.LastIndexOf(@"\") + 1); if (!File.Exists(ruta + "DemoBD.sdf")) { // Instancio SqlCeENgine para crear la base de datos .sdf SqlCeEngine engine = new SqlCeEngine("Data Source= " + ruta + "DemoBD.sdf;");); } } } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt

{ background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Luego de obtener la ruta del archivo .exe, en la variable ruta de tipo String, pregunto si el archivo no existe, haciendo uso de File.Exist, si esta condicin es verdadera procedemos a crear la base de datos.

Crear la base de datos:

Creamos el archivo de base de datos con estas instrucciones:

// Instancio SqlCeENgine para crear la base de datos .sdf SqlCeEngine engine = new SqlCeEngine("Data Source= " + ruta + "DemoBD.sdf;");); engine.CreateDatabase(); engine.Dispose();

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace;

background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Luego procedemos a crear la tabla que vamos a necesitar, para esto utilizando ADO.NET, abrimos una conexin a la base de datos, creamos un comando para ejecutar la instruccin de creacin de la tabla en la base de datos y por ultimo cerramos la conexin a la base de datos.

A continuacin como queda el cdigo del evento Load de la forma en la cual se crea la base de datos y la tabla a utilizar:

private void Form1_Load(object sender, EventArgs e) { // Obtengo la ruta del archivo .exe ruta = nombreExe.Substring(0, nombreExe.LastIndexOf(@"\") + 1); if (!File.Exists(ruta + "DemoBD.sdf")) { // Instancio SqlCeEngine para crear la base de datos .sdf SqlCeEngine engine = new SqlCeEngine("Data Source= " + ruta + "DemoBD.sdf;"); engine.CreateDatabase(); engine.Dispose(); // Instancio la conexion a la base de datos SqlCeConnection conn = new SqlCeConnection(); StringBuilder sbQuery = new StringBuilder(); SqlCeCommand cmd = new SqlCeCommand(); try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("CREATE TABLE Contactos( "); sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" Id int IDENTITY(1,1) NOT NULL "); ,Nombre nvarchar(150) NOT NULL "); ,Direccion nvarchar(150) NOT NULL "); ,Telefono nvarchar(10) NOT NULL "); ,Celular nvarchar(10) NOT NULL "); , CONSTRAINT CONTACTOS_PK PRIMARY KEY "); sbQuery.Append(" sbQuery.Append(" ( "); Id ");

sbQuery.Append(" sbQuery.Append("

) "); ) ");

// Configuro el objeto commando para ejecutar la sentencia SQL cmd.CommandText = sbQuery.ToString(); // Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion cmd.ExecuteNonQuery(); conn.Close(); conn.Dispose(); } catch (SqlCeException sqlEx) { MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Abriendo Base de Datos"); return; } } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Si ejecutamos nuestra aplicacin hasta este momento vamos a observar en el directorio el archivo de la base de datos.

En las imgenes anteriores podemos observar que la base de datos se creo de manera correcta al igual que la tabla.

Recapitulando un poco:

Para crear la base de datos: se necesita el objeto SqlCeEngine de ADO.NET para SQL Mobile.

Para crear la tabla por cdigo: Se necesita:

un objeto SqlCeConnection que establece y abre la conexin con la base de datos SQL Mobile. un objeto SqlCeCommand que permite ejecutar las sentencias SQL contra la base de datos utilizando el objeto SqlCeConnection creado en el paso anterior.

Ahora que ya tenemos la base de datos con su tabla creada, vamos a crear una opcin en el men para adicionar registros a nuestra tabla, para esto

vamos a adicionar al men la opcin Adicionar y vamos a crear un panel para la captura de los datos.

Adems vamos a adicionar un Panel que nos servir para simular una ventana con los datos a capturar.

Dentro del panel vamos a colocar controles label y controles TextBox que nos

permitan capturar los datos de diferentes datos de la tabla. Nuestro panel de captura va a quedar de al siguiente manera:

En el evento click del botn grabar vamos a colocar toda la lgica de la grabacin de los datos, a continuacin el cdigo del botn:

Adicionar Registro

// Grabar los datos en la tabla private void btnGrabar_Click(object sender, EventArgs e) {

SqlCeConnection conn = new SqlCeConnection(); StringBuilder sbQuery = new StringBuilder(); SqlCeCommand cmd = new SqlCeCommand(); try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("INSERT INTO Contactos ( "); sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" Nombre "); ,Direccion "); ,Telefono "); ,Celular ");

sbQuery.Append(" ) VALUES ( "); '" + txtNombre.Text + "'"); ,'" + txtDireccion.Text + "'"); ,'" + txtTelefono.Text + "'"); ,'" + txtCelular.Text + "'"); ");

sbQuery.Append(" )

// Configuro el objeto commando para ejecutar la sentencia SQL cmd.CommandText = sbQuery.ToString(); // Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion cmd.ExecuteNonQuery(); LimpiarCampos(); } catch (SqlCeException sqlEx) {

MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Grabando Datos"); } finally { conn.Close(); conn.Dispose(); } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

En este cdigo utilizamos los objeto SqlCeConnection para establecer al conexin con la base de datos, SqlCeCommand para ejecutar la instruccin INSERT en la tabla y adicionar los datos del contacto, como siempre todo esto debe estar dentro de un bloque try catch para capturar las excepciones si llega a ocurrir alguna al momento de ejecutar el comando.

El mtodo LimpiarCampos() lo que hace es limpiar los controles textbox utilizados.

Editar o Modificar Datos

Para la edicin de los datos, vamos a crear un nuevo Panel y dentro colocar los controles necesarios para poder realizar estas modificaciones al registro, adems un campo para pedir el ID del registro y traer los datos y editarlos.

La pantalla de edicin queda de esta manera:

Buscar un Contacto

El botn buscar ejecuta una sentencia SELECT contra la tabla de Contactos para ubicar el ID digitado, si no lo encuentra muestra un mensaje indicando esta situacin, si lo encuentra rellena los controles con los valores obtenidos de la base de datos.

Para realizar esta operacin, abrimos la conexin ala base de datos a travs de SqlCeConnect, y utilizando un SqlCeCommand ejecutamos una sentencia contra la base de datos, como esta sentencia a diferencia de las anteriores si devuelve un resultado, que ser el registro que estamos buscando, utilizamos el mtodo ExecuteReader del objeto Comando para esta operacin.

En nuestro programa declaramos una variable de tipo IDataReader para que pueda recibir los datos y procesarlos de acuerdo a nuestras necesidades.

Una vez tenemos los datos en el DataReader los leemos y llenamos los controles textbox con sus correspondientes valores.

A continuacin el cdigo del botn Buscar:

// Boton Buscar un registro de acuerdo al id private void btnBuscar_Click(object sender, EventArgs e) { SqlCeConnection conn = new SqlCeConnection(); StringBuilder sbQuery = new StringBuilder(); SqlCeCommand cmd = new SqlCeCommand(); IDataReader dr; try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("SELECT Id "); sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" ,Nombre " ); ,Direccion "); ,Telefono " ); ,Celular " ); ");

sbQuery.Append("FROM Contactos

sbQuery.Append(" WHERE ID = " + txtID.Text); // Configuro el objeto commando para ejecutar la sentencia SQL cmd.CommandText = sbQuery.ToString(); // Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion dr = cmd.ExecuteReader(); while (dr.Read()) { txtEditNombre.Text = dr["Nombre"].ToString(); txtEditDireccion.Text = dr["Direccion"].ToString(); txtEditTelefono.Text = dr["Telefono"].ToString(); txtEditCelular.Text = dr["Celular"].ToString(); } // Cierro el DataReader dr.Close(); if(txtEditNombre.Text == String.Empty) MessageBox.Show("Registro no Existe, Verifique.", "Editar Contactos"); } catch (SqlCeException sqlEx) { MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Grabando Datos"); } finally { // Cierro la conexion conn.Close(); conn.Dispose(); } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Ahora que ya podemos ubicar o buscar un registro dentro de nuestra tabla de contactos, podemos cambiar los diferentes datos del registro y grabar las modificaciones, para esto vamos a codificar el botn grabar del panel de Edicin de los datos.

A continuacin el cdigo para grabar los datos modificados:

// Boton grabar los cambios en el registro private void btnEditGrabar_Click(object sender, EventArgs e) { SqlCeConnection conn = new SqlCeConnection(); StringBuilder sbQuery = new StringBuilder(); SqlCeCommand cmd = new SqlCeCommand(); try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("UPDATE Contactos SET "); sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" Nombre " + "= ,Direccion " + "= '" + '" + '" + '" + txtNombre.Text + "'"); txtDireccion.Text + "'"); ,Telefono " + "= ,Celular " + "= txtTelefono.Text + "'"); txtCelular.Text + "'"); sbQuery.Append(" WHERE ID = " + txtID.Text); // Configuro el objeto commando para ejecutar la sentencia SQL cmd.CommandText = sbQuery.ToString();

// Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion cmd.ExecuteNonQuery(); LimpiarCamposEdit(); MessageBox.Show("Registro Editado de manera Correcta", "Editar Contactos"); } catch (SqlCeException sqlEx) { MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Grabando Datos"); } finally { conn.Close(); conn.Dispose(); } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Como podemos apreciar en el cdigo anterior, armamos un sentencia SQL UPDATE para modificar los datos de nuestra tabla, aqu una de laspartes ms importantes es el WHERE, tengan muy presente que si hacemos una sentencia UPDATE sin un WHERE se aplicaran los cambios a todos los registros de la tabla, por esto es muy importante esta sentencia en un UPDATE.

Eliminar Registros de la Tabla

Para eliminar los registros, vamos al men y creamos una nueva opcin de Eliminar, esta opcin va a llamar nuevamente al panel de edicin, pues todo nos sirve, el botn de buscar, la rutina que rellena los controles con al informacin guardada en la base de datos, el botn de cancelar o salir, nicamente vamos a crear un cdigo que si se llama desde al opcin Eliminar el texto del botn grabar cambia a Eliminar y se realizar la accin de eliminar el registro.

Al eliminar vamos a verificar que el campo de Nombre no este vaco, esto nos garantizar que no ocurra un error al intentar eliminar un registro sin verificarlo. A continuacin el cdigo de eliminar:

else { // VERIFICO QUE HAYA CONSULTADO A ALGUIEN if (txtEditNombre.Text == String.Empty) { MessageBox.Show("No ha Seleccionado un Contacto para eliminar", "Eliminando Contactos"); return; } // Eliminar el registro de la Tabla de Contactos try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("DELETE FROM Contactos "); sbQuery.Append(" WHERE ID = " + txtID.Text); // Configuro el objeto commando para ejecutar la sentencia SQL cmd.CommandText = sbQuery.ToString(); // Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion cmd.ExecuteNonQuery();

LimpiarCamposEdit(); MessageBox.Show("Registro Eliminado de manera Correcta", "Eliminar Contactos"); } catch (SqlCeException sqlEx) { MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Eliminando Datos"); } finally { conn.Close(); conn.Dispose(); } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt {

background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Como se puede apreciar es el else del botn de Editar, pues recuerden que estamos utilizando la misma forma que en editar.

Desplegar Datos en una Grilla

Por ltimo vamos a crear una nueva opcin en el men que nos permita listar todos los registros de la tabla para colocarlos dentro de un control ListView, que de acuerdo a las pruebas que yo he realizado es mucho mas rpido en Windows Mobile que un control datagrid, aqu nuevamente, les digo si necesita o prefieren utilizar un control datagrid lo pueden utilizar pues este si puede ser enlazado a datos (Bindable), esto queire decir que cuenta con una propiedad DataSource, mientras que el control ListView, no cuenta con esta propiedad.

Para esto vamos a agregar un nuevo panel al formulario llamado panDisplay y cuya propiedad Visible la vamos a colocar a false igual que los otros, al cual le vamos a asociar un control ListView.

El control ListView lo vamos a configurar para que muestre una lista pues este control puede comportarse para mostrar los mismos datos de diferentes maneras. Para hacer esto, vamos a cambiar la propiedad View del control al valor Details, al hacer esto, aparece una barra de ttulos en el control.

Tambin vamos a ubicar la propiedad FullRowSelect y la vamos a colocar a True.

El siguiente paso es configurar las diferentes columnas que va a mostrar el control, para esto vamos a ir a la propiedad Columns, como lo muestra la siguiente imagen:

Esto nos muestra una ventana para configurar las diferentes columnas que queremos tenga nuestro control.

Utilizamos el botn Agregar para adicionar las columnas que queremos muestre nuestro control ListView.

Como se puede apreciar en la imagen, por cada columna podemos cambiar las propiedades que aparecen a la derecha, las propiedades ms importantes a cambiar son: Text, que indica el texto de esa columna dentro del control, y Width, que indica el ancho que va a tener esa columna para mostrar los datos, tambin podremos controlar el alineamiento que va a tener esa columna, por defecto ser a la izquierda.

Nuestro formulario se ver de al siguiente forma:

Agregamos un botn de Cerrar para cerrar esta pantalla y regresar a la pantalla principal.

El cdigo del tem del men que llama esta opcin es el siguiente:

// Menu Mostrar la lista de Contactos en Grilla private void menuItem6_Click(object sender, EventArgs e) { panDisplay.Location = new Point(3, 3); panDisplay.Visible = true;

CargarDatosGrilla(); }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

El mtodo CargarDatosGrilla, se encarga de llenar el control ListView con los datos que existan en la tabla de contactos.

A continuacin el cdigo para llenar el ListView con los datos de la tabla

/// <summary> /// Metodo que carga los datos de Contactos en al Grilla /// </summary> private void CargarDatosGrilla() { SqlCeConnection conn = new SqlCeConnection(); StringBuilder sbQuery = new StringBuilder(); SqlCeCommand cmd = new SqlCeCommand(); IDataReader dr; try { // Indico la cadena de conexion a utilizar para abrir la base de datos SQL Mobile conn.ConnectionString = "Data Source= " + ruta + "DemoBD.sdf;"; // Abro la conexion a la base de datos conn.Open(); // Creo la sentencia SQL a utilizar sbQuery.Append("SELECT Id "); sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" sbQuery.Append(" ,Nombre "); ,Direccion "); ,Telefono "); ,Celular "); ");

sbQuery.Append("FROM Contactos

// Configuro el objeto commando para ejecutar la

sentencia SQL cmd.CommandText = sbQuery.ToString(); // Asigno la conexion al objeto commando cmd.Connection = conn; // Ejecuto la instruccion dr = cmd.ExecuteReader(); // Declaro un objeto ListViewItem, para cargar lso registros en el Control ListView ListViewItem lvItem = new ListViewItem(); // Limpio el control Listview, antes de empezar a llenarlo listView1.Items.Clear(); // recorro el dataReader para leer todos los registros while (dr.Read()) { // Inicializo el Control lvItem = new ListViewItem(); // Lleno los datos de la fila del control lvItem.Text = dr["Id"].ToString(); lvItem.SubItems.Add( dr["Nombre"].ToString()); lvItem.SubItems.Add( dr["Direccion"].ToString()); lvItem.SubItems.Add( dr["Telefono"].ToString()); lvItem.SubItems.Add( dr["Celular"].ToString()); // Agrego la fila al control listView1.Items.Add(lvItem); } // Cierro el DataReader dr.Close(); } catch (SqlCeException sqlEx) { MessageBox.Show("Ha ocurrido una excepcin:\r\n" + sqlEx.Message, "Grabando Datos"); } finally

{ // Cierro la conexion conn.Close(); conn.Dispose(); } }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Bueno espero que con este artculo se aclaren muchas dudas al respecto de como hacer o utilizar ADO.NET en Windows Mobile con el Compact Framewok .NET.

En un prximo artculo explicare como utilizar la arquitectura de N-Capas en aplicaciones para Windows Mobile.

Saludos y que lo disfruten!!! Etiquetas: CF, Compact Framework, PocketPC, PPC, VS2005, VS2008, WinCE, Windows CE, Windows Mobile publicadas por Roberto Alvarado @ 9:38 AM Vnculos a esta publicacin
SBADO, ENERO 24, 2009

Creacin de Reportes con Crystal Reports en Visual Studio 2005/2008


Este pequeo tutor de como crear un reporte en Crystal Reports desde Visual Studio 2005/2008, lo hago porque he recibido muchas consultas de como hacerlo de la mejor forma, quizs hiera algunas susceptibilidades, pero espero que entiendan que tambin hay otras maneras de hacer las cosas. En primer lugar en este tutor les voy a indicar como crear el reporte de la manera mas larga, pero tambin, es la mejor manera para tener el control total sobre lo que queremos mostrar en el reporte. La manera mas fcil de crear un reporte es agregar al proyecto un nuevo tem de tipo reporte de Crystal Reports, y conectarse a la base de datos desde el explorador de servidores del Visual Studio, seleccionar las tablas y arrastrarlas sobre el diseador del reporte. Si, esta es la manera mas fcil, pero tambin la que mas problemas nos puede dar al momento de empezar a cambiar campos a mostrar o al tratar de agregar una condicin o filtro a los datos que queremos mostrar en el reporte.

La anterior es una buena tcnica, siempre y cuando el reporte sea sencillo y detectemos que no tendr cambios. A continuacin describo la manera en yo creo mis reportes tanto para web como para windows. A muchos les parecer mas larga pero les aseguro que no tendrn problemas en el futuro pues tienen todo controlado ustedes. Voy a utilizar un proyecto Windows Forms y una base de datos Sql Server 2008, pero se van a dar cuenta que lo pueden hacer con cualquier tipo de base de datos. No voy a entrar en detalles del tipo de conexin a la base de datos ni las instrucciones para traer los datos. A continuacin muestro la forma con los datos que vamos a utilizar para nuestro reporte:

Bueno la idea de nuestro proyecto es que poder tener un reporte con estos datos, lo primero que vamos a hacer es agregar a nuestro proyecto un objeto dataset, que es el que nos va a servir para poder crear nuestro reporte en Crystal Reports.

Clic derecho en el nombre del proyecto, del men seleccionamos la opcin Add, y luego New Item para que nos aparezca la siguiente pantalla y poder escoger el objeto a adicionar a nuestro proyecto.

Escogemos adicionar un objeto dataset que nos servir como fuente de datos para el reporte y poder crear nuestro reporte como queremos. Le damos un nombre a nuestro dataSet, por lo general yo lo llamo igual que el reporte con el prefijo ds, entonces nuestro dataset se va a llamar dsPersonas.xsd

Al darle clic al boton Add nos muestra la ventana de diseo en la cual vamos a agregar un datatable con sus respectivos campos que son los que necesitamos para dibujar el reporte. Al estar aqu, damos clic derecho sobre la superficie para poder agregar el datatable :

Nos muestra el datatable creado, podemos cambiar el nombre que coloca por defecto, haciendo clic sobre el nombre y se coloca en modo de edicion para poder cambiarlo.

Para agregar los diferentes campos de nuestro datatable, seguimos los siguientes paso: 1. Clic derecho en el rea de los campos del datatable y los vamos agregando.

2. al seleccionar Agregar Columna:

nos permite colocarle el nombre a la columna, este nombre DEBE ser igual al nombre que vamos a devolver en nuestra consulta SQL a la Base de datos.

3. En la ventana de propiedades de la columna que estamos agregando, podemos asignar el tipo de campo y su longitud en caso de ser una cadena ( String) y que sea requerido. Mi recomendacin es que se apeguen a los mismos tipos de datos que estn definidos en la base de datos.

4. En proceso de agregar los campos necesarios para el reporte:

Si me preguntan si es se pueden agregar campos que no se van a utilizar en el reporte, la respuesta es SI, porque es posible que ya tengamos la consulta realizada que nos sirve para nuestro reporte y solo es crearlo a partir de la consulta que ya existe, y como la consulta nos devuelve datos que no vamos a colocar ene l reporte, de todas formas tenemos que crear esos campos en nuestro datatable. 5. Aqui esta nuestro datatable completo para empezar a generar nuestro reporte:

Quizs me pensaran: es mucho trabajo pero piensen en esto, este sistema si mas tarde necesitan agregar un nuevo campo es simplemente venir agregar el campo y actualizar la fuente de datos del reporte para tener acceso a ese nuevo campo que acabamos de crear, por el otro mtodo, eso no es tan fcil, es mejor agregar el campo y volver a crear el reporte. Aclaracin: yo, particularmente, no he sabido, o no he logrado como hacerlo cuando lo intente. 6. Creamos el reporte en crystal reports, nuevamente clic derecho en el nombre del proyecto, Add, New Item.., en la ventana que aparece, seleccionamos Reporting y escogemos el tipo de reporte Crystal Report:

Asignamos un nombre al reporte que se guarda con la extensin .rpt, y clic al botn Add para crear el reporte en nuestro proyecto.

Aparece la siguiente pantalla para seleccionar el tipo de reporte a crear, en la parte izquierda sealado en el circulo rojo aparece una nueva barra de

herramientas con la cual vamos a trabajar al adicionar los campos al reporte, en la parte derecha, he resaltado en el circulo rojo que se agregan al proyecto de manera automtica las referencias necesarias para que funcionen los reporte de Crystal Reports en nuestro proyecto. De la ventana, seleccionamos la segunda opcin, crear un reporte en blanco As a Blank Report

Al darle clic al boton OK de la pantalla anterior nos muestra el reporte en blanco como aparece en la imagen anterior. La seccin de Report Header, colocaremos lo que queremos que aparezca solo en la primera hoja del reporte. En la seccin Page Header, colocaremos los que queremos se muestre en la cabecera de todas las paginas del reporte, aqu colocaremos los ttulos de las columnas, por ejemplo. En la seccin Details, colocaremos el detalle de las columnas del reporte La seccin Report Footer, es la contraparte de la del Page Header, aqu podramos colocar los nmeros de pagina del reporte, por ejemplo. La seccin Page Footer es la contraparte de Report header.

Ya teniendo claro esto, lo siguiente es seleccionar la fuente de datos de nuestro reporte, aqu es donde entra a jugar el dataset que creamos en pasos anteriores, pues no necesitamos tener la conexin a la base de datos abierta para disear nuestro reporte.

Damos Clic derecho en el Field Explorer en la entrada Database Field, al aparecer el men contextual de la imagen seleccionamos Database Expert para ir a seleccionar nuestra fuente de datos.

En esta ventana, expandimos Project Data, luego ADO.NET DataSets, aqu nos van a aparecer todos los dataset que tengamos creados en nuestro proyecto, en nuestro caso solo aparece dsPersonas, que es el que hemos creado en pasos anteriores. Seleccionamos el datatable y damos clic en el botn para pasar los datos a la parte derecha de la ventana en la cual va a exponer los campos del datable para poder incluirlos en nuestro reporte.

Hacemos clic en el botn OK para empezar a disear nuestro reporte. Al hacer esto, ya contamos con los campos del dataset en el Field Explorer:

Ahora simplemente es arrastrar los campos al rea del reporte y colocarlos de la manera como deseamos se vea el reporte.

Seleccionamos la Toolbox (barra de herramientas de crystal) y de all escogemos el control text object y lo arrastramos a la seccin de page header para colocar el titulo del reporte all, en la imagen estn seleccionados en crculos rojos todos los controles mencionados.

Al arrastrar un campo del datatable y soltarlo en la seccin de detalle de manera automtica coloca un control de texto para el titulo del control que acabamos de arrastrar.

Para corregir el texto del titulo, lo seleccionamos, le damos clic derecho al control y escogemos del men la opcin Edit Text Object, lo que nos permite cambiar el texto del titulo.

La imagen nos muestra como queda nuestro reporte, no es el alcance de este tutor, indicar como colocar los diferentes atributos de presentacin grafica del reporte. En nuestro formulario windows (web forms) o en nuestro formulario web (web forms) agregamos un control CrystalReportViewwer , el cual nos servir para mostrar nuestro reporte en pantalla y poder imprimirlo o exportarlo a algn formato como PDF o Excel. En el boton Imprimir de nuestro formulario, el codigo que voy a colocar para ir a la base de datos, realizar la consulta de los datos, colocarlos en un datatable y este datatable pasarlo a la propiedad datasource del reporte. A continuacion el codigo del boton imprimir: Private Sub btnImprimir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImprimir.Click Dim oCnn As New OleDbConnection Objeto de conexion a la base de datos Dim daDatos As New OleDbDataAdapter Objeto Adaptador para leer datos de la Base de datos Dim cmdExec As New OleDbCommand objeto comando para ejecutar sentencias sql Dim dtDatos As New DataTable datatable para recibir los datos de la base de datos Dim sbQuery As New StringBuilder StringBuilder para armar cadenas Try oCnn.ConnectionString = "Provider=SQLNCLI10;Server=ralvarado;Database=MiBD;Uid=sa; Pwd=XXX;" oCnn.Open() cmdExec = oCnn.CreateCommand cmdExec.Connection = oCnn sbQuery.Append("SELECT Consecutivo ") sbQuery.Append(" ,IdentificacionPersona ") sbQuery.Append(" ,TipoPersona ") sbQuery.Append(" ,Grupo ") sbQuery.Append(" ,PrimerNombre ") sbQuery.Append(" ,PrimerApellido ") sbQuery.Append(" ,SegundoApellido ") sbQuery.Append(" ,Sexo ") sbQuery.Append(" ,Profesion ") sbQuery.Append(" ,Direccion1 ") sbQuery.Append(" ,Direccion2 ") sbQuery.Append(" ,TelFijo1 ")

sbQuery.Append(" ,TelFijo2 ") sbQuery.Append(" ,TelMovil ") sbQuery.Append(" ,PaginaWeb ") sbQuery.Append(" ,ZonaPostal ") sbQuery.Append(" ,Fax ") sbQuery.Append(" ,Email1 ") sbQuery.Append(" ,Email2 ") sbQuery.Append(" ,FechaNacimiento ") sbQuery.Append(" FROM Persona ") cmdExec.CommandText = sbQuery.ToString daDatos = New OleDbDataAdapter(cmdExec) daDatos.Fill(dtDatos) Dim CrReport As New CrystalDecisions.CrystalReports.Engine.ReportDocument ' Asigno el reporte CrReport = New CrystalDecisions.CrystalReports.Engine.ReportDocument() CrReport.Load(Application.StartupPath & "\crPersonas.rpt") CrReport.SetDataSource(dtDatos) CrystalReportViewer1.ReportSource = CrReport Catch ex As Exception MessageBox.Show("excepcion: " & ex.Message, "Mostrando Reporte") End Try End Sub Observen que al llenar los datos en dtDatos, simplemente debo asignarle este objeto al Reporte en su mtodo SetDataSource. Con esto puede ser cualquier base de datos, siempre y cuando los datos correspondan a la estructura del dataset creado como fuente de datos del reporte. Si en algn momento nuestro reporte cambia que hay que agregarle un nuevo campo, simplemente vamos a nuestro dataset y le agregamos el campo, luego vamos al reporte y lo abrimos y verificamos nuestra fuente de datos para que nuestro nuevo campo aparezca en al lista, luego es simplemente incluirlo en el reporte.

Bueno espero haber sido claro en como crear un reporte con Crystal Report y les aseguro que no van a tener problemas al momento de modificaciones en el reporte.

Vous aimerez peut-être aussi