FoxPro/Visual FoxPro - Bitacora en foxpro

 
Vista:
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 27/02/2014 23:02:57
BUENAS UNA CONSULTA USTEDES TIENE UN EJEMPLO O UN CODIGO QUE ME MUESTRE LA BITACORA
PORQUE EL CODIGO QUE TENGO NO ME QUIERE FUNCIONAR BIEN ME TOMA OTRO NOMBRE DE USUARIO
ES EL SGT

SELECT bitacora
APPEND BLANK
REPLACE hora WITH TIME()
REPLACE fecha WITH DATE()
REPLACE empleado WITH (bitacora.empleados)
REPLACE modulo WITH "DATOS DEL CLIENTE"
REPLACE actividad WITH "SALIO DE DATOS DEL CLIENTE"
thisform.refresh

este codigo es el que tengo en los botones del proyecto lo que me hace es lo sgt si entramos al formulario digamos clientes quiero que el usuario que ingreso desde el principio me remplace empleados con el nombre de usuario que ingreso al sistemas.
si me lo ingresas pero no el usuario que ingreso sino el ultimo usuario registrado en la tabla de usuarios.
aclaro tengo tabla de usuario,bitacora,y empleado
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Bitacora en foxpro

Publicado por Fidel José (558 intervenciones) el 27/02/2014 23:57:38
No queda claro tu problema. Pero lo que se ve en ese código es algo extraño. O pusiste un código que no es el que usas.
SELECT BITACORA
append blank && agrega un registro en blanco
replace emplado with (bitacora.empleados) && ???
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por marco (19 intervenciones) el 28/02/2014 00:04:42
disculpe es el sgt codigo

SELECT bitacora && && la tabla
APPEND BLANK && adiciona un nuevo registro
REPLACE hora WITH TIME() &&remplace con tiempo
REPLACE fecha WITH DATE()&&remplace con dia
REPLACE empleado WITH (usuario.nombre)&&remplace con nombre de usuario quien ingreso al sistema
REPLACE modulo WITH "DATOS DEL CLIENTE"&&remplace al modulo o formulario que ingreso
REPLACE actividad WITH "SALIO DE DATOS DEL CLIENTE"&&remplace con la actividad que hizo
thisform.refresh

y lleva el append blank para adicionar un nuevo resgistro de lo que hace el usuario que ingreso
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Bitacora en foxpro

Publicado por Fidel José (558 intervenciones) el 28/02/2014 16:17:03
Bien, lo que no se ve en ese código, es como situas el puntero en la tabla Usuarios. Lo que incorpora a la bitácora no es necesariamente el usuario actual, sino el que corresponde al registro.
Si el usuario es el que se identifica en el inicio del programa, lo puedes enviar a una propiedad de screen.
* Corre la verificación de usuario. Seguramente dará en la tabla usuario con el usuario correspondiente.

Addproperty(_Screen,"Usuario",Usuario.nombre) && crea una propiedad de Screen, con el valor del campo nombre de la tabla usuario.

Ahora en la bitácora, lo que pondría es:
INSERT INTO BITACORA ;
(HORA,FECHA,EMPLEADO,MODULO,ACTIVIDAD) ;
VALUES (TIME() , DATE() , _SCREEN.USUARIO , "DATOS DEL CLIENTE" , "SALIO DE DATOS DEL CLIENTE")

Notas
1) Acostumbrate a utilizar INSERT INTO en lugar de APPEND BLANK, REPLACE
2) no utilices múltiples comandos REPLACE, porque fuerzas el controlador de bloqueo en cada sentencia. Aún con Append Blank es mucho mejor lo siguiente:
SELECT bitacora
APPEND BLANK
REPLACE hora WITH TIME(),;
fecha WITH DATE(),;
empleado WITH _Screen.Usuario ,;
modulo WITH "DATOS DEL CLIENTE",;
actividad WITH "SALIO DE DATOS DEL CLIENTE"

3) Por qué escribes
REPLACE empleado WITH (usuario.nombre) ???

La sentencia correcta sería
REPLACE empleado WITH usuario.nombre && sin paréntesis
Los paréntensis se utilizan (cuando corresponde) para hacer una sustitución de nombre, porque es más rápido que una macrosustitución
Por ejemplo
lcCampo="Empleado"
REPLACE (lcNombre) with usuario.nombre && en lugar de Replace &lcCampo with Usuario.nombre

