FoxPro/Visual FoxPro - Orientacion sobre Leng. de Prog.

   
Vista:

Orientacion sobre Leng. de Prog.

Publicado por Many (111 intervenciones) el 18/09/2017 03:43:47
Saludo a todos los amigos de este prestigioso foro

Una vez pedí orientaciones para programar en VFP9, me orientaron y me ayudaron hasta llegar a hacer varios programas y usar base de datos MYSQL con foxpro cosa que siempre había soñado.
Nuevamente necesito de sus orientaciones antes de iniciar un proyecto.

Soy maestro de un Centro educativo público y quiero desarrollar un programa que ayude a simplificar las tareas más importantes del centro (registro de estudiantes, entrada de calificaciones, record final, consultas etc).

Desde que me inicie estuve claro que para acezar los datos en mysql debo hacerlo a base de consulta mientras que algunos lenguajes se conectan una vez a la db y luego tienen acceso permanente a la db sin intermediario (cursor) como lo hace Delphi.

Estaría bien trabajar con VFP9 y MYSQL para este sistema de gestión de estudiantes que crece constantemente y que en algunos mementos tendrá de 1 a 20 estudiantes consultando sus calificaciones.

Por falta de conocimientos hace unos años este sistema lo hice en VFP9 y con tablas dbf pero en red no sirvió para nada.

Si creen que puedo tener problemas pueden recomendar algunos y arranco con él para este proyecto.

A la espera de sus recomendaciones como siempre.
Gracias ustedes.
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

Orientacion sobre Leng. de Prog.

Publicado por neo (1605 intervenciones) el 18/09/2017 16:11:03
Si ya tienes experiencia en VFP + MySQL no veo ningun problema para trabajar en red, y si tambien te enfocas en no tener conexion permanente sino que sea conexion / desconexion, puedes tambien estar seguro que tu programa trabajará sin problemas por conexiones simultaneas..

Saludos!
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

Orientacion sobre Leng. de Prog.

Publicado por santiago (431 intervenciones) el 18/09/2017 16:48:26
Hola, si ya habías hecho el sistema con dbf, debería haber funcionado a la perfección en red, tal vez no fue así porque las tablas las abrías en modo exclusivo (es solo especulación), para graficar mejor el asunto, con dbf y fox (cualquier versión) puedes hacer sistemas para múltiples usuarios, es cierto que cuando tienes mas de 25 usuarios en una intranet se pone un poco mas lento, pero eso depende de como programaste tu sistema, en fin si deseas resucitar el que ya hiciste, cuestión de revisar porque no te funciono en red.

Suerte.
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

Orientacion sobre Leng. de Prog.

Publicado por many (111 intervenciones) el 18/09/2017 17:28:19
Saludo
Gracias a todos y estoy claro de lo que dice neo

Pero esto se torna mas interesante que lo que planifiqué:
Tengo un sistema de facturacion en VFP9 con dbf, este funciona de maravilla en una terminal pero cuando lo pongo a trabajar en red hasta con dos pc trabajando ya inician los problemas ejemplo:

Si hay una pc facturando cuando intento entrar en la segunda pc duerme un poco dando a entender que no va a iniciar.
Si abre un form en modo de diseño en otra pc #2 se tarda de la misma manera para abrir.
Si cierra el form estando en diseño también se tarda para guardar y liberarse.

Si esto lo hace con 2 pc imaginemos con mas.

Estoy seguro que el problema es de como manejar las tablas ya que yo la pego todas en el entorno de datos y al abrir cada form necesita cargar todas las tablas y ya están siendo usada entonces el esfuerzo es mayor.

Si logro solucionar que funcionen por lo menos 5 ó 10 pc en red para mi habrá VFP9 por mucho tiempo.

Al parecer necesito saber como abrir y cerrar las tables para reducir este problema ya que me llené de dolor al ver un sistema en VFP9 en varias terminales funcionando muy bien pero no se como lo lograron.

Muchísimas gracias a todos y que el señor les de sabidurías para sigan haciendo lo que hacen por nosotros.

Espero lo antes posible por su respuestas.
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

Orientacion sobre Leng. de Prog.

Publicado por many (111 intervenciones) el 19/09/2017 00:08:41
Saludo a todos

Estoy haciendo un llamando de favor a todos los programadores con experiencia en este tema para ver la posibilidad de echar a andar una programa que hice con mucho sacrificio hasta el punto que se me afecto la vista.

