miércoles, 26 de noviembre de 2008

¡Increible pero cierto!

Pues sí, todavía no salgo de mi asombro. Acostumbrado como estoy a tener que desechar memorias USB (o pendrives, como los llaman algunos) de estas que te regalan con publicidad, porque a la más mínima, o pierden todos los archivos que tenías, o directamente "se morían".

Bueno, pues el caso es que tenía uno con llavero incorporado, en el que llevaba unas llaves, y no es que lo usara mucho, pero como lo llevaba siempre encima (por las llaves) me había sacado de algún que otro apuro.

La semana pasada perdí dicho llavero, y por fin ayer aparecieron: lavadas, centrifugadas y casi casi planchadas. Cuál sería mi sorpresa cuando esta mañana llego al curro, pincho la memoria (por simple curiosidad y sin ninguna esperanza) y ¡Oh maravilla! ahí estaban todos los archivos intactos.

Sí, ya sé que las memorias USB no llevan batería ni ninguna corriente eléctrica que pueda provocar cortocircuitos en contacto con el agua, pero cuántas he perdido por muchísimo menos.

En fin, la lástima es que no sé la marca ni nada para cuando tenga que comprar una.

jueves, 25 de septiembre de 2008

Creación de aplicaciones con Iceberg

Hola a todos.
He estado viendo en distintos blogs información sobre Iceberg, una aplicación que permite crear aplicaciones web "sin una sola línea de código".
La propuesta parece interesante, así que me he lanzado a instalarlo. En primer lugar, comentar que es gratuita para organizaciones sin ánimo de lucro, para el resto hasta un máximo de 5 usuarios.
A partr de los 5 usuarios cada licencia cuesta 200$ negociables por volumen. La aplicación se instala sobre la plataforma .net de microsoft, permite gestonar roles y usuarios, así como calendarios para gestionar los proyectos.
Para crear nuestra primera aplicación disponemos de un asistente para diseñar los objetos de negocio, las relaciones entre ellos y los formularios para la toma de datos. Para crear acciones más específicas disponemos del gestor de flujos de trabajo. En posts sucesivos seguiré comentando las impresiones que me vaya causando el producto.
Saludos a todos.

miércoles, 17 de septiembre de 2008

Control calendario: funcionalidad de cambio de mes y año

    protected void next_Click(object sender, EventArgs e)
    {
        Mes = Convert.ToInt16(DropDownList1.SelectedValue.ToString());
        Ano = Convert.ToInt16(DropDownList2.SelectedValue.ToString());
        if (Mes == 12)
        {
            Mes = 1;
            Ano += 1;
        }
        else
            Mes += 1;

        this.DropDownList1.SelectedValue = Mes.ToString();
        this.DropDownList2.SelectedValue = Ano.ToString();
    }
    protected void prev_Click(object sender, EventArgs e)
    {
        Mes = Convert.ToInt16(DropDownList1.SelectedValue.ToString());
        Ano = Convert.ToInt16(DropDownList2.SelectedValue.ToString());
        if (Mes == 1)
        {
            Mes = 12;
            Ano -= 1;
        }
        else
            Mes -= 1;

        this.DropDownList1.SelectedValue = Mes.ToString();
        this.DropDownList2.SelectedValue = Ano.ToString();
    }

martes, 16 de septiembre de 2008

Control calendario: mostrar los datos del datatable