Por ejemplo
dTEmp="C:\myApp\Datos"
lcuse=Addbs(dTEmp)+"Clientes"
USE (lcUse) IN 0 SHARED
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por marco (19 intervenciones) el 28/02/2014 17:53:12
Pero como haga para,llevar él conteo de ingreso me explico para darle un nuevo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 28/02/2014 19:36:25
lo hice y me aparece error dice que en usuario
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 28/02/2014 20:29:40
YA ME DIO EL PRIMER CODIGO EL SGTS


Addproperty(_Screen,"Usuario",BITACORA.EMPLEADO)

INSERT INTO BITACORA ;
(HORA,FECHA,EMPLEADO,MODULO,detalle,numero) ;
VALUES (TIME() , DATE() , _SCREEN.USUARIO , "DATOS DEL CLIENTE" , "SALIO DE DATOS DEL CLIENTE",PADL(ALLTRIM(STR(RECCOUNT())),8,"0"))

thisform.Release

PERO CUANDO CAMBIO DE USUARIO ME SIGUE GUARDANDO EL USUARIO ANTERIO NO EL MISMO USUARIO QUE INGRESA
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Bitacora en foxpro

Publicado por Fidel José (558 intervenciones) el 28/02/2014 22:54:59
Tal vez no me expliqué correctamente.
En el punto en que ingresas el usuario (será un formulario, supongo), debes controlar de alguna forma que se usuario esté registrado. Tal vez de ahí deduzcas algunas autorizaciones o impedimentos. Supongo yo, que esa información la tienes en la tabla "usuarios".
Suponte que el Sr. Usuario ingresa su nombre de usuario en un control textbox del formulario de registro, digamos Text1.
En el evento Valid del text1 estarás haciendo la búsqueda del nombre ingresado en la tabla Usuarios. Si lo encuentra validas la entrada y si no lo rebotas. Por ejemplo (me ahorro el tema de la clave de usuario).
* Evento Valid del Text1Form de registro
if !empty(this.value)
this.value=alltrim(this.value)
select usuarios
locate for trim(nombre)==this.value
IF !FOUND()
messagebox("Usuario No Existe")
return 0
endif
Addproperty(_SCREEN,"USUARIO",TRIM(USUARIOS.NOMBRE) )
* Acá habilito un botón de entrada al sistema
* REcuerda que en valid no se puede utilizar Set Focus, pero puedes usar Return Thisform.CmdEntry si CmdEntry es un botón que permite el acceso.
ENDIF


Ahora, _Screen.Usuario tendrá el nombre del usuario y ya no cambiarás el valor de esta propiedad en otro lugar de la aplicación.

Si en lugar de eso, utilizas un combobox con todos los usuarios registrados, pidiendo luego la clave de usuario, el valor de la propiedad _Screen.Usuario debe tomarse del Value del ComboBox cuando se valida la clave de usuario.

Fijate las observaciones sobre el código remitido:

Addproperty(_Screen,"Usuario",BITACORA.EMPLEADO) && esto no debe ir aquí. Debe ir en el ingreso del usuario

INSERT INTO BITACORA ;
(HORA,FECHA,EMPLEADO,MODULO,detalle,numero) ;
VALUES (TIME() , DATE() , _SCREEN.USUARIO , "DATOS DEL CLIENTE" , "SALIO DE DATOS DEL CLIENTE",PADL(ALLTRIM(STR(RECCOUNT())),8,"0"))

thisform.Release

En lugar de Alltrim(Str()), como ya sabes que Reccount() devolverá un Interger, es mejor utilizar:

lcCantidadRegistrosTabla = Transform( Reccount() )
De todos modos, entiendo que será mejor que pongas REccount( "queTabla" ). Fijate que INSERT INTO no necesita seleccionar la tabla y el resultado de REccount() será la cantidad de registros que tenga la tabla seleccionada (que no se sabe cual es en este momento).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 01/03/2014 01:24:16
BUANAS MUCHAS GRACIAS POR TU COLABORACION PERO FUNCIONA BIEN HASTA QUE CAMBIO DE USUARIO
EL CODIGO QUE TENGO EL FORMULARIO DE INGRESO ES EL SGTS EN UN BOTON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
select empleados
 