Con las nuevas esperanza que he recibido ya tome un form en una pc y puse una tabla con 10 campos y 10 registros en un servidor.

mapie la carpeta del servidor donde esta la tabla y lo ejecuté.

Hago búsqueda por matricula, ejecuto select, agrego etc pero ya noto que aveces para cargar el form tarda de 5 a 8 segundo conectado desde una solo pc y sin cargar la tabla el servidor ya que así tardaría mas.

Yo tengo un sistema hace 15 años en una red con 8 pc y lo hace muy bien pero en foxpro 2.6.

Quiero seguir aquí, ayúdenme por favor, díganme cual es el truco para no dejar mi tiempo perdido

gracias amigos.
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

Orientacion sobre Leng. de Prog.

Publicado por Fidel José (520 intervenciones) el 19/09/2017 01:47:14
En realidad, se necesitarían saber unas cuantas cosas antes de responder algo sensato.
Que un form se tarde 8 segundos en aparecer indica que algo no está donde debería. Pero hay que ver de qué se habla.

Te comento como trabajo, aunque no estoy convencido de que ayude en algo.
Mi sistema funciona en varias empresas, aunque la más grande utiliza entre 10 y 12 pc más un equipo que hace de servidor (en realidad es un repositorio con carpetas compartidas y no hace otra cosa).

1) El sistema está distribuido por terminal. O sea, cada usuario tiene el sistema y en el servidor solamente se leen y escriben datos.
2) Uso exclusivamente tablas libres (nunca me gustó el contenedor DBC)
3) Utilizo la sesión predeterminada de datos, lo que me obliga a tener un método de control de apertura y cierre de tablas. Esto se puede reemplazar fácilmente utilizando sesión privada, aunque hay que hacerse cargo de algunos detalles.
4) No utlizo el DataEnviromnet.
5) Abro las tablas necesarias en el LOAD de cada form (o en el INIT de los container de clase cuando corresponde)
Todas las tablas se abren con el modelo:
USE (addbs(path)+"tabla") IN 0 SHARED
6) Cierro las tablas en el Destroy o UNLOAD del form (o en el Destroy de los container de clase cuando corresponde)
Nota: las tablas se abren y se cierran físicamente dependiendo del programa de control de tablas.
No utilizo recursos mapeados. En su lugar, de ser posible, trato de que la red tenga direcciones IP estáticas y en lugar del nombre del servidor en la red, utilizo su dirección IP + REcurso compartido.
Supongamos que el servidor está en la IP 192.168.0.1 y el recurso compartido se llama "Sistema", podemos crear una variable pública con la dirección (yo la guardo en un archivo txt)
ADDPROPERTY(_Screen,"dapserv", "\\192.168.0.1\sistemas")
Luego para abrir una tabla que está en el servidor\Sistemas\Datos
USE (ADDBS(_SCREEN.DAPSERV)+ADDBS("Datos")+lcTabla ) IN 0 SHARED


7) En todo lo posible evito utilizar tablas locales, temporales o fijas. Uso cursores en lugar de tablas temporales.
8) Utilizo bloqueo manual de registros. Esta es una elección personal, que también deriva de utilizar tablas libres.
9) Utilizo INSERT INTO en lugar de APPEND BLANK + REPLACE. Incluso para cursores.
10) Desbloqueo registros inmediatamente (UNLOCK)
11) Envío un comando FLUSH después de cada sesión de grabación.

En cuanto a la interfaz.
1) Trato de evitar en todo lo posible el uso de formularios modales. No porque sean lentos, sino porque cierran el uso de la interfaz, y porque dadas ciertas circunstancias, pueden hacer que el enfoque se mude a otra parte y nos quedamos colgados.
2) He construido una biblioteca de clases visuales con todos los objetos que necesito (distintos textbox según el uso, editbox, commandbutton, commnadgroup, container, forms, etc) de modo que los forms o los containers de clase solamente utilizan los objetos de la clase y no los Textbox, editbox, etc estándar.
3) He construido clases no visuales que se utilizan en distintos formularios y procesos. Por ejemplo, utilizo una sola clase grid que se implementa mediante una clase no visual. En cada form, solamente se atribuyen los valores correspondientes a la clase no visual y ésta se encarga de construir el control grid y adjuntar los otros objetos que utilizo asociados.
4) He agregado el control de errores TRY / CATCH / ENDTRY en todos los objetos de clase y todos los procedimientos que voy relevando. De esta forma, he podido aprender de mis propios errores de acuerdo a los registro de errores de cada usuario.

