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.
miércoles, 26 de noviembre de 2008
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();
}
{
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;
}
}
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>");
%>
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();
}
}
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();
}
}
Suscribirse a:
Entradas (Atom)