e=alltrim(proper(thisform.txtnombre.value))
c=alltrim(thisform.txtclave.value)
locate for alltrim(proper(e)) = alltrim(proper(empleados.nombre))
if found()
		if alltrim(c) = alltrim(empleados.Clave)
			messagebox("HOLA  " + alltrim (nombre))
			if alltrim(cargo)="1"
			 messagebox("BIENVENIDO ADMINISTRADOR")
			 do "menuadmi.mpr"
			thisform.release
			endif
			if alltrim(cargo)="2"
			 messagebox("BIENVENIDO VENDEDOR")
			 do "menuven.mpr"
			thisform.release
			endif
		else
			messagebox("CLAVE INCORRECTA VERIFIQUE")
		endif
else
	messagebox("NOMBRE DE USUARIO INCORRECTO VERIFIQUE")
ENDIF
Addproperty(_SCREEN,"USUARIO",TRIM(EMPLEADOS.NOMBRE) )
			thisform.refresh
 
Addproperty(_Screen,"Usuario",EMPLEADOS.NOMBRE)
thisform.release

EN LOS OTROS FORMULARIOS TENGO EL SGT CODIGO EN EL BOTON DE SALIR Y EN EL INT DEL FORMULARIO

1
2
3
4
5
6
7
Addproperty(_Screen,"Usuario",TRIM(EMPLEADOS.NOMBRE))
 
INSERT INTO BITACORA ;
(HORA,FECHA,EMPLEADO,MODULO,detalle,numero) ;
VALUES (TIME() , DATE() , _SCREEN.USUARIO , "DATOS DEL CLIENTE" , "SALIO DE DATOS DEL CLIENTE",PADL(ALLTRIM(STR(RECCOUNT())),8,"0"))
 
thisform.Release

Y CUANDO CAMBIO DE USUARIO NO ME RESGISTRA EL USUARIO ME REGISTRA EL USUARIO ANTERIO O HAY VECES QUE NO ME LO REGISTRA QUEDA EN BLANCO
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 01/03/2014 02:42:16
MUCHAS GRACIAS POR TODA LA COLABORACION NO HABIA PUESTO CUIDADO EN LA ULTIMA PARTE QUE DIJO QUE EL Addproperty(_Screen,"Usuario",Usuario.nombre) NO IBA EN LOS FORMULARIOS SOLO IBA PARA EL INGRESO Y NO PARA LOS FORMULARIOS

MUCHAS GRACIAS POR TODO
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Bitacora en foxpro

Publicado por juan (50 intervenciones) el 01/03/2014 13:23:05
Podrias mostrarnos como te quedo el codigo ya solucionado
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Bitacora en foxpro

Publicado por Fidel José (558 intervenciones) el 01/03/2014 14:11:59
No hay problema Marco.
De todos modos quiero agregar un comentario. No sé cómo instrumentas el formulario de ingreso del usuario, pero la lógica debería ser algo así.

En la forma en que tu lo pones, resulta difícil comprender el desenlace verdadero del formulario de inicio.
Lanzar un menú desde un formulario no parece una buena práctica y es probable que tengas problemas para cerrar el sistema. A veces el thisform.release no consigue eliminar el formulario de la memoria y queda como un objeto oculto y perdido. Si el form es WindowType=1 puede aparecer el cartel de que no se puede cerrar Visual Fox, aun cuando no está activo como formulario y _Screen.FormCount=0

La propuesta es organizar una respuesta del formulario de inicio, configurandolo como WindowType=1 y utilizando el formato de llamada DO FORM INGRESO TO lnRespuesta. Si LnRespuesta=0 el sistema debe cerrarse, porque el formulario de inicio tiene que preveer que el supuesto usuario desista de ingresar en la aplicación. Por ejemplo, cerrando el formulario con la cruz de arriba. En este caso, el curso de acción y los saludos se trasladan al programa que convoca al formulario y son consecuencia de la respuesta del mismo. La respuesta se analizará cuando el formulario se cierre, lo que no deja ninguna duda sobre su liberación.

A su vez, puedes mejorar la interfase del formulario de ingreso, devolviendo a los cuadros respectivos con SEtfocus y REturn.