De la misma manera que construimos la tabla del calendario, dentro da cada una de las celdas, montaremos otra tabla con los datos datos del DataTable, pero filtrando únicamente los correspondientes a la fecha que estamos tratando:
System.Data.DataTable datos = datos_fecha_agrupa(indice);
la variable indice es la que itera por las fechas del mes, y la función datos_fecha_agrupa devuelve un DataTable con los datos a mostrar:


    // Devuelve un datatable con los datos a mostrar para cada fecha.
    //
    // La primera columna es la fecha.
    // 
    // Si agrupar es true agrupa por la segunda columna y totaliza por la tercera.
    //
    // El origen de datos debe estar ordenado por la columna a agrupar.

    public DataTable datos_fecha_agrupa(DateTime fecha)
    {
        string artAnt = "";
        double cantAcum = 0;
        bool primero = true;
        object[] valores = new object[2];
        if (datosglobal == null)
            return null;
        DataTable datos = datosglobal;
        if (datos.Rows.Count == 0)
            return null;            // Si no hay datos, no hace nada

        if (agrupar)
        {
            Int32 total = 0;
            Int32 totalAnt = 0;
            DataTable salida = new DataTable();
            salida.Columns.Add("Artículo", System.Type.GetType("System.String"));
            salida.Columns.Add("Cantidad", System.Type.GetType("System.Double"));

            foreach (DataRow fila in datos.Rows)
            {
                if (Convert.ToDateTime(fila.ItemArray[0]).Equals(fecha))
                {
                    string art = fila.ItemArray[1].ToString();
                    double cantidad= (double)fila.ItemArray[2];
                    if (disponible)
                    {
                        total = (Int32)fila.ItemArray[3];
                    }
                    if (art.Equals(artAnt))
                    {
                        cantAcum += cantidad;
                    }
                    else
                    {
                        if (primero)
                        {
                            primero = false;
                        }
                        else
                        {
                            valores[0] = (object)artAnt;
                            if (disponible)
                                valores[1] = (object)(totalAnt - cantAcum);
                            else
                                valores[1] = (object)cantAcum;
                            salida.Rows.Add(valores);
                        }
                        artAnt = art;
                        cantAcum = cantidad;
                        if (disponible)
                            totalAnt = total;
                    }
                }
            }
            if (!primero)
            {
                valores[0] = (object)artAnt;
                if (disponible)
                    valores[1] = (object)(totalAnt - cantAcum);
                else
                    valores[1] = (object)cantAcum;
                salida.Rows.Add(valores);
            }
            return salida;
        }
        else
        {
            int campos=datos.Columns.Count-1;
            DataTable salida2 = new DataTable();
            foreach (System.Data.DataColumn dcolumna in datos.Columns)
            {
                if(!dcolumna.ColumnName.Equals("Fecha"))
                    salida2.Columns.Add(dcolumna.ColumnName, dcolumna.DataType);
            }
            foreach (System.Data.DataRow dfila in datos.Rows)
            {
                object[] val=new object[campos];
                if (Convert.ToDateTime(dfila.ItemArray[0]).Equals(fecha))
                {
                    for(int i=1;i<=campos;i++)
                        val[i-1]=dfila.ItemArray[i];
                    salida2.Rows.Add(val);
                }
            }
            return salida2;
        }
    }

lunes, 15 de septiembre de 2008

Control calendario: comentarios.

Como vemos, lo que hacemos es construir una tabla HTML a la que vamos dando formato en función de las características del mes seleccionado y de los datos a mostrar, ya que habrá que comenzar a escribir en el calendario en la primera fila y en la columna correspondiente al día de la semana del primer día del més. De la misma manera, hay que terminar cuando se alcance el final del mes y no seguir rellenando las celdas. Para esto se utilizan las variables comenzar y final. Así, en las celdas de la tabla que corresponden a los días del mes haremos lo siguiente:
  • Escribir el día del mes.
  • crear un link a la url que le pasemos al control como propiedad, añadiendole el parámetro ?fecha=fecha_seleccionada.
  • cambiar el color del fondo.
  • escribir los datos del DataTable correspondientes a la fecha en curso.

viernes, 29 de agosto de 2008

Control de calendario: construcción dinámica de la tabla.

Utilizaremos una tabla de 6 filas y 7 columnas
La variable de tipo fecha indice, recorre todos los días del mes, diasemini contiene el día de la semana del primer día del mes para controlar en qué columna de la primera fila empezamos a pintar los días. Comenzar y final de tipo boolean marcarán el comienzo y el fin de los días que se pintan en la tabla.

<%
    DateTime indice = fini;
    cFechas dfechas = new cFechas();
    int diasemini = (int)fini.DayOfWeek;
    bool comenzar = false;
    bool final = false;
    if (diasemini == 0)
    {
        diasemini = 7;
    }
%>
    <h1><%Response.Write(this.DropDownList1.SelectedItem.ToString()+" de "+this.DropDownList2.SelectedItem.ToString()); %></h1>
    <table cellpadding="2px" cellspacing="0px" >
    <tr align='center'><td>Lunes</td><td>Martes</td><td>Miércoles</td><td>Jueves</td><td>Viernes</td><td>Sábado</td><td>Domingo</td></tr>
<%
    for (int fila = 1; fila <= 6; fila++)
    {
%>
        <tr valign='top'>
<%
        for (int col = 1; col <= 7; col++)
        {

            Response.Write("<td style='border: 1px solid #000000; font-size: small; vertical-align: top; text-transform: lowercase; width: "+ancho+"; height: 50px; ");
            if (!final)
            {
                if (!comenzar)
                {
                    if (col == diasemini)
                        comenzar = true;
                    else
                        Response.Write("'>");
                }
                if (comenzar)
                {
                    Response.Write(" background-color: #DE9600; color: #A50031;'>");
                    if (!url.Equals("nada"))
                        Response.Write("<a href='"+ url + "?fecha="+indice.ToShortDateString()+"' target='_blank'>");
%>
                    <div style='text-align:right; font-size:x-large; font-weight:bold'><% Response.Write(indice.Day.ToString());%>
                    </div>
<%
                    if (!url.Equals("nada"))
                        Response.Write("</a>");
                    int diasem = (int)indice.DayOfWeek;
                    if (diasem == 0) diasem = 7;
                    //                    System.Data.DataTable datos = dfechas.ocupado(indice);
                    System.Data.DataTable datos = datos_fecha_agrupa(indice);

                    Response.Write("<table width='"+ ancho+"'>");

                    if (datos!=null && datos.Rows.Count>0)
                    {
                        foreach (System.Data.DataRow dfila in datos.Rows)
                        {
                            Response.Write("<tr>");
                            int i=0;
                            foreach (System.Data.DataColumn dcolumna in datos.Columns)
                            {
                                if (agrupar && i == 1)
                                {
                                    Response.Write("<td align='right'>");
                                }
                                else
                                {
                                    Response.Write("<td>");
                                }
                                Response.Write(dfila.ItemArray[i].ToString());
                                Response.Write("</td>");
                                i++;
                            }
                            Response.Write("</tr>");
                        }
                    }
                    Response.Write("</table>");
                    if (indice.CompareTo(ffin) >= 0) final = true;
                    indice = indice.AddDays(1);
                }
            }
            else
                Response.Write("'>");
                
            Response.Write("</td>");
        }      
        Response.Write("</tr>");
    }
    Response.Write("</table>");

        
