jueves, 2 de diciembre de 2010

Como cambiar de Color a tus Barras segun su valor


Hola espero que les haya gustado mi artículo anterior, esta vez voy a explicarles como personalizar reportes usando Reporting Services, en este caso vamos a dar  color a las barras de un gráfico  dependiendo de su valor.
Veamos. Tenemos la siguiente tabla 
 dbo.Indicador

dbo.InfoEvaluado
Usare el siguiente Stored Procedure

CREATE PROCEDURE [dbo].[USP_SeleccionarScore]
@IdInfoEvaluado int
as 
  SELECT IdInfoEvaluado, codIndicador, Tipo = 'ESTUDIANTIL' ,valor=Convert(decimal,valor1)/100
  FROM Indicador where IdInfoEvaluado = @IdInfoEvaluado and  
  codIndicador = 'SCORE'
  union   
  SELECT IdInfoEvaluado, codIndicador, Tipo = 'VEHICULAR' ,valor= Convert(decimal,valor2)/100
  FROM Indicador where IdInfoEvaluado = @IdInfoEvaluado and  
  codIndicador = 'SCORE'
  union
  SELECT IdInfoEvaluado, codIndicador, Tipo = 'HIPOTECARIO' ,valor =Convert(decimal,valor3)/100
  FROM Indicador where IdInfoEvaluado = @IdInfoEvaluado and  
  codIndicador = 'SCORE' 
  order by valor
 
y el siguiente script
SELECT        IdInfoEvaluado, Apellidos + ', ' + Nombre AS NombreCompleto
FROM            InfoEvaluado
El Diseño del reporte quedaria de esta manera.

 En el chart data vamos a colocar los datos de esta forma.
Hasta acá todo es sencillo, como verán el reporte por defecto nos muestra las barras del mismo color pero nosotros necesitamos que las barras cambien de color dependiendo del valor que tienen. En este caso voy colocar las siguientes condiciones, si el valor esta entre 0 y 45 va a ser Rojo, si el valor esta entre 46 y 80 va a ser Amarillo y si el valor esta entre 81 y 100 es Verde,

 Ahora bien vamos a colocar la siguiente expresión. Para esto hacemos click derecho en el Chart Series llamado Valor, y seleccionamos Series Properties
Note que cuando selecciona un Chart Series aparecen unos puntos blancos sobre las barras.

 Hacemos Click en el botón fx y se nos muestra la siguiente pantalla.


Y como observaran he colocado un código muy simple. Que paso a mostrar.
=Switch(SUM(Fields!valor.Value)*100>=0 and SUM(Fields!valor.Value)*100<=40,
"Red",SUM(Fields!valor.Value)*100>40 and SUM(Fields!valor.Value)*100<=80,
"Yellow",SUM(Fields!valor.Value)*100>80 and SUM(Fields!valor.Value)*100<=100,
"Green")
Le dan aceptar y listo hacemos un preview y nos mostrara el siguiente gráfico.
Espero que este mini tutorial les haya servido. Y hasta la próxima….

Algo más pueden cambiar su expresión por este otro... en el caso que quieran  mostrar de diferente color cada barra según la fila.
=iif(RowNumber(Nothing)=1,"Red",iif(RowNumber(Nothing)=2,
"Yellow","Green"))

domingo, 28 de noviembre de 2010

Crear una columna de botones con imagen usando la clase DataGridViewButtonColumn

En esta oportunidad voy a dejarlos un ejemplo de como podemos personalizar nuestro DataGridView, en este caso voy a mostrar como usar imagenes usando la clase DataGridVIewButton... espero que les sirva ^^!.

Cuando presentamos un conjunto de datos en forma tabular mediante el control DataGridView, hay ocasiones en las que se necesita proporcionar al usuario la posibilidad de realizar ciertas operaciones, en base a uno o varios valores situados en las celdas de una determinada fila del control.

Por ejemplo, en el formulario que vemos en la siguiente imagen se muestra un DataGridView con algunos campos de la tabla DimProduct, perteneciente a la base de datos AdventureWorksDW. El objetivo consiste en que el usuario pueda introducir en el TextBox un valor, que representa un porcentaje de descuento a aplicar sobre el campo ListPrice, de la fila del DataGridView que seleccione.

Entre las diversas técnicas disponibles para realizar la operación que acabamos de mencionar, en este artículo vamos a hacer uso de las clases DataGridViewButtonColumn y DataGridViewButtonCell, que combinaremos para crear, dentro del control DataGridView, una nueva columna calculada, cuyas celdas contengan botones, que al ser pulsados, nos permitan realizar una operación con los valores de otras celdas de la fila seleccionada. Como particularidad añadida, los botones de nuestra nueva columna contendrán una imagen.
En primer lugar crearemos, en Visual Studio 2008, un nuevo proyecto de tipo Windows Forms Application, al que daremos el nombre DGVColumnaBotonesImagen, añadiendo al diseñador del formulario los controles mostrados en la anterior imagen.
Seguidamente pasaremos al editor de código del formulario, y en su evento Load escribiremos el siguiente bloque de código, que usaremos para conectarnos a una base de datos y cargar el DataGridView con un subconjunto de los registros de la tabla.
using System.Data.SqlClient;
//....
namespace DGVColumnaBotonesImagen
{
public partial class Form1 : Form
{
    //....

    private void Form1_Load(object sender, EventArgs e)
    {
        SqlConnection cnConexion = new SqlConnection();
        cnConexion.ConnectionString = "Data Source=localhost;" +
            "Initial Catalog=AdventureWorksDW;" +
            "Integrated Security=True";

        string sSQL = "SELECT ProductKey, SpanishProductName, ListPrice " +
            "FROM DimProduct WHERE ListPrice IS NOT NULL";

        SqlCommand cmdComando = new SqlCommand(sSQL, cnConexion);
        SqlDataAdapter daAdaptador = new SqlDataAdapter(cmdComando);
        DataTable tblDimProduct = new DataTable();
        daAdaptador.Fill(tblDimProduct);
        this.dataGridView1.DataSource = tblDimProduct;
        //....
    }
    //....
A continuación definiremos nuestra columna personalizada creando una instancia de la clase DataGridViewButtonColumn, que añadiremos a la colección de columnas del DataGridView.
private void Form1_Load(object sender, EventArgs e)
{
    //....
    DataGridViewButtonColumn colBotones = new DataGridViewButtonColumn();
    colBotones.Name = "colBotones";
    colBotones.HeaderText = "Valor Stock";

    this.dataGridView1.Columns.Add(colBotones);
}
La siguiente imagen muestra el resultado.

El anterior código crea una nueva columna basada en botones, pero estos carecen de contenido. Para incluir una imagen en su interior crearemos un manipulador para el evento CellPainting del control, en el que realizaremos las siguientes operaciones:
En primer lugar comprobaremos si la celda a pintar corresponde a nuestra columna de botones y se encuentra en una fila válida; en caso afirmativo, pintamos la celda ejecutando el método DataGridViewCellPaintingEventArgs.Paint. Seguidamente obtenemos una instancia del botón situado en la celda y otra de la imagen (un icono en este ejemplo) a situar en su interior, dibujando esta mediante el método Graphics.DrawIcon, con un tamaño ligeramente inferior al del botón.
Finalmente, para poder visualizar de forma más adecuada el botón, ajustamos las dimensiones de la fila y columna que lo alojan en función de las dimensiones de la imagen. También debemos asignar el valor true a la propiedad DataGridViewCellPaintingEventArgs.Handled, que nos servirá para que el control tenga en cuenta la implementación que hemos realizado sobre este evento.
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex >= 0 && this.dataGridView1.Columns[e.ColumnIndex].Name == "colBotones" && e.RowIndex >= 0)
    {
        e.Paint(e.CellBounds, DataGridViewPaintParts.All);

        DataGridViewButtonCell celBoton = this.dataGridView1.Rows[e.RowIndex].Cells["colBotones"] as DataGridViewButtonCell;
        Icon icoAtomico = new Icon(Environment.CurrentDirectory + @"\Atomico.ico");
        e.Graphics.DrawIcon(icoAtomico, e.CellBounds.Left + 3, e.CellBounds.Top + 3);

        this.dataGridView1.Rows[e.RowIndex].Height = icoAtomico.Height + 10;
        this.dataGridView1.Columns[e.ColumnIndex].Width = icoAtomico.Width + 10;

        e.Handled = true;
    }
}
En la siguiente imagen podemos ver el control con la columna resultante, incluyendo los botones con el icono.

Tan sólo resta añadir al botón la lógica que efectúe el cálculo del descuento comentado al comienzo del artículo, aspecto este que resolveremos codificando el evento CellClick del DataGridView. Al producirse este evento comprobaremos si existe valor en el TextBox del formulario, y en caso afirmativo, nos cercioraremos de que la celda sobre la que se ha realizado la pulsación corresponde a nuestra columna calculada, si esto se cumple, procederemos con el cálculo, mostrándolo en una caja de mensaje.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (this.txtPorcentaje.Text == string.Empty)
    {
        MessageBox.Show("Introducir valor para el porcentaje");
        this.txtPorcentaje.Focus();
    }
    else
    {
        if (this.dataGridView1.Columns[e.ColumnIndex].Name == "colBotones")
        {
            decimal nListPrice = (decimal)this.dataGridView1.Rows[e.RowIndex].Cells["ListPrice"].Value;
            int nPorcentaje = int.Parse(this.txtPorcentaje.Text);
            decimal nDescuento = (nListPrice * nPorcentaje) / 100;

            MessageBox.Show(nDescuento.ToString("#,#.##"), "Descuento aplicable");
        }
    }
}
La siguiente imagen muestra el resultado de una operación.