Nota 1)
No uses Thisform.REfresh porque sí. En general, no uses Thisform.Refresh.
Cuando necesites refrescar determinados controles, crea un método de refresco y ataca específicamente los objetos que quieres refrescar. Pero ten en cuenta que el REfresh tiene sentido si estás atando los controles del form por ControlSource y cambias el valor de la variable, propiedad o campo de tabla o cursor liado al control por ControlSource.
Por ejemplo, si declaro en el init de un form:
Addproperty(thisform, "Prop1" , "Casa")
Thisform.TExt1.ControlSource='Thisform.Prop1'

*Cuando se presente el form, el Text1 tendrá el value "Casa".
*Supone que un botón hacemos lo siguiente:
Thisform.Prop1="Auto"
*Ahora, para que Text1 se entere del cambio, necesitamos un refresh. Entonces:
Thisform.Text1.REfresh
* Ahora, Text1 asumirá el Value="Auto"

De otra forma, solo será una pérdida de tiempo y en algunos casos (combobox, por ejemplo) un embrollo.
De ninguna manera se justifica la siguiente secuencia:
Thisform.Refresh
Thisform.release
Esto lo único que puede significar es que uno no tiene en claro qué cosa hace cada evento o método.

Nota 2)
Trata de que Thisform.Release se ubique una sola vez dentro de un método. En algunos casos es necesario utilizar una variable Flag para saber si debe ejecutarse la liberación o no. Ello es preferible a repertir el Release por todas partes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
* En el LOAD del formulario Frm_Ingreso con Addproperty()
* O declaras la propiedad en el diseñador de formularios.  tHISFORM.REtorna=0
* Si la declaras en el diseñador también la verás en el IDE, lo cual suele ser una ventaja.
 
*<Load>
IF !PEMSTATUS(Thisform,"Retorna",5)
         ADDPROPERTY(thisform,"Retorna",0)
ELSE
        THISFORM.RETORNA=0
ENDIF
*</Load>
 
* Botón de Aceptar Usuario en Frm_Ingreso
*<CmdAceptar.Click>
select empleados
e=alltrim(proper(thisform.txtnombre.value))
c=alltrim(thisform.txtclave.value)
locate for alltrim(proper(e)) = alltrim(proper(empleados.nombre))
if found()
	if alltrim(c) = alltrim(empleados.Clave)
		ADDPROPERTY(_Screen,"Usuario",TRIM(empleados.nombre))
		thisform.retorna=VAL(ALLTRIM(cargo))
	else
		messagebox("CLAVE INCORRECTA VERIFIQUE")
		thisform.txtNombre.SetFocus
		RETURN
	endif
else
	messagebox("NOMBRE DE USUARIO INCORRECTO VERIFIQUE")
	thisform.TxtClave.Setfocus
	RETURN
ENDIF
 
Thisform.Release
*</CmdAceptar.Click>
 
 
* Programa Principal (inicio de la aplicación)
*<Main.prg>
* Comandos de inicializacion y SET
*
LOCAL lnREspuesta,lcMessage
lcMessage="Hola "
lnREspuesta=0
DO FORM \forms\Frm_Ingreso TO lnRespuesta
IF EMPTY(lnRespuesta)
	* Rutina de Cierre de la aplicación
	QUIT
ENDIF
DO CASE
 
	CASE LnRespuesta=1
		lcMessage=lcMessage ;
			+CHR(13);
			+"BIENVENIDO ADMINISTRADOR"
		do "menuadmi.mpr"
 
	CASE lnREspuesta=2
		LcMessage=lcMessage ;
			+CHR(13);
			+"BIENVENIDO VENDEDOR"
 
		do "menuven.mpr"
 
ENDCASE
MESSAGEBOX(lcMessage)
 
* OTROS comandos que correspondan
 
* </Main.prg>
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Bitacora en foxpro

Publicado por Marco (19 intervenciones) el 01/03/2014 20:07:04
Muchas gracias por todo

ya me esta funcionando muy bien el programa

ahora el sgt tengo que mostrar un reporte de por fecha y por cliente tengo sgt codigo

REPORT FORM reporte_facturacion FOR facturas.fecha >= thisform.text1.Value .AND. facturas.fecha <= thisform.text2.Value .AND. facturas.cliente = thisform.combo1.value preview

me muestra desde la fecha pero me muestra todos los de la fecha no por el cliente que especifico

y lo otro que me hace falta es el reporte de productos vendidos desde la fecha
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar