| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Mie 01 May, 2013 10:16 am Asunto: |
|
|
Muchisimas gracias _Leo, como siempre tus soluciones funcionan a la perfección
Saludos |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Lun 06 May, 2013 9:30 am Asunto: |
|
|
Hola de nuevo.
Sigo haciendo la aplicación para la ong y me ha surgido una duda con una secuencia SQL
La cuestión es el control de la lotería. Necesito hacer un filtro en el que alguno de los 3 componentes (o 2 o 3) esté activo
el código ahora es: | Código: | floteria->SQL->Clear();
if(Edit1->Text.Length())
Valor=" WHERE "+COLUMNALOT+" LIKE '%"+Edit1->Text+"%'";
else Valor="";
if(solosorteo->Text.Length()) // combobox
Valor+=" WHERE sorteo = '"+solosorteo->Text+"'";
if(nocobrados->Checked)
Valor+=" Where cobradas = false";
floteria->SQL->Add("SELECT *FROM LOTERIA"+Valor);
floteria->SQL->Add("ORDER BY "+COLUMNALOT);
floteria->Active=true;
|
La historia es:
- el primer filtro es un like de cualquier columna para poder filtrar lo que quieran
- el segundo es un combo en el que están todos los sorteos en los que se ha vendido lotería.
- el tercero es un check para que solo aparezcan los registros que estén pendientes de cobro
Por separado me aclaro, pero la union de 2 o 3 filtros.....
Gracias por vuestra ayuda
Saludos |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Lun 06 May, 2013 11:56 am Asunto: |
|
|
Tal vez sea algo enrevesado, pero yo haría algo así:
| Código: | floteria->SQL->Clear();
floteria->SQL->Text = "SELECT * FROM LOTERIA WHERE";
if(Edit1->Text.Length())
floteria->SQL->Text = floteria->SQL->Text + COLUMNALOT + " LIKE '%" + Edit1->Text + "%' &";
if(solosorteo->Text.Length()) // combobox
floteria->SQL->Text = floteria->SQL->Text + "sorteo = '" + solosorteo->Text + "' &";
if(nocobrados->Checked)
floteria->SQL->Text = floteria->SQL->Text + "cobradas = false &";
floteria->SQL->Text = floteria->SQL->Text.SubString(1, floteria->SQL->Text.LastDelimiter("&") - 1);
floteria->SQL->Text = StringReplace(floteria->SQL->Text, "&", "AND", TReplaceFlags() << rfReplaceAll);
floteria->SQL->Text = StringReplace(floteria->SQL->Text, "\r\n", " ", TReplaceFlags() << rfReplaceAll) + " ORDER BY " + COLUMNALOT; |
Te lo explico porque reconozco que es una poco raro: Supongamos que tienen valores Edit1->Text y nocobrados; tras pasar los tres condicionales te quedaría así el query:
| Código: | SELECT * FROM LOTERIA WHERE\r\n<COLUMNALOT> LIKE '%<Edit1->Text>%' &\r\ncobradas = false &"; |
Seguramente así veríamos el código del query con el depurador (evidentemente en COLUMNALOT y en Edit1->Text lo valores que correspondieran).
Despúes del SubString tendríamos esto:
| Código: | SELECT * FROM LOTERIA WHERE\r\n<COLUMNALOT> LIKE '%<Edit1->Text>%' &\r\ncobradas = false"; |
Después del primer StringReplace habríamos quitado todos los & y habría los respectivos AND:
| Código: | SELECT * FROM LOTERIA WHERE\r\n<COLUMNALOT> LIKE '%<Edit1->Text>%' AND\r\ncobradas = false"; |
Después del segundo StringReplace quedaría algo así:
| Código: | SELECT * FROM LOTERIA WHERE <COLUMNALOT> LIKE '%<Edit1->Text>%' AND cobradas = false ORDER BY <COLUMNALOT>"; |
Prueba y me dices. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Lun 06 May, 2013 12:19 pm Asunto: |
|
|
Muchas gracias Angel, pero te has olvidado que puede no haber ninguno de los 3 filtros.
Usando lo que me has enseñado lo he montado de esta forma y funciona
| Código: | floteria->SQL->Clear();
if(Edit1->Text.Length())
Valor=COLUMNALOT+" LIKE '%"+Edit1->Text+"%'";
else Valor="";
if(solosorteo->Text.Length()){ // combobox
if(Valor!="") Valor+=" AND ";
Valor+="sorteo = '"+solosorteo->Text+"'";
}
if(nocobrados->Checked){
if(Valor!="") Valor+=" AND";
Valor+=" cobradas = false";
}
if(Valor!="") whe=" WHERE ";
floteria->SQL->Add("SELECT *FROM LOTERIA"+whe+Valor);
floteria->SQL->Add("ORDER BY "+COLUMNALOT);
floteria->Active=true;
|
Muchas gracias por tu ayuda
lo de asignar a Valor y no asignarlo directo al SQL es por seguir el resultado en modo paso a paso y ver si se ha "colado" algo
Saludos |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Mar 07 May, 2013 12:36 am Asunto: |
|
|
| Angel escribió: | Me alegro de haber sido de ayuda.  |
pues voy a abusar un poco mas de tu sapiencia, si no te importa claro
Como se que te mueves muy bien entre fechas, quiero que me des una idea para solucionar un problemita | Código: | Valor=tsocis->FieldByName("fecha_alta")->Text; // Valor="05/05/2013"
if(Valor.Length()>10) Valor[11]=0;
if(Valor!="") fechalta->Date=StrToDate(Valor); // correcto
Valor=tsocis->FieldByName("fecha_nacimiento")->Text; // Valor="06/05/2013 13:23:60"
if(Valor.Length()>10) Valor[11]=0; // Valor="06/05/2013"
if(Valor!="") fnaci->Date=StrToDate(Valor); // Error
|
El error dice que no puede convertir "06/05/2013
Nótese que en el error faltan las comillas de cierre. Pues bien ahí es donde me pierdo, puesto que Valor tiene a mi entender las 2 fechas correctas.
El problema viene dado desde que saco la fecha en datetimepicker->Date que en teoría debería dar solo la fecha y no la fecha y la hora juntos. No me había dado cuenta del fallo hasta que me ha saltado el error al intentar poner fecha y hora juntos en el datetimepicker->Date. Por cierto, no lo hace siempre pero deberé comprobarlo
Gracias por permitirme "abusar" un poco mas de tu paciencia, Angel
Saludos |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Mie 08 May, 2013 10:29 am Asunto: |
|
|
¿Y por qué tienes declarado el campo en la tabla como texto? Sería más sencillo si fuera un campo fecha.
Lo que te da error me da la impresión que debe ser por que está entrando fecha y hora. Si SIEMPRE te entra como pones, con un espacio entre la fecha y al hora (dd/mm/yyyy hh:nn:ss) podrías coger sólo la parte hasta el espacio:
| Código: | Valor = tsocis->FieldByName("fecha_nacimiento")->Text;
Valor = Valor.SubString(1, Valor.Pos(" ")).Trim(); |
De esta manera la cadena (por ejemplo "06/05/2013 13:23:60") te quedaría sólo con la feca ("06/05/2013").
Otra cosa que yo haría sería poner un try catch(...):
| Código: | Valor = tsocis->FieldByName("fecha_alta")->Text.Trim();
if(!Valor.IsEmpty())
{
try
{
fechalta->Date = StrToDate(Valor);
}
catch(...)
{
}
} |
De esta manera te evitarías entradas erróneas o absurdas.
Otra cosa que me despistas es lo de Valor[11] = 0. Con eso estás AÑADIENDO un cero al final de cada fecha. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Mie 08 May, 2013 8:10 pm Asunto: |
|
|
Gracias Angel, Me acabas de volver loco. Yo creía que lo tenia todo bien y....
por partes, aunque no por orden:
lo del Valor[11]=0 es simplemente para cortar el String como si de un char se tratase. Siempre me ha funcionado. Al fin y al cabo un String debería ser un char muy largo ¿no?. Por cierto, Strings cuenta los caracteres a partir de 1 (por eso 11 y no 10)
Lo que quiero, como debes imaginarte por el nombre del campo que en la base de datos está definido como DATE short, es que SOLO me guarde la fecha. La hora no la quiero.
Porque pongo ->Text?
Si ponía ->Value y la fecha estaba vacía me daba error de conversión
Si ponía ->AsDate y la fecha contenía la hora me daba error de fecha incorrecta al cargarla en el datetimepicker. No se porque, ya que los datos salen de un datetimepicker y al devolverlos no los entiende
Así que solo me quedaba poner Text, pasarla a un String y con StrToDate ponerla en el datetimepicker.
En resumen, que lo que quiero es guardar en la base de datos SOLO la fecha y no se como hacerlo. Probaré a hacer | Código: | Valor = tsocis->FieldByName("fecha_nacimiento")->Text;
Valor = Valor.SubString(1, Valor.Pos(" ")).Trim();
| a ver si a la hora de guardar la fecha a la DB puedo evitar que esté la hora
Gracias por tu gran ayuda.
Saludos |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Mie 08 May, 2013 9:29 pm Asunto: |
|
|
| bosoft escribió: |
.
.
lo del Valor[11]=0 es simplemente para cortar el String como si de un char se tratase. Siempre me ha funcionado. Al fin y al cabo un String debería ser un char muy largo ¿no?. Por cierto, Strings cuenta los caracteres a partir de 1 (por eso 11 y no 10)
.
.
.
En resumen, que lo que quiero es guardar en la base de datos SOLO la fecha y no se como hacerlo. Probaré a hacer | Código: | Valor = tsocis->FieldByName("fecha_nacimiento")->Text;
Valor = Valor.SubString(1, Valor.Pos(" ")).Trim();
| a ver si a la hora de guardar la fecha a la DB puedo evitar que esté la hora
.
.
|
Y funciona. No lo entiendo, pero funciona
Muchas gracias por el consejo
Saludos |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 09 May, 2013 5:33 am Asunto: |
|
|
| bosoft escribió: | | Gracias Angel, Me acabas de volver loco. Yo creía que lo tenia todo bien y.... |
Si yo no digo que esté mal...
| bosoft escribió: | | lo del Valor[11]=0 es simplemente para cortar el String como si de un char se tratase. Siempre me ha funcionado. Al fin y al cabo un String debería ser un char muy largo ¿no?. Por cierto, Strings cuenta los caracteres a partir de 1 (por eso 11 y no 10) |
No se me había ocurrido nunca. Sí, se puede decir que un string es un char muy largo. Pero ten en cuenta que un char termina con un NULL (\0) y no con un cero.
| bosoft escribió: | | Lo que quiero, como debes imaginarte por el nombre del campo que en la base de datos está definido como DATE short, es que SOLO me guarde la fecha. La hora no la quiero. |
Lo entiendo; sin embargo es la primera vez que veo que si un campo es definido como DATE guarde también la hora. Al menos ni en Paradox ni en Firebird me ha ocurrido.
| bosoft escribió: | Porque pongo ->Text?
Si ponía ->Value y la fecha estaba vacía me daba error de conversión
Si ponía ->AsDate y la fecha contenía la hora me daba error de fecha incorrecta al cargarla en el datetimepicker. No se porque, ya que los datos salen de un datetimepicker y al devolverlos no los entiende
Así que solo me quedaba poner Text, pasarla a un String y con StrToDate ponerla en el datetimepicker.
En resumen, que lo que quiero es guardar en la base de datos SOLO la fecha y no se como hacerlo. Probaré a hacer
| Código: | Valor = tsocis->FieldByName("fecha_nacimiento")->Text;
Valor = Valor.SubString(1, Valor.Pos(" ")).Trim(); |
a ver si a la hora de guardar la fecha a la DB puedo evitar que esté la hora |
No dejes d poner un try...catch para controlar las posibles fechas erróneas. Cuando hablas de DATE short, ¿te refieres al formato dd/mm/yy? _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Jue 09 May, 2013 8:25 am Asunto: |
|
|
| Angel escribió: |
Si yo no digo que esté mal... |
Era un pensamiento en voz alta, en este caso, con letra ¿alta?
| Angel escribió: | No se me había ocurrido nunca. Sí, se puede decir que un string es un char muy largo. Pero ten en cuenta que un char termina con un NULL (\0) y no con un cero. |
En C puro, de donde vengo, es lo mismo un valor 0 que un null. Aunque normalmente se confunda por un valor 48 que equivale al carácter 0 y eso ya no es lo mismo
| Angel escribió: |
Lo entiendo; sin embargo es la primera vez que veo que si un campo es definido como DATE guarde también la hora. Al menos ni en Paradox ni en Firebird me ha ocurrido. |
Ya te comenté que usaría access y es lo que me está volviendo loco
| Angel escribió: |
No dejes d poner un try...catch para controlar las posibles fechas erróneas. Cuando hablas de DATE short, ¿te refieres al formato dd/mm/yy? |
Lo pongo, pero eso no me evita el error y las ganas de decirle cuatro cositas bien dichas al programador de access
Si, el short equivale dd/mm/yyyy. Y no, no veo por ninguna parte hh:mm:ss. ¿entonces porque narices lo aceptas? (otra vez pienso en voz alta)
Muchas gracias Angel.
Saludos |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 09 May, 2013 11:39 am Asunto: |
|
|
Te sugiero otra alternativa. Define el campo fecha como VARCHAR(8) y guarda la fecha como cadena en el formato yyyymmdd. Al convertirla podrías hacerlo así:
| Código: | tsocis->FieldByName("fecha_alta")->Text = fechaalta->Date.FormatString("yyyymmdd"); |
2. Para leerlo
| Código: | Valor = tsocis->FieldByName("fecha_alta")->Text; // Valor="20130505"
if (!Valor.IsEmpty())
fechaalta->Date = EncodeDate((Word)StrToInt(Valor.SubString(1, 4)),
EncodeDate((Word)StrToInt(Valor.SubString(5, 2)),
EncodeDate((Word)StrToInt(Valor.SubString(7, 2))); |
Te quitarías el dolor de cabeza de la hora. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Jue 09 May, 2013 12:28 pm Asunto: |
|
|
No lo había pensado. Lo probaré a ver como resulta. El dolor de cabeza me lo da el datetimerpicker, que mira que es malo de narices
He pensado incluso en hacer un edit para la fecha, porque es raro que a un componente te de el resultado mal
muchas gracias por la idea, Angel
Saludosa |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 09 May, 2013 3:31 pm Asunto: |
|
|
| bosoft escribió: | No lo había pensado. Lo probaré a ver como resulta. El dolor de cabeza me lo da el datetimerpicker, que mira que es malo de narices
He pensado incluso en hacer un edit para la fecha, porque es raro que a un componente te de el resultado mal
muchas gracias por la idea, Angel
Saludosa |
Us un TMaskEdit. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Jue 09 May, 2013 8:07 pm Asunto: |
|
|
| Angel escribió: |
Us un TMaskEdit. |
Si te soy sincero, siempre le he tenido manía a ese componente, pero por esta vez te haré caso y lo probaré. Mira que si me llega a gustar y todo.
De todas formas, debe de haber algún componente tipo datetimepicker y que funcione, sobre todo en lo referente a mostrar un calendario
Muchas gracias Angel
Saludos |
|
| Volver arriba |
|
 |
|