valid sobre get + button
- José Luis Sánchez
- Posts: 556
- Joined: Thu Oct 13, 2005 9:23 am
- Location: Novelda - Alicante - España
- Contact:
valid sobre get + button
Hola,
En mis programas cuando tengo que introducir un valor que es clave de una tabla en otra uso una combinación de un control GET dónde escribir un valor de la clave y un BUTTON para que en caso de que no se haya introducido nada en el GET se pueda seleccionar el valor. En el VALID del GET suelo comprobar que el valor introducido exista en la tabla secundaria, si no existe el valor doy un aviso, pero si el campo queda en blanco dejo salir del GET confiando en que el usuario seleccione un valor a través del BUTTON. Esto funciona bien para casos en que la clave es opcional, pero para el caso en que la clave es obligatoria no pues el usuario se puede escapar del GET sin introducir una clave.
Me gustaría saber si alguien tiene implementado un sistema de validación de claves que combine GET y BUTTON y que permita el uso de los dos controles, escribiendo el valor o seleccionándolo de una lista, pero que sea fuerte, es decir, que no deje pasar el control si no hay ningún valor introducido en el GET.
Saludos,
José Luis
En mis programas cuando tengo que introducir un valor que es clave de una tabla en otra uso una combinación de un control GET dónde escribir un valor de la clave y un BUTTON para que en caso de que no se haya introducido nada en el GET se pueda seleccionar el valor. En el VALID del GET suelo comprobar que el valor introducido exista en la tabla secundaria, si no existe el valor doy un aviso, pero si el campo queda en blanco dejo salir del GET confiando en que el usuario seleccione un valor a través del BUTTON. Esto funciona bien para casos en que la clave es opcional, pero para el caso en que la clave es obligatoria no pues el usuario se puede escapar del GET sin introducir una clave.
Me gustaría saber si alguien tiene implementado un sistema de validación de claves que combine GET y BUTTON y que permita el uso de los dos controles, escribiendo el valor o seleccionándolo de una lista, pero que sea fuerte, es decir, que no deje pasar el control si no hay ningún valor introducido en el GET.
Saludos,
José Luis
Re: valid sobre get + button
Hola José Luis:
Yo desde hace años lo controlo así, y funciona perfectamente.
Ademas por construmbre en procesos que se debe de introducir códigos de referencia, todos los campos los desactivo excepto el campo código ( una función Inicia() que se ejecuta en ON ONIT en todos los procesos ) y una vez validados los activo y desactivo el campo código, de este modo, controlo todo el proceso y no dejo que hagan nada que no se deba hacer.
Asi:
El botón que visualizaría la tabla:
Y la función que validad:
El único truco para controlar el GET y y el/los BUTTONS es:
Que hace que cuando pulsen el botón de tablas o el botón cancelar el valid devuelva .T. y haga la acción de los botones.
Lo hago siempre así por el uso de copiar y pegar código de un programa a otro, pero supongo que si declaras los botones con CANCEL funcionaria igual si usar el control de los botones con lFocused.
Luego al pulsar el botón de aceptar también tengo una función que controla si algún campo es obligatorio, así controlo todo el proceso sin dejar nada al azar-
espero que te sirva, un saludo
JLL
Yo desde hace años lo controlo así, y funciona perfectamente.
Ademas por construmbre en procesos que se debe de introducir códigos de referencia, todos los campos los desactivo excepto el campo código ( una función Inicia() que se ejecuta en ON ONIT en todos los procesos ) y una vez validados los activo y desactivo el campo código, de este modo, controlo todo el proceso y no dejo que hagan nada que no se deba hacer.
Asi:
Code: Select all | Expand
REDEFINE GET oCampos[1] VAR cCampos[1] ID 100 OF oDlg FONT oFont PICTURE "@!" VALID Localizar()
El botón que visualizaría la tabla:
Code: Select all | Expand
/* Boton para la tabla de aves */
REDEFINE BUTTON oBotonBMP[3] ID 650 OF oDlg;
ACTION CogerTablas()
Y la función que validad:
Code: Select all | Expand
/*------------------------------------------------------------------------------*/
STATIC Function Localizar()
/*------------------------------------------------------------------------------*/
IF oBotonBMP[2]:lFocused .OR. oBotonBMP[3]:lFocused
Return( .T. )
END
IF Empty( cCampos[1] )
MsgInfo( "Debe de introducir el número de anilla."+CRLF+CRLF+;
"Pulse el boton de aceptar para continuar. " )
Return( .F. )
END
IF !MiDosBuscar( "Aves", 1, cCampos[1] )
MsgInfo( "El número de anilla introducido no " +CRLF+;
"existe en la Base de Datos de Aves." +CRLF+CRLF+;
"Pulse el boton de aceptar para continuar. " )
cCampos[1] := Space( 30 )
MiDosRefresca( @oCampos, 1, Len( oCampos ) )
Return( .F. )
END
CargaDatosAves()
MiTodosDesactivar( @oCampos, 1, 1 )
Botones( 2 )
MiActivar( @oCampos, 6, 7 )
MiActivar( @oCampos, 9, 9 )
MiActivar( @oCampos, 11, 13 )
cCampos[6] := Ubicacio->CodUbi
cCampos[11] := Comida->CodCom
MiDosRefresca( @oCampos, 1, Len( oCampos ) )
/* Cargo la tabla de las tomas del pollito seleccionado */
IF PasaTABLA( cCampos[1] )
/* desactivamos el menu popup de la tabla en las consultas */
/* para todas las columnas del xBrowse */
AEval( oGrid:aCols, { | o | o:bRClickData := {||NIL} } )
/* Desactivamos la opcion doble click del browse en las consultas */
AEval( oGrid:aCols, { | o | o:bLDClickData := {||NIL} } )
MiTodosDesactivar( @oCampos, 6, 7 )
MiTodosDesactivar( @oCampos, 9, 9 )
MiTodosDesactivar( @oCampos, 11, 13 )
cCampos[6] := CriaMano->CodUbi
cCampos[11] := CriaMano->CodCom
MiDosRefresca( @oCampos, 1, Len( oCampos ) )
RefrescaBRW( oGrid )
Botones( 0 )
oBotonBMP[2]:SetText( "Cerrar" )
oBotonBMP[2]:cToolTip := "Cerrar"
oBotonBMP[1]:Hide()
MsgInfo( "El número de anilla introducido ya " +CRLF+;
"esta dado de alta en la base de datos." +CRLF+CRLF+;
"Pulse el boton de aceptar para continuar. " )
END
Return( .T. )
El único truco para controlar el GET y y el/los BUTTONS es:
Code: Select all | Expand
IF oBotonBMP[2]:lFocused .OR. oBotonBMP[3]:lFocused
Return( .T. )
END
Que hace que cuando pulsen el botón de tablas o el botón cancelar el valid devuelva .T. y haga la acción de los botones.
Lo hago siempre así por el uso de copiar y pegar código de un programa a otro, pero supongo que si declaras los botones con CANCEL funcionaria igual si usar el control de los botones con lFocused.
Luego al pulsar el botón de aceptar también tengo una función que controla si algún campo es obligatorio, así controlo todo el proceso sin dejar nada al azar-
espero que te sirva, un saludo
JLL
Libreria: FWH/FWH1109 + Harbour 5.8.2 + Borland C++ 5.8.2
Editor de Recursos: PellecC
ADA, OURXDBU
S.O: XP / Win 7 /Win10
Blog: http://javierlloris.blogspot.com.es/
e-mail: javierllorisprogramador@gmail.com
Editor de Recursos: PellecC
ADA, OURXDBU
S.O: XP / Win 7 /Win10
Blog: http://javierlloris.blogspot.com.es/
e-mail: javierllorisprogramador@gmail.com
Re: valid sobre get + button
Por cierto, te llego al correo lo que necesitabas? No me has dicho nada al respecto.
Un saludo
JLL
Un saludo
JLL
Libreria: FWH/FWH1109 + Harbour 5.8.2 + Borland C++ 5.8.2
Editor de Recursos: PellecC
ADA, OURXDBU
S.O: XP / Win 7 /Win10
Blog: http://javierlloris.blogspot.com.es/
e-mail: javierllorisprogramador@gmail.com
Editor de Recursos: PellecC
ADA, OURXDBU
S.O: XP / Win 7 /Win10
Blog: http://javierlloris.blogspot.com.es/
e-mail: javierllorisprogramador@gmail.com
- joseluisysturiz
- Posts: 2064
- Joined: Fri Jan 06, 2006 9:28 pm
- Location: Guatire - Caracas - Venezuela
- Contact:
Re: valid sobre get + button
Yo lo hago de esta manera si te refieres al Get junto con Button, ojo esto lo tengo usando mysql y la clase tdolphin de Daniel, pero es 100% adaptable a DBF, espero le sirva a alguien o si es lo que necesitas, cualquier duda, aca estamos, saludos
codigo
REDEFINE GET aGetP[7] VAR aVarP[7] ID 108 OF oFolder:aDialogs[1] PICTURE '@!' ; // COD.CLINICA
ACTION( IIF( EMPTY( aVarP[7] := llamabrow( aVarP[7], "clinicas", "cli_codigo" ,;
{"cli_codigo","cli_nombre"}, {"Código","Nombre"} ) ), .F., .T. ) ) ;
VALID( IIF( !novacio( aVarP[7] ), .F. ,;
( bQry := buscar( aVarP[7], "clinicas", "cli_codigo" ) ,; // RECIBE array {logico(.t.,.f.), query}
IIF( !bQry[1], ( .F. ) ,;
( aVarP[8] := bQry[2]:cli_nombre, aGetP[8]:REFRESH(), .T. ) ) ) ) ) ;
WHEN ( !EMPTY( aVarP[1] ) )
codigo
FUNCTION llamabrow( aVar, cTabla, cCampo, aCampos, aTitulos )
// aVar -> contenedora del valor entrado (puede llegar vacio solo para seleccionar)
// cTabla -> nombre de la tabla para hacer el query
// cCampo -> nombre del campo para ordenar el query y hacer comparacion con aVar ((puede llegar vacio solo para seleccionar))
// aCampos -> contenedor de las var para el browse
// aTitulos -> contenedor de los titulos de las columnas
LOCAL oWnd
LOCAL oDlg
LOCAL oBrow
LOCAL cCodigo := aVar//SPACE(10) // CONTENEDOR QUE RETORNARA EL VALOR SELECCIONADO
LOCAL cSqlCmd // COMANDO QUE SE EJECUTARA EN SQL PARA CONSULTA...
LOCAL cQry // PARA HACER LA CONSULTA EN MYSQL...
LOCAL oError // CAPTURA LOS ERRORES DE MYSQL...
LOCAL aBtn[2]
//-------- INICIO CONEXION MYSQL Y CREACION DE LA CONSULTA --------------
IF EMPTY( aVar ) //.AND. EMPTY( cCampo )
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+aCampos[1]+" ASC"
ELSE
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+cCampo+" ASC"
ENDIF
TRY // INTENTO CONECTARME CON LA BASE DE DATOS...
cQry := TDolphinQry():New( cSqlCmd, oDatos:oConex ) //REALIZA CONSULTA CON TDolphin
CATCH oError // CAPTURA EL ERROR Y LO MUESTRO CON msgstop()
MSGALERT( "Error en Consulta, Sentencia: " + CRLF + CRLF + cSqlCmd, oDatos:cTitMsg )
RETURN( NIL )
END
//-------- HASTA ACA CONEXION MYSQL, ESTO ES LO IMPORTANTE PARA USO DE LAS TABLAS -----
// VERIFICO SI TABLA TIENE REGISTROS...
IF cQry:LastRec() = 0
MSGINFO( " No hay Registros Cargados en Tabla..." + cTabla, oDatos:cTitMsg )
RETURN ( cCodigo )
ENDIF
DEFINE DIALOG oDlg RESOURCE "DLG_BRW" of oWnd ; // DEFINICION DEL oDlg
TITLE "Seleccione " + aTitulos[1]
// DEFINICION DEL xBROWSE CON DATA
oBrow := TXBrowse():New( oDlg )
WITH OBJECT oBrow
:SetDolphin( cQry, .t., .t., aCampos ) // aCampos es pasado como parametros por la funcion que llama...
:nMarqueeStyle := MARQSTYLE_HIGHLROW
:nColDividerStyle := LINESTYLE_BLACK
:nStretchCol := STRETCHCOL_LAST
:lColDividerComplete := .t.
:nHeaderHeight := 30
:l2007 := .t.
:lFooter := .t.
:lRecordSelector := .t.
:bClrStd := {|| IF( cQry:RecNo() % 2 == 0, {CLR_BLACK, CLR_WHITE}, {0, RGB(203,226,254)} ) }
:bKeyDown := {|nKey| IIF( nkey == 13 ,; // SI PULSA Enter
( cCodigo := cValToChar( cQry:FieldGet( aCampos[1]) ), oDlg:End() ), ) }
END WITH
oBrow:aCols[1]:cHeader := aTitulos[1]
oBrow:aCols[1]:bStrData := {|| IIF( cQry:LastRec() > 0, cValToChar(cQry:FieldGet( aCampos[1] )), ) }
oBrow:aCols[1]:nHeadStrAlign := AL_LEFT
oBrow:aCols[1]:nDataStrAlign := AL_LEFT
oBrow:aCols[2]:cHeader := aTitulos[2]
oBrow:aCols[2]:bStrData := {|| IIF( cQry:LastRec() > 0, cValToChar(cQry:FieldGet( aCampos[2] )), ) }
oBrow:aCols[2]:nHeadStrAlign := AL_LEFT
oBrow:aCols[2]:nDataStrAlign := AL_LEFT
oBrow:CreateFromResource(100)
// FIN DEFINICION DEL xBROWSE CON DATA
//------ DEFINICION DE LOS BOTONES -------------------------
// BOTON SELECCIONAR
REDEFINE BUTTONBMP aBtn[1] ID 201 OF oDlg UPDATE ;
ACTION ( cCodigo := cQry:FieldGet( aCampos[1] ), oDlg:End() ) ;
BITMAP 2006 PROMPT "&Seleccionar" TEXTRIGHT
// BOTON CALCELAR
REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg UPDATE ;
ACTION ( oDlg:End() ) ;
BITMAP 2004 PROMPT "Cancelar" TEXTRIGHT
aBtn[2]:lCancel := .T. // PARA CERRAR DIALOGO BOTON Cancelar
//------ FIN DEFINICION DE LOS BOTONES -------------------------
ACTIVATE DIALOG oDlg CENTER
cQry:End() // CIERRO LA CONSULTA
RETURN ( cCodigo ) // FIN MAESTRO
Codigo
FUNCTION novacio( cVar ) // VALIDA CAMPO NO QUEDE VACIO
IF EMPTY( cVar )
MSGALERT( "Campo no puede quedar Vacio.", oDatos:cTitMsg )
RETURN ( .F. )
ENDIF
RETURN ( .T. ) // FIN VALIDA CAMPO NO QUEDE VACIO
Codigo
FUNCTION buscar( cVar, cTabla, cCampo ) // BUSCA UN VALOR Y DEVUELVE EL REGISTRO COMPLETO PARA USAR LOS DEMAS DATOS DEL REGISTRO
// ULTIMA MODIFICACION Y ADAPTACION 23/08/2011
// DEVUELVE array CON VALOR LOGICO Y QUERY...
// SI {.t., query} ENCONTRO VALOR ENTRADO
//
// cVar := CONTROLA EL CAMPO POR EL CUAL SE HACE LA VALIDACION, ES DECIR ES EL CAMPO CLAVE
// EN CADA UNA DE LAS TABLAS, INCLUIDA POR JLY 07/03/2011
// cTabla := CONTROLA TABLA SOBRE LA CUAL SE HARA LA BUSQUEDA
// cCampo := CONTROLA CAMPO POR EL CUAL SE HARA LA BUSQUEDA EN LA TABLA
LOCAL cSqlCmd, cQry, oError, lExiste := .F.
IF LEN( ALLTRIM( cValToChar( cVar ) ) ) > 0 // SI ESCRIBIO ALGO HAGO query ...SINO RETORNO .f.
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+cCampo+" ASC" // ORDENO LA TABLA ASCendente
TRY // INTENTO CONECTARME CON LA BASE DE DATOS...
cQry := TDolphinQry():New( cSqlCmd, oDatos:oConex ) //REALIZA CONSULTA CON TDolphin
CATCH oError // CAPTURA EL ERROR Y LO MUESTRO CON msgstop()
MSGALERT( "Error en Funcion buscar(), Sentencia: " + CRLF + CRLF + cSqlCmd, oDatos:cTitMsg )
RETURN( {.F., NIL} )
END
// VERIFICO SI TABLA TIENE REGISTROS...
IF cQry:LastRec() = 0
MSGINFO( " No hay Registros Cargados en Tabla..." + cTabla, oDatos:cTitMsg )
RETURN( {.F., cQry} )
ENDIF
IF cQry:Seek( cVar, cCampo ) = 0 // NO ENCONTRO VALOR ENTRADO
MSGALERT("Valor no existe...")
RETURN( {.F., cQry} )
ELSE
* msginfo("encontrado")
lExiste := .T.
ENDIF
ENDIF
RETURN( {lExiste, cQry} )
![Shocked :shock:](./images/smilies/icon_eek.gif)
codigo
REDEFINE GET aGetP[7] VAR aVarP[7] ID 108 OF oFolder:aDialogs[1] PICTURE '@!' ; // COD.CLINICA
ACTION( IIF( EMPTY( aVarP[7] := llamabrow( aVarP[7], "clinicas", "cli_codigo" ,;
{"cli_codigo","cli_nombre"}, {"Código","Nombre"} ) ), .F., .T. ) ) ;
VALID( IIF( !novacio( aVarP[7] ), .F. ,;
( bQry := buscar( aVarP[7], "clinicas", "cli_codigo" ) ,; // RECIBE array {logico(.t.,.f.), query}
IIF( !bQry[1], ( .F. ) ,;
( aVarP[8] := bQry[2]:cli_nombre, aGetP[8]:REFRESH(), .T. ) ) ) ) ) ;
WHEN ( !EMPTY( aVarP[1] ) )
codigo
FUNCTION llamabrow( aVar, cTabla, cCampo, aCampos, aTitulos )
// aVar -> contenedora del valor entrado (puede llegar vacio solo para seleccionar)
// cTabla -> nombre de la tabla para hacer el query
// cCampo -> nombre del campo para ordenar el query y hacer comparacion con aVar ((puede llegar vacio solo para seleccionar))
// aCampos -> contenedor de las var para el browse
// aTitulos -> contenedor de los titulos de las columnas
LOCAL oWnd
LOCAL oDlg
LOCAL oBrow
LOCAL cCodigo := aVar//SPACE(10) // CONTENEDOR QUE RETORNARA EL VALOR SELECCIONADO
LOCAL cSqlCmd // COMANDO QUE SE EJECUTARA EN SQL PARA CONSULTA...
LOCAL cQry // PARA HACER LA CONSULTA EN MYSQL...
LOCAL oError // CAPTURA LOS ERRORES DE MYSQL...
LOCAL aBtn[2]
//-------- INICIO CONEXION MYSQL Y CREACION DE LA CONSULTA --------------
IF EMPTY( aVar ) //.AND. EMPTY( cCampo )
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+aCampos[1]+" ASC"
ELSE
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+cCampo+" ASC"
ENDIF
TRY // INTENTO CONECTARME CON LA BASE DE DATOS...
cQry := TDolphinQry():New( cSqlCmd, oDatos:oConex ) //REALIZA CONSULTA CON TDolphin
CATCH oError // CAPTURA EL ERROR Y LO MUESTRO CON msgstop()
MSGALERT( "Error en Consulta, Sentencia: " + CRLF + CRLF + cSqlCmd, oDatos:cTitMsg )
RETURN( NIL )
END
//-------- HASTA ACA CONEXION MYSQL, ESTO ES LO IMPORTANTE PARA USO DE LAS TABLAS -----
// VERIFICO SI TABLA TIENE REGISTROS...
IF cQry:LastRec() = 0
MSGINFO( " No hay Registros Cargados en Tabla..." + cTabla, oDatos:cTitMsg )
RETURN ( cCodigo )
ENDIF
DEFINE DIALOG oDlg RESOURCE "DLG_BRW" of oWnd ; // DEFINICION DEL oDlg
TITLE "Seleccione " + aTitulos[1]
// DEFINICION DEL xBROWSE CON DATA
oBrow := TXBrowse():New( oDlg )
WITH OBJECT oBrow
:SetDolphin( cQry, .t., .t., aCampos ) // aCampos es pasado como parametros por la funcion que llama...
:nMarqueeStyle := MARQSTYLE_HIGHLROW
:nColDividerStyle := LINESTYLE_BLACK
:nStretchCol := STRETCHCOL_LAST
:lColDividerComplete := .t.
:nHeaderHeight := 30
:l2007 := .t.
:lFooter := .t.
:lRecordSelector := .t.
:bClrStd := {|| IF( cQry:RecNo() % 2 == 0, {CLR_BLACK, CLR_WHITE}, {0, RGB(203,226,254)} ) }
:bKeyDown := {|nKey| IIF( nkey == 13 ,; // SI PULSA Enter
( cCodigo := cValToChar( cQry:FieldGet( aCampos[1]) ), oDlg:End() ), ) }
END WITH
oBrow:aCols[1]:cHeader := aTitulos[1]
oBrow:aCols[1]:bStrData := {|| IIF( cQry:LastRec() > 0, cValToChar(cQry:FieldGet( aCampos[1] )), ) }
oBrow:aCols[1]:nHeadStrAlign := AL_LEFT
oBrow:aCols[1]:nDataStrAlign := AL_LEFT
oBrow:aCols[2]:cHeader := aTitulos[2]
oBrow:aCols[2]:bStrData := {|| IIF( cQry:LastRec() > 0, cValToChar(cQry:FieldGet( aCampos[2] )), ) }
oBrow:aCols[2]:nHeadStrAlign := AL_LEFT
oBrow:aCols[2]:nDataStrAlign := AL_LEFT
oBrow:CreateFromResource(100)
// FIN DEFINICION DEL xBROWSE CON DATA
//------ DEFINICION DE LOS BOTONES -------------------------
// BOTON SELECCIONAR
REDEFINE BUTTONBMP aBtn[1] ID 201 OF oDlg UPDATE ;
ACTION ( cCodigo := cQry:FieldGet( aCampos[1] ), oDlg:End() ) ;
BITMAP 2006 PROMPT "&Seleccionar" TEXTRIGHT
// BOTON CALCELAR
REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg UPDATE ;
ACTION ( oDlg:End() ) ;
BITMAP 2004 PROMPT "Cancelar" TEXTRIGHT
aBtn[2]:lCancel := .T. // PARA CERRAR DIALOGO BOTON Cancelar
//------ FIN DEFINICION DE LOS BOTONES -------------------------
ACTIVATE DIALOG oDlg CENTER
cQry:End() // CIERRO LA CONSULTA
RETURN ( cCodigo ) // FIN MAESTRO
Codigo
FUNCTION novacio( cVar ) // VALIDA CAMPO NO QUEDE VACIO
IF EMPTY( cVar )
MSGALERT( "Campo no puede quedar Vacio.", oDatos:cTitMsg )
RETURN ( .F. )
ENDIF
RETURN ( .T. ) // FIN VALIDA CAMPO NO QUEDE VACIO
Codigo
FUNCTION buscar( cVar, cTabla, cCampo ) // BUSCA UN VALOR Y DEVUELVE EL REGISTRO COMPLETO PARA USAR LOS DEMAS DATOS DEL REGISTRO
// ULTIMA MODIFICACION Y ADAPTACION 23/08/2011
// DEVUELVE array CON VALOR LOGICO Y QUERY...
// SI {.t., query} ENCONTRO VALOR ENTRADO
//
// cVar := CONTROLA EL CAMPO POR EL CUAL SE HACE LA VALIDACION, ES DECIR ES EL CAMPO CLAVE
// EN CADA UNA DE LAS TABLAS, INCLUIDA POR JLY 07/03/2011
// cTabla := CONTROLA TABLA SOBRE LA CUAL SE HARA LA BUSQUEDA
// cCampo := CONTROLA CAMPO POR EL CUAL SE HARA LA BUSQUEDA EN LA TABLA
LOCAL cSqlCmd, cQry, oError, lExiste := .F.
IF LEN( ALLTRIM( cValToChar( cVar ) ) ) > 0 // SI ESCRIBIO ALGO HAGO query ...SINO RETORNO .f.
cSqlCmd := "SELECT * FROM "+cTabla+" ORDER BY "+cCampo+" ASC" // ORDENO LA TABLA ASCendente
TRY // INTENTO CONECTARME CON LA BASE DE DATOS...
cQry := TDolphinQry():New( cSqlCmd, oDatos:oConex ) //REALIZA CONSULTA CON TDolphin
CATCH oError // CAPTURA EL ERROR Y LO MUESTRO CON msgstop()
MSGALERT( "Error en Funcion buscar(), Sentencia: " + CRLF + CRLF + cSqlCmd, oDatos:cTitMsg )
RETURN( {.F., NIL} )
END
// VERIFICO SI TABLA TIENE REGISTROS...
IF cQry:LastRec() = 0
MSGINFO( " No hay Registros Cargados en Tabla..." + cTabla, oDatos:cTitMsg )
RETURN( {.F., cQry} )
ENDIF
IF cQry:Seek( cVar, cCampo ) = 0 // NO ENCONTRO VALOR ENTRADO
MSGALERT("Valor no existe...")
RETURN( {.F., cQry} )
ELSE
* msginfo("encontrado")
lExiste := .T.
ENDIF
ENDIF
RETURN( {lExiste, cQry} )
Dios no está muerto...
Gracias a mi Dios ante todo!
Gracias a mi Dios ante todo!
- José Luis Sánchez
- Posts: 556
- Joined: Thu Oct 13, 2005 9:23 am
- Location: Novelda - Alicante - España
- Contact:
Re: valid sobre get + button
Hola,
Lo de saltar del valid cuando el siguiente control que toma el foco es el botón está bien, pero yo quería algo más... no se como decirlo... sencillo. Yo de hecho lo que hago es que cuando el get queda en blanco y quiero que haya algo lanzo la función que invoca el click del botón.
En mis programas lo que hago es tener una función que controla la introducción de una clave en una tabla. Esta función se usa siempre que se lee un campo clave, tanto si se da de alta un registro, se modifica o se duplica. Y también cuando se introduce un valor como clave ajena en otra tabla. Aquí os dejo el código, y agradezco que vosotros hayais compartido el vuestro. En este caso estoy controlando claves de recetas, tanto el código como el título de la receta.
Saludos,
José Luis
Lo de saltar del valid cuando el siguiente control que toma el foco es el botón está bien, pero yo quería algo más... no se como decirlo... sencillo. Yo de hecho lo que hago es que cuando el get queda en blanco y quiero que haya algo lanzo la función que invoca el click del botón.
En mis programas lo que hago es tener una función que controla la introducción de una clave en una tabla. Esta función se usa siempre que se lee un campo clave, tanto si se da de alta un registro, se modifica o se duplica. Y también cuando se introduce un valor como clave ajena en otra tabla. Aquí os dejo el código, y agradezco que vosotros hayais compartido el vuestro. En este caso estoy controlando claves de recetas, tanto el código como el título de la receta.
Code: Select all | Expand
function ReClave( cReceta, oGet, nMode, nField, aGet )
// nMode 1 nuevo registro
// 2 modificación de registro
// 3 duplicación de registro
// 4 clave ajena
// nField 1 ReTitulo
// 2 ReCodigo
local lreturn := .f.
local nRecno := RE->( RecNo() )
local nOrder := RE->( OrdNumber() )
local nArea := Select()
local aTPlato := { 'Entradas', '1er Plato', '2o Plato', 'Postre', 'Dulce', 'Otro' }
if Empty( cReceta )
if nMode == 4
// MsgStop("Es obligatorio rellenar este campo.")
lReturn := ReSelAjena( @cReceta, oGet, 4, 2, aGet )
return lReturn
endif
endif
SELECT RE
if nField == 1
RE->( DbSetOrder( 1 ) )
else
RE->( DbSetOrder( 2 ) )
endif
RE->( DbGoTop() )
if RE->( DbSeek( UPPER( cReceta ) ) )
DO CASE
Case nMode == 1 .OR. nMode == 3
lreturn := .f.
if nField == 1
MsgStop("Receta existente.")
else
MsgStop("Código de receta existente.")
endif
Case nMode == 2
if RE->( Recno() ) == nRecno
lreturn := .t.
else
lreturn := .f.
if nField == 1
MsgStop("Receta existente.")
else
MsgStop("Código de receta existente.")
endif
endif
Case nMode == 4
lreturn := .t.
if aGet != Nil
aGet[2]:ctext := RE->ReTitulo
aGet[3]:cText := aTPlato[MAX(VAL(RE->RePlato),1)]
aGet[4]:cText := RE->ReTipo
endif
END CASE
else
if nMode < 4
lreturn := .t.
else
if nField == 1
MsgStop("Receta inexistente.")
else
MsgStop("Código de receta inexistente.")
endif
lReturn := ReSelAjena( @cReceta, oGet, 4, 2, aGet )
endif
endif
if lreturn == .f.
if nField == 1
oGet:cText( space(60) )
else
oGet:cText( space(10) )
endif
endif
RE->( DbSetOrder( nOrder ) )
RE->( DbGoTo( nRecno ) )
Select (nArea)
return lreturn
Saludos,
José Luis
-
- Posts: 845
- Joined: Sun Oct 09, 2005 5:36 pm
- Location: la laguna, mexico.
Re: valid sobre get + button
Jose Luis,
A ver si entendi lo que quieres hacer: desde una funcion controlar en un valid que el get te permita o no avanzar si tiene codigo y hacerlo por medio de un boton,
te explico yo que hago a ver si te puede ayudar...
Tengo una funcion sel_Catalogo donde cargo el catalogo especificado, y los campos que quiero que me devuelva en un arreglo,,
REDEFINE GET aoObjetos[3] ;
VAR aoDatos[3] ;
PICTURE "99" ;
ID 103 OF oDlg ;
UPDATE ;
BITMAP "WBuscar" ;
ACTION ( aInfo:=Sel_Catalogo( aoDatos[3], "colaboradores", {"cacceso","paterno","materno"} ),;
IF(aInfo[1] <> 0,;
( aoDatos[3]:=aInfo[1],aoDatos[4]:=ALLTRIM(aInfo[2])+" "+ALLTRIM(aInfo[4])+" "+ALLTRIM(aInfo[5]),;
aoObjetos[3]:Refresh(), aoObjetos[4]:Refresh() ),),;
aoObjetos[3]:SetFocus(), oDlg:Update() ) ;
VALID ( IF(aoDatos[3] <> 0,; <-- aqui valido que haga si el codigo tiene algun dato o es cero
( aInfo:=Sel_Catalogo( aoDatos[3], "colaboradores", {"cacceso","paterno","materno"}, .T. ),;
aoDatos[3]:=aInfo[1],aoDatos[4]:=ALLTRIM(aInfo[2])+" "+ALLTRIM(aInfo[4])+" "+ALLTRIM(aInfo[5]),;
lCont:=BuscaCorte(pcAccion,@aoDatos,aoObjetos,@aInfo,aoBtn),;
IF(!lCont,aoObjetos[3]:SetFocus(),aoObjetos[5]:SetFocus()),lCont:=.T. ),;
( aoDatos[3]:=0,aoDatos[4]:="",lCont:=.F. ) ),;
aoObjetos[3]:Refresh(), aoObjetos[4]:Refresh(), oDlg:Update(), lCont )
aoObjetos[3]:bKeydown := {|nKey| IF( nKey == VK_F2, aoObjetos[3]:oBtn:PostMsg(WM_CLICK,13,0), )} <- pulsando F2 carga catalogo
Te adjunto una imagen y la funcion:
![Image](http://img710.imageshack.us/img710/9146/jlsdm.th.jpg)
salu2
paco
A ver si entendi lo que quieres hacer: desde una funcion controlar en un valid que el get te permita o no avanzar si tiene codigo y hacerlo por medio de un boton,
te explico yo que hago a ver si te puede ayudar...
Tengo una funcion sel_Catalogo donde cargo el catalogo especificado, y los campos que quiero que me devuelva en un arreglo,,
REDEFINE GET aoObjetos[3] ;
VAR aoDatos[3] ;
PICTURE "99" ;
ID 103 OF oDlg ;
UPDATE ;
BITMAP "WBuscar" ;
ACTION ( aInfo:=Sel_Catalogo( aoDatos[3], "colaboradores", {"cacceso","paterno","materno"} ),;
IF(aInfo[1] <> 0,;
( aoDatos[3]:=aInfo[1],aoDatos[4]:=ALLTRIM(aInfo[2])+" "+ALLTRIM(aInfo[4])+" "+ALLTRIM(aInfo[5]),;
aoObjetos[3]:Refresh(), aoObjetos[4]:Refresh() ),),;
aoObjetos[3]:SetFocus(), oDlg:Update() ) ;
VALID ( IF(aoDatos[3] <> 0,; <-- aqui valido que haga si el codigo tiene algun dato o es cero
( aInfo:=Sel_Catalogo( aoDatos[3], "colaboradores", {"cacceso","paterno","materno"}, .T. ),;
aoDatos[3]:=aInfo[1],aoDatos[4]:=ALLTRIM(aInfo[2])+" "+ALLTRIM(aInfo[4])+" "+ALLTRIM(aInfo[5]),;
lCont:=BuscaCorte(pcAccion,@aoDatos,aoObjetos,@aInfo,aoBtn),;
IF(!lCont,aoObjetos[3]:SetFocus(),aoObjetos[5]:SetFocus()),lCont:=.T. ),;
( aoDatos[3]:=0,aoDatos[4]:="",lCont:=.F. ) ),;
aoObjetos[3]:Refresh(), aoObjetos[4]:Refresh(), oDlg:Update(), lCont )
aoObjetos[3]:bKeydown := {|nKey| IF( nKey == VK_F2, aoObjetos[3]:oBtn:PostMsg(WM_CLICK,13,0), )} <- pulsando F2 carga catalogo
Te adjunto una imagen y la funcion:
![Image](http://img710.imageshack.us/img710/9146/jlsdm.th.jpg)
Code: Select all | Expand
FUNCTION Sel_Catalogo( pnId, pcTabla, paFields, plBuscar, pcConsulta, plRefresh )
LOCAL oDlg, oBrw2, nxId := 0, aDatos:=ARRAY(2), lRet := .F.
LOCAL oQry2 := NIL, cNombre := "", x
LOCAL aoObjetos[2], aoBtn[2], aoCols[2]
LOCAL cFiltro:=Space(60), cVar:=""
LOCAL aRowGradi := { { .5, RGB( 232, 241, 252 ), RGB( 232, 241, 252 ) }, ;
{ .5, RGB( 210, 225, 244 ), RGB( 235, 243, 253 ) } }
aSelGradi := { { .4, RGB( 255, 255, 230 ), RGB( 255, 200, 130 ) },;
{ .6, RGB( 255, 170, 032 ), RGB( 255, 223, 162 ) } }
DEFAULT paFields := {}, plBuscar := .F.,;
pcConsulta := "SELECT * FROM " + LOWER(pcTabla) + " WHERE id = " + ValToStr( pnId ),;
plRefresh := .T.
AFILL(aDatos,NIL)
oQry2 := oApp:oServer:Query(pcConsulta)
IF plBuscar .AND. !GETKEYSTATE( VK_F2 )
IF oQry2:LastRec() > 0
aDatos[1] := oQry2:FieldGet("id")
aDatos[2] := oQry2:FieldGet("nombre")
IF LEN(paFields) > 0
FOR x := 1 TO LEN(paFields)
AADD( aDatos, oQry2:FieldGet(paFields[x]) )
NEXT
ENDIF
oQry2:End()
RETURN( aDatos )
ELSE
aDatos[1]:=0
aDatos[2]:=""
IF LEN(paFields) > 0
FOR x := 1 TO LEN(paFields)
AADD( aDatos, oQry2:FieldGet(paFields[x]) )
NEXT
ENDIF
oQry2:End()
RETURN( aDatos )
ENDIF
ENDIF
IF oQry2:LastRec() > 0 .AND. ( GETKEYSTATE( VK_RETURN ) .OR. GETKEYSTATE( VK_TAB ) )
lRet := .T.
aDatos[1] := oQry2:FieldGet("id")
aDatos[2] := oQry2:FieldGet("nombre")
IF LEN(paFields) > 0
FOR x := 1 TO LEN(paFields)
AADD( aDatos, oQry2:FieldGet(paFields[x]) )
NEXT
ENDIF
oQry2:End()
RETURN( aDatos )
ELSE
nxId := 0
cNombre := SPACE( LEN( oQry2:FieldGet("nombre") ) )
IF plRefresh
oQry2:cQuery := "SELECT * FROM " + LOWER(pcTabla) + " ORDER BY nombre"
ENDIF
oQry2:Refresh()
IF oQry2:LastRec() == 0
MsgStop("No Existe Información en el Catálogo de : "+pcTabla+" !!","Atención...")
IF LEN(paFields) > 0
FOR x := 1 TO LEN(paFields)
AADD( aDatos, oQry2:FieldGet(paFields[x]) )
NEXT
ENDIF
oQry2:End()
RETURN( aDatos )
ENDIF
DEFINE DIALOG oDlg ;
RESOURCE "SEL_CATALOGO" ;
TITLE "Catálogo de : " + LOWER(pcTabla) ;
FONT oApp:fNormal
oDlg:lHelpIcon:=.F.
REDEFINE GET aoObjetos[1] ;
VAR cFiltro ;
PICTURE "@k!" ;
ID 101 OF oDlg ;
UPDATE
aoObjetos[1]:cToolTip := "Introduzca los datos para filtrar el catálogo"
oBrw2 := TXBrowse():New( oDlg )
oBrw2:SetMySql( oQry2, .F. )
oBrw2:nMarqueeStyle := MARQSTYLE_HIGHLROW
oBrw2:nColDividerStyle := LINESTYLE_NOLINES
oBrw2:nRowDividerStyle := LINESTYLE_LIGHTGRAY
oBrw2:lColDividerComplete := .T.
oBrw2:nHeaderHeight := 28
oBrw2:nRowHeight := 20
oBrw2:bClrSelFocus := { || { CLR_BLACK, oApp:aRowGradi } }
oBrw2:SetBackGround( oApp:cDirBmps+"Logo1.jpg", BCK_STRETCH )
oBrw2:bLDblClick := { || (lRet:=.T.,oDlg:End()) }
oBrw2:bKeyDown := { |nKey| IF( nKey == VK_RETURN,(lRet:=.T.,oDlg:End()),) }
oBrw2:nStretchCol := STRETCHCOL_LAST
aoCols[1] := oBrw2:AddCol()
aoCols[1]:nWidth := 70
aoCols[1]:cHeader := "Código"
aoCols[1]:bStrData := { || TRANSFORM( oQry2:FieldGet("id"), "999999" ) }
aoCols[1]:nDataStrAlign := AL_RIGHT
aoCols[1]:nHeadStrAlign := AL_CENTER
aoCols[1]:bLClickHeader := { || oApp:CambiaOrden( "id", @oQry2, oBrw2, pcTabla) }
aoCols[2] := oBrw2:AddCol()
aoCols[2]:nWidth := 310
aoCols[2]:cHeader := "Nombre"
aoCols[2]:bStrData := { || oQry2:FieldGet("nombre") }
aoCols[2]:bLClickHeader := { || oApp:CambiaOrden( "nombre", @oQry2, oBrw2, pcTabla) }
aoCols[2]:nDataStrAlign := AL_LEFT
aoCols[2]:nHeadStrAlign := AL_CENTER
oBrw2:CreateFromResource(300)
REDEFINE BUTTONBMP aoBtn[1] ID 102 OF oDlg ;
BITMAP oApp:cDirBmps+"Buscar16.bmp" TEXTRIGHT ;
ACTION ( oQry2:cQuery := "SELECT * FROM " + LOWER(pcTabla) + IF(EMPTY(cFiltro),"", " WHERE nombre LIKE '%" + ALLTRIM(cFiltro) + "%'"),;
oQry2:Refresh(), oQry2:GoTop(),;
oBrw2:Refresh(), oBrw2:SetFocus(),;
cFiltro := space(60), aoObjetos[1]:Refresh(), aoBtn[1]:oJump := oBrw2 )
REDEFINE BUTTONBMP aoBtn[2] ID 103 OF oDlg ;
BITMAP "BTN_OK" TEXTRIGHT ;
ACTION ( lRet := .T., oDlg:End() )
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT oBrw2:SetFocus()
IF lRet
oQry2:GetRow()
aDatos[1] := oQry2:FieldGet("id")
aDatos[2] := oQry2:FieldGet("nombre")
IF LEN(paFields) > 0
FOR x := 1 TO LEN(paFields)
AADD( aDatos, oQry2:FieldGet(paFields[x]) )
NEXT
ENDIF
ELSE
aDatos[1]:=0
aDatos[2]:=""
ENDIF
ENDIF
oQry2:End()
RETURN( aDatos )
salu2
paco
____________________
Paco
Paco
- joseluisysturiz
- Posts: 2064
- Joined: Fri Jan 06, 2006 9:28 pm
- Location: Guatire - Caracas - Venezuela
- Contact:
Re: valid sobre get + button
Por lo que veo le hemos dado al tocayo Jose Luis casi todos lo mismo, pero por lo que dice no es lo que necesita, entonce de verdad no entiendo, si puedes ser mas especifico seria mejor para asi poder ayudarte man..saludos... ![Shocked :shock:](./images/smilies/icon_eek.gif)
![Shocked :shock:](./images/smilies/icon_eek.gif)
Dios no está muerto...
Gracias a mi Dios ante todo!
Gracias a mi Dios ante todo!
- José Luis Sánchez
- Posts: 556
- Joined: Thu Oct 13, 2005 9:23 am
- Location: Novelda - Alicante - España
- Contact:
Re: valid sobre get + button
Hola,
Creo que me he expresado mal. No es que no me sirva el código que habeis publicado, sino que pensé que habría alguna otra manera de hacerlo.
Pido disculpas si alguien se ha sentido ofendido, y creo que debí publicar el código en el primer post sobre el tema.
Saludos,
José Luis
Creo que me he expresado mal. No es que no me sirva el código que habeis publicado, sino que pensé que habría alguna otra manera de hacerlo.
Pido disculpas si alguien se ha sentido ofendido, y creo que debí publicar el código en el primer post sobre el tema.
Saludos,
José Luis