En cuanto a los datos.
Como siempre, el diseño de tablas debe ser lo más compacto posible. Cuando una tabla tiene campos que quedan vacíos en una multitud de registros, resulta evidente que había que crear una tabla asociada para guardar esos datos.
Si se apunta al uso de SELECT SQL, hay que ser cuidadoso en el sentido de construir índices que resulten útiles para este comando y para la tecnología rushmore. De lo contrario, las consultas pueden ser impiadosas. Los índices deben responder al modelo de consulta, de lo contrario, el comando SQL construirá sus propios índices y el resultado será una espera importante, cuando se trabaja en red.

Cuestiones generales:
1) Evitar la macrosustitución toda vez que resulte posible
Algunos ejemplos
SELECT (lcCursor) en lugar de SELECT &lcCursor
lnDato = Evaluate(m.lcCursor + "." + m.lcCampo) en lugar de lnDato = &lcCursor..&lcCampo

En muchos casos resulta necesario el dominio de las referencias de objetos
Por ejemplo, se puede pasar el nombre de un objeto como parámetro

Thisform.TalProc(This.Name)
* Procedure TalProc
LPARAMETERS tcName
thisform.&lcName..Value = x

Thisform.TalProc(this)
* Procedure TalProc
LPARAMETERS toObject
toObject.Value = x

2) Evitar las variables públicas
3) Declarar las variables locales como tales al inicio de un método
4) Usar el prefijo "m." para referirse a variables de memoria (evita que VFP busque en la tabla o cursor del área de trabajo, con lo que en procesos largos se nota el ahorro de tiempo y de paso se conoce de donde vienen los valores).
5) Utilizar las propiedades de formulario o de clase en lugar de variables locales permite que un formulario pueda tener instancia múltiple sin conflictos de ningún tipo.

6) No utilizar SET FILTER en tablas de uso compartido. Esto es cómodo pero insoportable como resultado. Crear las consultas SQL que correspondan en su lugar.
7) Si se utiliza el comando SET RELATION, implementarlo sobre tablas abiertas con ALIAS AGAIN y que el Alias esté reservado para es uso.

Bueno, ya es muy largo. Aunque no suficiente.
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

Orientacion sobre Leng. de Prog.

Publicado por many (111 intervenciones) el 19/09/2017 06:03:00
Buenas noches
He quedado sin palabras

Rápidamente he identificado varios errores que son mortales en este ambiente de programación:

Mi primer problema esta en que uso DataEnviromnet y mapeo la carpeta que contiene las tablas en el servidor.
hay que tener claro que cada ves que una terminal entra carga el DataEnviromnet y se activan todas las tablas en todas las terminales, creo que es problema mas grande que tengo.

Guardo usando append blank y replace.

Son varias cosas, primero voy limpiar mi programa y luego te digo en este mismo tema.

Gracias a todos por el 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

Orientacion sobre Leng. de Prog.

Publicado por many (111 intervenciones) el 20/09/2017 01:13:27
Saludo amigos

Inicié por esta parte ya que se que es el gran problema

ruta = ADDPROPERTY(_Screen,"dapserv", "\\10.0.0.198\dbliceo")
USE (ADDBS(_SCREEN.DAPSERV)+ADDBS("estudiantes")+ruta ) IN 0 SHARED

Pero me dice que los datos no coinciden

Esta es la linea que me enviaron y no veo la variable lctabla declarada en parte a anterior que me da error la puse ruta.
USE (ADDBS(_SCREEN.DAPSERV)+ADDBS("Datos")+lcTabla ) IN 0 SHARED

Donde esta mi error, por favor
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

Orientacion sobre Leng. de Prog.

Publicado por Fidel José (520 intervenciones) el 20/09/2017 15:38:30
Hola Many:
En ese ejemplo, lcTabla es una variable que representa el nombre de una tabla.

