lunes, 13 de septiembre de 2010

Filtrar y Ordenar un DataTable con un DataView

Los que usamos DataTables para llenar controles de .NET como DataGrids, ComboBox, CheckBoxList, etc., generalmente obtenemos los datos de una consulta SQL, y como bien saben, en ella podemos agregar filtros y ordenamiento de la información.

¿Pero que pasa en los casos en que el DataTable se llena manualmente o los datos son manipulados con código?, por ejemplo la traducción de los Nombres de los Productos. No siempre los filtros o el ordenamiento lo podemos hacer en el origen o mediante una consulta SQL.

Usando algunos de los métodos y propiedades de los DataViews de System.Data podemos lograr el objetivo, por ejemplo:

//Llenamos un DataTable con la información requerida
DataTable myDT = mifuncionLlenado();

//Creamos un DataView com el DataTable
DataView myDV = new DataView(myDT);

/*Para ordenar los datos usamos la propiedad Sort del DataView con el campo o los campos con los que queremos hacerlo, muy parecido a SQL*/
myDV.Sort = "nombreProducto ASC";

/*Y para filtrarlo usamos la propiedad RowFilter*/
myDV.RowFilter = "productoTipo = 1";

//Establecidas las propiedades llenamos un Control con el DataView
this.myDataGrid1.DataSource = myDV;

/*Y todavia podemos llenar otro control con el mismo DataView pero con diferente filtro*/
myDV.RowFilter = "productoTipo = 2";
this.myDataGrid.DataSource = myDV;

El DataView puede ser la vista de un DataTable al que se le puede aplicar filtros, ordenamiento, entre otras cosas, pero haciendolo en memoria.

Espero sea de ayuda y apoyo este artículo.

Happy Coding!!

Fuente: http://msdn.microsoft.com/es-es/library/system.data.dataview(VS.80).aspx

miércoles, 1 de septiembre de 2010

Transacciones en SQL Server 2005

Después de un rato de no estar por aquí regreso con esta pequeña entrada que se me hace muy interesante y sobre todo útil. Las Transacciones sobre SQL Server son de mucha ayuda al realizar consultas algo complejas que impliquen afectar de manera riesgosa la integridad de la tablas en la Base de Datos.

Todo lo que se incluya dentro de la sección de la Transacción se realizará, a menos que ocurra un problema, ya que si esto pasa, todo lo que se llevaba hecho hasta entonces regresará a su estado anterior... como si nunca hubiera pasado nada.

Y utilizando el Try... Catch SQL Server podran obtener cierta información el error ocurrido.

BEGIN TRY
BEGIN TRANSACTION
--Codigo riesgoso aqui. Lo que sigue es ejemplo
declare @d decimal
set @d = (select 5 / 0)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
select 'Lo sentimos ocurrio un Error. Revise los siguientes datos para mas información.' as Mensaje, error_number() AS Numero_de_Error, error_severity() AS Gravedad_del_Error, error_state() AS Estado_del_Error, error_procedure() AS Procedimiento_del_Error, error_line() AS Linea_de_Error, error_message() AS Mensaje_de_Error;
ROLLBACK TRANSACTION
END CATCH

Como conclusión, el uso de las Transacciones protege los datos de la Base de Datos ante un error ocurrido durante la ejecución de las querys. De esa manera, se pueden ejecutar con mucho mas confianza.

Happy Coding!!

jueves, 3 de abril de 2008

Calendario en Javascript

Crear un calendario en javascript es muy útil, por su aspecto vistoso. La forma para mostrarlo va a ser utilizando un botón y un textbox; es decir al dar clic en el botón se va a mostrar el calendario y después de elegir una fecha, ésta se mostrará en el textbox.

El procedimiento para realizarlo es el siguiente:

1. Se agrega en la carpeta del proyecto los scripts (estilos).

2. Después dentro de Head en el código HTML, se escribe el siguiente código:















Es importante mencionar que el calendario que se va a mostrar, va a ser dependiendo de los scripts que nosotros elijamos, ya que existen distintos estilos para mostrar, además de otros idiomas.

3. Por ultimo, dentro de body en el codigo HTML, se escribe el siguiente código:









Donde en inputField va a ir el nombre del textbox, en ifFormat el formato de la fecha que se va a mostrar en el textbox y button el nombre del botón.

Si se desea presentar el calendario con solo pulsar un textbox, el código es el siguiente:









Este código es similar al del paso 3, solo que en este caso en button se va a escribir el nombre del textbox, para que cuando pulsemos sobre el textbox se muestre el calendario sin la necesidad de pulsar un botón.

Espero les sea de gran ayuda este código para crear un calendario.

Abrir un popup (ventana emergente) y actualizar la ventana padre

La idea principal es abrir un popup (ventana emergente) y producir algún cambio en las variables o base de datos, al mismo tiempo que se presiona un botón y se ven los cambios en la página padre que abrió la ventana emergente.

Es muy fácil realizar la actualización, para ello es necesario copiar el siguiente código en las dos ventanas (padre e hijo) como se explica a continuación:

Ventana Padre

En el load se escribe el siguiente código:






NOTA: La línea que va antes de eventtarget son dos guión bajo seguidos.

En el botón Abrir se escribe el siguiente código para mostrar la ventana emergente o ventana hijo:




Ventana Hijo

En el botón Guardar se escribe el siguiente código para mostrar un mensaje y actualizar:




NOTA: La línea que va antes de doPostBack son dos guión bajo seguidos.

Como ven, es muy sencillo actualizar los datos.

Espero que les sea de mucha utilidad.

martes, 11 de marzo de 2008

HotSpots en ImageMap …áreas circulares en una imagen que causan postbak al dar clic sobre ellas.

El control ImageMap es usado para desplegar una imagen clickeable en una página web que puede ser usada para hacer un PostBack al WebServer, o para abrir otra página siguiendo una URL.

A diferencia del control ImageButton, este permite definir regiones “hot-spots” de formas circulares CircleHotSpot, Rectangulares RectangleHotSpot, y Poligonales PolygonHotSpot que causan PostBack cuando el usuario da clic en ellas, mientras que en un ImageButton dando clic en cualquier parte de la imagen se hace un PostBack.

El primer HotSpot definido toma precedencia sobre los demás, por ejemplo si tenemos dos CircleHotSpot el primero con un radio menor al segundo y ambos con el mismo centro.

El círculo menor quedaría dentro del segundo pero su área clickeable siempre estaría activa y limitada por el área mayor.

Para el siguiente ejemplo, primero Agregaremos un ImageMap y un Label a nuestra página:

Como serán utilizadas varias zonas circulares o CircleHotSpot ara ello he creado un procedimiento que recibe las coordenadas en (x,y) del centro, el radio y la descripción en este caso el valor que será devuelto al hacer el PostBack.

public void zona_circular(int x, int y,int radio,string descripcion)

{

CircleHotSpot chs;

chs = new CircleHotSpot();

chs.X = x;

chs.Y = y;

chs.Radius = radio;

chs.PostBackValue = descripcion;

ImageMap1.HotSpots.Add(chs);

}

En el evento Load de la página, establecemos la imagen que será mostrada en el ImageMap1, el AlternateText que será el comentario mostrado cuando se posicione el Mouse sobre el control y el HotSpotMode que da el comportamiento para los objetos HotSpot de un ImageMap cuando se hace clic en ellos, en este caso es PostBack pero puede ser Inactive (sin comportamiento), Navigate (se desplaza a una URL).

ImageMap1.ImageUrl = "~/images/homer.jpg";

ImageMap1.AlternateText = "This is a picture of Homero";

ImageMap1.HotSpotMode = HotSpotMode.PostBack;

Después llamaremos a la función zona_circular(X,Y,Radio,Descripción); cuantas veces sea necesario de acuerdo a las zonas que deseemos definir:

zona_circular(124, 151, 6, "Left Eye Center");

zona_circular(133, 145, 35, "Left Eye");

zona_circular(193, 145, 6, "Right Eye center");

zona_circular(183, 173, 20, "Nose");

zona_circular(155, 233, 50, "Mouth");

Finalmente en el evento clic del ImageMap agregamos la siguiente línea:

Label1.Text = "You clicked the " + e.PostBackValue;

Con esta línea traemos el valor asociado al funcionamiento del Hotspot.

De esta forma cada vez que demos clic en un área hotspot como resultado tendremos en la etiqueta o label el valor del PostBack.

En las imagenes puede apreciarse el mensaje del PostBackValue en el label después de haber dado clic en los HotSpots del ImageMap.



DataSet, XML y Flash

En ocaciones tenemos registros leidos desde la base de datos y almacenados en un DataSet, y se nos ocurre que podremos mostrarla en una aplicacion de Macromedia Flash, pues bien, Flash no tiene un soporte nativo para base de datos, pero si la lectura de archivos XML.

Pues bien para crear un archivo XML desde el DataSet basta lo siguiente:

'Esta es una clase que facilita la conexion y la ejecusion de consultas
Dim Conn As New Conectividad()
'Mi Objeto DataSet
Dim ds As New DataSet
'Llenamos el DataSet con el resultado de la consulta
ds = Conn.Consulta("Select * from datos", strError)
'E invocando al metodo WriteXml podemos crear tan facilmente un archivo XML
ds.WriteXml(Server.MapPath("MyXML.XML"), XmlWriteMode.IgnoreSchema)

Una ves creado el archivo XML, en Flash bastará este script para leer y mostrar cada uno de los registros del XML

//Este va en el fotograma 1
//Variables globales para control de recorrido por el XML
_global.pos=0;
_global.limite=0;

//Nuevo Objeto XML
var obj_xml:XML = new XML();
obj_xml.ignoreWhite = true;
//Esta Funcion sera invocada cuando se intente cargar un archivo XML
obj_xml.onLoad = function(exito) {
//La variable exito sera "true" si se cargo bien y "false" si el archivo no //existe o no se pudo cargar por errores en su estructura
if (exito) {
//Numero de registros
_global.limite=obj_xml.firstChild.childNodes.length;
//modelo, des y precio son los nombres de las instancias de componentes TextInput
modelo.text=obj_xml.firstChild.childNodes[_global.pos].childNodes[1].firstChild.nodeValue;
des.text=obj_xml.firstChild.childNodes[_global.pos].childNodes[3].firstChild.nodeValue;
precio.text=obj_xml.firstChild.childNodes[_global.pos].childNodes[2].firstChild.nodeValue;

//img es una instancia del componente Loader, al cual le indicamos la ruta de la //imagen a mostrar
img.contentPath=obj_xml.firstChild.childNodes[_global.pos].childNodes[4].firstChild.nodeValue;
img.load();
} else {
trace("Error"); //Que indique que hubo un error si no cargo el archivo
}
};


//Esta es la función que invoca la carga del archivo
function cargarXML() {
obj_xml.load("myXML.XML");
}

//Cargamos la funcion al iniciar
cargarXML();


Si deseamos un recorrido por cada uno de los registros deberemos incluir un boton de avance y otro de retroceso y escribir el siguiente script

//Boton retroceso
on (release) {
//Llamamos a la función de carga del archivo XML
_global.pos--;//Disminuimos la posicion actual
if (_global.pos<0) //Si se paso del indice 0
_global.pos=0; //Lo ponemos en 0
cargarXML(); //Cargamos el archivo nuevamente, pero con la posicion indicada
}

//Boton Avanzar
on (release) {
//Llamamos a la función de carga del archivo XML
_global.pos++;//aumentamos la posicion actual
if (_global.pos>_global.limite - 1) //Si nos pasamos del limite
_global.pos=_global.limite-1;// Ponemos el indice en el ultimo registro
cargarXML(); //Cargamos nuevamente el archivo
}

Espero y alguna ves les sea util este sencillo ejercicio

lunes, 10 de marzo de 2008

Desde el sotano....tool tips dinámicos

Cuando utilizamos un ToolTip en Visual Studio, solo puede ser utilizado directamente sobre un control de Windows Forms, por ejemplo un TextBox, una Label, un Button, etc., ya que solo acepta dos parámetros; el control y la cadena de Texto que mostrará.

toolTip1.SetToolTip(listBox1, “Este es mi Tip”);

Sin embargo, si se deseará que el ToolTip cambiará para cada elemento de un ListBox o de un ComboBox, no es tan sencillo ya que no acepta en sus parámetros un evento como SelectedIndex o SelectedValue.

En un “googlazo” me encontre con un algoritmo que mostraba como realizarlo. Ahora solo faltaba tomar la información de una Base de Datos y que el ToolTip cambiará para cada elemento de la lista. Y esto fue lo que sucedió:

1.- Se considera de antemano que se tiene listo todo el formulario completo, de acuerdo a las necesidades. Así mismo una Base de Datos, por ejemplo, un directorio telefónico. Entre esos controles se encuentra un ListBox, el cual fue llenado en su propiedad DataSource una consulta hecha a la Base de Datos. Digamos una lista de nombres, y que se desea mostrar en el ToolTip su telefono.

2.- Una vez tomado de la Caja de Controles un ToolTip, nos dirigimos al evento SelectedIndexChanged del listBox1 y comenzamos a codificar:

private void lst_users_SelectedIndexChanged(object sender, EventArgs e)
{

/*Creamos un nuevo DataTable auxiliar y en el almacenamos el DataSource que contenga el listBox, convirtiendolo previamente*/
DataTable dt_aux_u = (DataTable)this.lst_users.DataSource;

/*Se prepara una variable de tipo de string que almacenará el texto del ToolTip*/
string telefono = "";

/*En una variable de tipo entero, se almacena el indíce del elemento seleccionado de la lista, previamente convirtiendolo a entero*/
int index = (int)this.lst_users.SelectedIndex;

/*Si el indice del elemento seleccionado se encuentra entre el rango de la lista*/
if (index >= 0 && index <>
{

/*La variable telefono almacena del DataTable el valor donde la fila con valor index y la columna “telefono” coincida. Esto esta basado en la Base de Datos*/
telefono = dt_aux_u.Rows[index][“telefono"].ToString();

//Si lo seleccionado no contiene nada
if (telefono =="")
{

//Se prepara un texto especial, para que el ToolTip no se muestre vacio

telefono = "Esta persona no tiene telefono";
}
}

/*Al final, establecemos el ToolTip con el control Windows Forms y la Variable*/
this.toolTip1.SetToolTip(this.lst_users, telefono);
}

3.- Cabe determinar que es necesario tener funcionando primero el acceso a la Base de Datos y el llenado del listBox correctamente, ya que la informacion para llenar el Tooltip lo tomamos del DataSource del control.

Esperando que sea util, así comentarios y sugerencias.

Dr. Omm