%>

jueves, 28 de agosto de 2008

Calendario: primer paso, crear el control de usuario y definir las propiedades

En primer lugar, creo un control de usuario, y lo llamo calendariomuestra.ascx.
Creo dos botones para ir al mes anterior y al siguiente y dos DropDownList para seleccionar el mes y el año:

<asp:Button ID="prev" runat="server" onclick="prev_Click" Text="<" /> 
<asp:Button ID="next" runat="server" onclick="next_Click" Text=">" /> 
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
onselectedindexchanged="DropDownList1_SelectedIndexChanged"> 
  <asp:ListItem Value="1">Enero</asp:ListItem> 
  <asp:ListItem Value="2">Febrero</asp:ListItem> 
  <asp:ListItem Value="3">Marzo</asp:ListItem> 
  <asp:ListItem Value="4">Abril</asp:ListItem> 
  <asp:ListItem Value="5">Mayo</asp:ListItem> 
  <asp:ListItem Value="6">Junio</asp:ListItem> 
  <asp:ListItem Value="7">Julio</asp:ListItem> 
  <asp:ListItem Value="8">Agosto</asp:ListItem> 
  <asp:ListItem Value="9">Septiembre</asp:ListItem> 
  <asp:ListItem Value="10">Octubre</asp:ListItem> 
  <asp:ListItem Value="11">Noviembre</asp:ListItem> 
  <asp:ListItem Value="12">Diciembre</asp:ListItem> 
</asp:DropDownList> 
<asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="True" 
onselectedindexchanged="DropDownList2_SelectedIndexChanged"> 
  <asp:ListItem>2006</asp:ListItem> 
  <asp:ListItem>2007</asp:ListItem> 
  <asp:ListItem>2008</asp:ListItem> 
  <asp:ListItem>2009</asp:ListItem> 
  <asp:ListItem>2010</asp:ListItem> 
  <asp:ListItem>2011</asp:ListItem> 
  <asp:ListItem>2012</asp:ListItem> 
<asp:ListItem></asp:ListItem> 
</asp:DropDownList> 


Y en el fichero de código defino las propiedades:

public DateTime fini = Convert.ToDateTime("1/7/2008");
public DateTime ffin = Convert.ToDateTime("31/7/2008");
// Contendrán las fechas de inicio y fin del mes seleccionado

private int _mes;
private int _ano = System.DateTime.Today.Year;
private string _ancho; // anchura de las columnas del calendario.
private string _url = "nada"; // url de la página a la que enlaza cada fecha.
private DataTable _datosglobal=new DataTable(); //Datos con las fechas

public int Mes
{
  get
  {
    return _mes;
  }
  set
  {
    _mes = value;
    if (_ano > 0)
    {
      fini = Convert.ToDateTime("1/" + _mes.ToString() + "/" + _ano.ToString());
      ffin = Convert.ToDateTime(System.DateTime.DaysInMonth(_ano, _mes).ToString() +
      "/" + _mes.ToString() + "/" + _ano.ToString());
    }
  }
}

public int Ano
{
  get
  {
    return _ano;
  }
  set
  {
    _ano = value;
    if (_mes > 0)
    {
      fini = Convert.ToDateTime("1/" + _mes.ToString() + "/" + _ano.ToString());
      ffin = Convert.ToDateTime(System.DateTime.DaysInMonth(_ano, _mes).ToString()
      + "/" + _mes.ToString() + "/" + _ano.ToString());
    }
  }
}
public string ancho
{
  get
  {
    return _ancho;
  }
  set
  {
    _ancho = value;
  }
}
public string url
{
  get
  {
    return _url;
  }
  set
  {
    _url = value;
  }
}

public DataTable datosglobal
{
  get
  {
    return _datosglobal;
  }
  set
  {
    _datosglobal = value;
  }
}
protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    Mes = Convert.ToInt16(System.DateTime.Today.Month);
    Ano = Convert.ToInt16(System.DateTime.Today.Year);
    this.DropDownList1.SelectedValue = Mes.ToString();
    this.DropDownList2.SelectedValue = Ano.ToString();
  }
}