Mira este ejemplo:
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
PROCEDURE NetUse
LPARAMETERS tcTabla, tlExclusive, tnIntentos ,tcAlias ,TlNotVerbose,tlNoUpDate
*!*	-----------------------------------------------------------------------------
*!*	Procedimiento de apertura de tablas
*!*	tcTabla			Addbs(path)+table_Name
*!*	tlExclusive 		.f. (shared) // tlExclusive (.t.) Exclusive
*!*	tnIntentos		9 por defecto
*!*	tcAlias			Alias con que se usará la tabla
*!*	TlNotVerbose		No presenta mensajes
*!*	tlNoUpdate		.t. Abre la tabla en solo lectura
*!*     Sample:                  lOpenTabla = NetUse(Addbs(_screen.dapsev)+addbs("Datos")+"Fleteros" )
*!*	-----------------------------------------------------------------------------
 
TRY
	LOCAL lcAlias,;
		lcCursor,;
		lcFileName,;
		lForever,;
		lRetop,;
		NCASOP,;
		loex as Exception
 
 
	tcAlias = iif(Vartype(m.tcAlias)#"C","",m.tcAlias)
	tnIntentos = EVL(tnIntentos,9)
	nCasop = 0
	tcTabla = ALLTRIM(m.tcTabla)
	lcCursor = JUSTSTEM(m.tcTabla)
	lcFileName = FORCEEXT(m.tcTabla,"dbf")
 
	lRetop = USED( EVL(m.tcAlias,m.lcCursor) )
	IF !m.lRetop
		IF FILE(m.lcFileName)
 
			DO WHILE .t.
				IF EMPTY(m.tcAlias)
					lcAlias=JUSTSTEM(m.tcTabla)
					IF m.tlExclusive
						USE (m.tcTabla) IN 0 EXCLUSIVE AGAIN
					ELSE
						USE (m.tcTabla) IN 0 SHARED AGAIN
			 		ENDIF
				ELSE
					lcAlias = m.tcAlias
 
					IF m.tlNoUpdate
						IF m.tlExclusive
							USE (m.tcTabla) IN 0 EXCLUSIVE AGAIN alias (m.tcAlias) NOUPDATE
						ELSE
							USE (m.tcTabla) IN 0 SHARED AGAIN ALIAS (m.tcAlias) NOUPDATE
					 	ENDIF
					ELSE
						IF m.tlExclusive
							USE (m.tcTabla) IN 0 EXCLUSIVE AGAIN alias (m.tcAlias)
						ELSE
							USE (m.tcTabla) IN 0 SHARED AGAIN ALIAS (m.tcAlias)
					 	ENDIF
					ENDIF
				ENDIF
				IF USED(m.lcAlias)
					lRetop = .t.
					EXIT
				ENDIF
 
				nCasop = m.nCasop + 1
				if nCasop <= m.tnIntentos
					LOOP
				ENDIF
				lRetop=.f.
				nMess = Messagebox(tcTabla+" no pudo abrirse tras "+transform(nCasop)+" intentos.",5,Proper(PROGRAM()))
				if m.nmess = 4
					nCasop = 0
					LOOP
				ELSE
					EXIT
				ENDIF
 
			ENDDO
		ELSE
			IF !tlNotVerbose
				MESSAGEBOX("El archivo "+LOWER(m.lcFileName)+" No Existe!",0,PROPER(PROGRAM()))
			ENDIF
		ENDIF
	ENDIF
CATCH TO loex
	loex.UserValue = PROGRAM()
	ShowError(loex)      && rutina que muestra un mensaje de error
FINALLY
 
ENDTRY
RETURN m.lretop
ENDPROC
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

Orientacion sobre Leng. de Prog.

Publicado por neo (1605 intervenciones) el 25/09/2017 17:56:59
Si necesitas ayuda por interno, puedes contactarme por email:
vfxprogrammer@gmail.com

Saludos!
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

Orientacion sobre Leng. de Prog.

Publicado por many (111 intervenciones) el 26/09/2017 05:06:25
Estimados y repetados amigos,

Aquí aclaro bien mi problema y pediré ayuda por parte según necesite ya aunque la agradezco hay ayudas como son buenas son de abundantes y nos suelen quedar un grande a los novatos.

Estoy teniendo problemas de lentitud con la conexión a tablas libres dbf que tengo en un servidor.

Ya he entendido que cuando se cargan las tablas desde el programa que corre en las terminales todo se torna lento debido a que las tablas están siempre cargadas en memoria y el programa apuntando constantemente a estas, no hay sistema que aguante esto en la red.
Según lo que he leído de ustedes lógicamente se cómo debe funcionar solo que me faltan herramientas y he aquí donde necesito ayuda.

Tengo una pc llamada servidor, ip=10.0.0.198
En esta misma pc llamada servidor tengo una carpeta llamada DBLICEO, en esta están las tablas libres que usa el sistema

Las tablas se llaman estudiantes, grados, áreas, docentes etc.

La carpeta DBLICEO a la que me refiero esta en la unidad D del servidor ya mencionado.

Tomando parte de la lógica de nuestro amigo Plinio necesito una variable para guardar la ruta donde se encuentran las tablas ejemplo:

Ruta = \\10.0.0.198\d\dbliceo algo así.

Luego

Otros códigos para llamar cualquier tabla usando la variable Ruta preferiblemente SQL pero no se como hacer para esta segunda linea

De esta manera mis tablas estarán cerrado y en reposo se tocaran al momento de insertar,actualizar,consultar etc.

Con esto sé que poder arrancar y el camino me la iré arreglando.

Por otro lado:
Quiero que me digan las ventajas de usar alias en ves del mismo nombre de la tabla.

No tengo como agradecerle ya que donde estoy solo yo programo en FOX.

Gracias a todos.
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
Imágen de perfil de Leonardo Daniel A.

Orientacion sobre Leng. de Prog.

Publicado por Leonardo Daniel A. (162 intervenciones) el 26/09/2017 05:32:23
Hola, yo eh tenido sistemas con mas de 60mil registros y varios usuarios consultando sin problemas.. siempre y cuando tengas bien definidos tus indices de busqueda y que sean estructurales (CDX), se supone que cuando haces una consulta SQL debe de tomar el indice que utilizs en el where, pero me eh dado cuenta de que no es asi... lo que hago es abrir las tablas que necesito, incluyendo las que hare consultas y les pongo el indice que usara

select 1
use nf1718 alias nomina

sele 2
use df1718a alias detalle order tag rfc

**** si es que voy a hacer un select * from detalle where rfc = 'algo'
*** o algun if seek( 'RRERR', 'detalle' )

pero no tiene nada que ver el abrir varias tablas, pues que solo las abres, no estas leyendo los datos
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

Orientacion sobre Leng. de Prog.

Publicado por Fidel José (520 intervenciones) el 26/09/2017 17:35:07
Many
En el servidor debes crear un recurso compartido con la carpeta que contiene los datos:
Si el recurso compartido se llama DBLICEO, la ruta de las tablas será:
\\10.0.0.198\DBLICEO.

Conocer esta ruta es fundamental para sistemas que trabajan distribuidos (los ejecutables en cada máquina). Si trabajas leyendo el ejecutable directamente del servidor, la programación debe ser para rutas relativas.

Ejemplo para el caso de sistemas distribuidos:
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
PROCEDURE get_Ruta
* Crea una propiedad de _Screen con la ruta asignada
* Si no existe el archivo de configuración se intenta crear, detectando la ruta con GetDir()
* ----------------------------------------------------------------
LOCAL lcFileConfig,lcFolder,lcTipíc
lcFileConfig = "localize.cfg"
lcFolder = ""
IF FILE(m.lcFileConfig)
	lcFolder = STREXTRACT(FILETOSTR(m.lcFileConfig),"<","/>")
ENDIF
IF EMPTY(m.lcFolder)
	lcFolder = GETDIR(FULLPATH(""),"Ruta de Datos","Buscando Ruta",48+64)
 
	IF !EMPTY(m.lcFolder)
		* Se puede hacer un test, por ejemplo buscando un archivo típico
		lcTipic = ADDBS(m.lcFolder)+"seguro.dbf"
		IF !FILE(m.lcTipic)
			MESSAGEBOX("La ruta "+m.lcFolder + " es incorrecta")
			lcFolder = ""
		ENDIF
	ENDIF
	IF !EMPTY(m.lcFolder)
		STRTOFILE("<"+m.lcFolder+"/>",m.lcFileConfig)
		ADDPROPERTY(_screen,"Ruta",m.lcFolder)
	ENDIF
ENDIF
IF EMPTY(m.lcFolder)
	MESSAGEBOX("Falta la ruta de datos")
	QUIT
ENDIF
ENDPROC
 
* Ejemplo de apertura de tabla
lcFile = ADDBS(_screen.ruta)+"seguro"
USE (lcFile) IN 0 SHARED

Para el caso de sentencias SQL, siempre es mejor tener las tablas que se han de utilizar abiertas, porque de todos modos habrá que ocuparse de cerrarlas.
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