Compartir Base de Datos en red FoxPro

313 views
Skip to first unread message

Cristhian Martínez

unread,
Jul 16, 2020, 9:25:06 AM7/16/20
to Comunidad de Visual Foxpro en Español
Buenos días
Estoy tratando de hacer funcionar un programita en red de dos pc con windows 10, no lo estoy logrando.
En el servidor (nombre maedi-pc) arranca y funciona perfectamente, pero en la estación al querer iniciar me sale el mensaje
"No se puede encontrar \\maedi-pc\negoc\productos.dbc"
no se por que si al parecer estoy direccionando correctamente el OPEN DATABASE a la carpeta donde se encuentra la base de datos "productos.dbc", en la carpeta C:\negoc\tablas.

No se que error estaría cometiendo, si pudieran ayudarme por favor

Este es el código de mi programa principal

SET EXCLUSIVE OFF
application.visible=.f.
SET TALK OFF
SET DELETED ON
SET CONFIRM ON
SET DECIMALS TO 2
SET ENGINEBEHAVIOR 70
SET HOURS TO 24

PUBLIC equipo, NombreServidor

IF FILE('C:\Windows\winweb.DLL') &&Archivo dll para comprobar si la maquina es servidor
equipo = 'Servidor'
NombreServidor = SUBSTR(SYS(0), 1, AT('#' ,SYS(0), 1)-1)
ELSE
equipo = 'Estación'
ENDIF

IF equipo = 'Servidor'
ServidorTablasRuta = 'C:\negoc\tablas'
SET PATH TO &ServidorTablasRuta
OPEN DATABASE 'C:\negoc\tablas\productos.dbc' SHARED
WAIT WINDOW 'Iniciando sesión en Servidor' TIMEOUT 1
DO FORM inicio
READ EVENTS
ELSE
WAIT WINDOW 'Iniciando sesión en Estación' TIMEOUT 1
DO FORM inicio
READ EVENTS
ENDIF  

Zarlu

unread,
Jul 16, 2020, 9:36:56 AM7/16/20
to Comunidad de Visual Foxpro en Español
Buenos días Cristhian Martínez!

Dices:
"..no se por que si al parecer estoy direccionando correctamente el OPEN DATABASE a la carpeta donde se encuentra la base de datos "productos.dbc", en la carpeta C:\negoc\tablas..."

Pudiera ser ese el detalle. En las terminales debes direccionar incluyendo/mencionando el servidor

Ejemplo:
Set Path To \\Serversistemas\sistnotaria\Notar2011\NotarDBA

Suerte
zarlu
Chetumal, Quintana Roo, México

Cristhian Martínez

unread,
Jul 16, 2020, 11:01:33 AM7/16/20
to Comunidad de Visual Foxpro en Español
Gracias por la respuesta amigo
Hice lo que me dijiste y funciona perfectamente, pero en este caso estoy obligado a cambiar el nombre de la PC servidor a maedi-pc. 
Lo que me gustaría es guardar el nombre del servidor en una variable, para no tener que estar cambiando el nombre de la PC.

Al querer hacer asi me salen tres errores
1. Incompatibilidad entre el tipo de operador y el tipo de operando (Pasar por Alto)
2.  Incompatibilidad entre el tipo de operador y el tipo de operando (Pasar por Alto)
3. Error al crear instancia del objeto Cursor. No se puede encontrar \\maedi-pc\negoc\productos.dbc

Este es el código del prg principal.  

SET EXCLUSIVE OFF
application.visible=.f.
SET TALK OFF
SET DELETED ON
SET CONFIRM ON
SET DECIMALS TO 2
SET ENGINEBEHAVIOR 70
SET HOURS TO 24

PUBLIC equipo, impr, objeto_con_enfoque, NombreServidor
fecha=DATE()

IF FILE('\Windows\winweb.DLL') &&Si el archivo existe, es servidor
equipo = 'Servidor'
NombreServidor = SUBSTR(SYS(0), 1, AT('#' ,SYS(0), 1)-1) &&Nombre del servidor - "maedi-pc"
ELSE
equipo = 'Estación'
ENDIF

IF equipo = 'Servidor'
SET PATH TO CURDIR(),tablas,informes
OPEN DATABASE  productos  SHARED
WAIT WINDOW 'Iniciando sesión en Servidor' TIMEOUT 1
DO FORM rotulo
READ EVENTS
ELSE
SET PATH TO \\maedi-pc\negoc\tablas                                           && Asi funciona
OPEN DATABASE \\maedi-pc\negoc\tablas\negocio.dbc             && Asi funciona
*SET PATH TO '\\'+ALLTRIM(NombreServidor)+'\negoc\tablas'   && Asi no funciona
*OPEN DATABASE '\\'+ALLTRIM(NombreServidor)+'\negoc\tablas\ productos.dbc'         && Asi no funciona
WAIT WINDOW 'Iniciando sesión en Estación' TIMEOUT 1
DO FORM rotulo
READ EVENTS
ENDIF

Zarlu

unread,
Jul 16, 2020, 11:45:59 AM7/16/20
to Comunidad de Visual Foxpro en Español
Qué tal Cristhian Martínez!

Espero no confundirte.
Como siempre hay varias formas y opiniones respecto de como hacerlo...

En mi caso en las pc donde se ejecuta la aplicación instalo una tabla que contiene, entre otros, la ruta de los archivos.
Te muestro una parte del código principal  para que lo analices...

............
*-prg de procesos
SET PROCEDURE TO procesos
*-variables sistema
_screen.addproperty("spExe")&&dir de arranque
_screen.addproperty("spPath")&&path
_screen.addproperty("spDat")&&dir de datos recno 1
_screen.addproperty("spRespal")&&dir de respaldo recno 2
_screen.addproperty("spUser")&&usuario logeado
_screen.spUser=""
*-dir tablas
USE pathdat.dbf IN 0 ALIAS rutas SHARED
Sele rutas
losdirec()&&carga directorios en variables
USE
*-dir arranque
_screen.spExe=LEFT(sys(16,1),RAT("\",sys(16,1))-1)&&dir ejecutable
*-path
_Screen.spPath=_screen.spExe+"; "+_screen.spDat
*- seteos
seteos()&&aqui se incluye el set path con la variable 
...............

Puntualizo que es una parte de muestra de un código.
En las aplicaciones se incluye un módulo para cambiar esos directorios si se requiere

zarlu
Chetumal, Quintana roo, México

Edwin Duran

unread,
Jul 16, 2020, 11:47:06 AM7/16/20
to Comunidad de Visual Foxpro en Español
Donde colocar el exe, en cada pc on en servidor

Cristhian Martínez

unread,
Jul 16, 2020, 2:05:41 PM7/16/20
to Comunidad de Visual Foxpro en Español
Muchas gracias por sus respuestas
He probado con el exe solo en el servidor y también copiando el exe en la estación (en este caso da error porque no encuentra la base de datos en la ubicación donde copio el exe)
He intentado analizar lo que Zarlu me propuso, pero no lo entiendo (soy nuevo aun en esto de la programacion)

Recalco que me ha funcionado perfectamente escribiendo directamente la dirección de las tablas en el servidor  dejando el código en el cual están los comentarios "&&Asi funciona"
La única diferencia sería que en vez de poner el nombre del servidor "maedi-pc", ponga una variable con este nombre. 
Eso es lo que quise hacer en las lineas con los comentarios &&Asi no funciona.

IF equipo = 'Servidor'
SET PATH TO CURDIR(),tablas,informes
OPEN DATABASE  productos  SHARED
WAIT WINDOW 'Iniciando sesión en Servidor' TIMEOUT 1
DO FORM rotulo
READ EVENTS
ELSE
SET PATH TO \\maedi-pc\negoc\tablas                                           && Asi funciona
OPEN DATABASE \\maedi-pc\negoc\tablas\negocio.dbc             && Asi funciona
*SET PATH TO '\\'+ALLTRIM(NombreServidor)+'\negoc\tablas'   && Asi no funciona
*OPEN DATABASE '\\'+ALLTRIM(NombreServidor)+'\negoc\tablas\ productos.dbc'         && Asi no funciona
WAIT WINDOW 'Iniciando sesión en Estación' TIMEOUT 1
DO FORM rotulo
READ EVENTS
ENDIF

Gracias

Cristhian Martinez 

alvarocastellar

unread,
Jul 16, 2020, 2:23:04 PM7/16/20
to Comunidad de Visual Foxpro en Español
para mi no lo necesitas,  esas dos lineas funcionan tanto para el equipo servidor como para la estacion haz la prueba y te daras cuentas, omite todo las lineas que serian para la estacion,


SET PATH TO CURDIR(),tablas,informes
OPEN DATABASE  productos  SHARED
WAIT WINDOW 'Iniciando sesión en el programa ' TIMEOUT 1
DO FORM rotulo
READ EVENTS

Pruebalo asi desde el servidor y desde la estacion, veras que te funciona.  Genera un exe y haz la prueba

Zarlu

unread,
Jul 16, 2020, 2:33:38 PM7/16/20
to Comunidad de Visual Foxpro en Español
Qué tal Cristhian Martínez!

Trataré con otro ejemplo:
lcPath="\\Server\sistnotaria\Notar2011"&&path en terminales
IF equipo = 'Servidor'
lcPath="c:\sistnotaria\Notar2011"&&path en servidor
EndIF
Set Path To (lcPath)
.....

Cristhian Martínez

unread,
Jul 16, 2020, 2:47:38 PM7/16/20
to Comunidad de Visual Foxpro en Español
Hola Zarlu
En el ejemplo que me das el nombre del servidor debe ser necesariamente "Server"
Como puedo hacer para guardar el nombre del servidor en una variable? Para no tener problemas por si alguien cambia el nombre del servidor.

Y quede algo así:

lcPath="\\VariableConElNombreDelServidor\sistnotaria\Notar2011"&&path en terminales
IF equipo = 'Servidor'
lcPath="c:\sistnotaria\Notar2011"&&path en servidor
EndIF
Set Path To (lcPath)

Gracias

Zarlu

unread,
Jul 16, 2020, 4:07:10 PM7/16/20
to Comunidad de Visual Foxpro en Español
Qué tal Cristhian Martínez!

En el ejemplo anterior "Server" es el nombre del equipo que funciona como servidor.
Debes adaptarlo al nombre de tu equipo servidor

Para "...por si alguien cambia el nombre del servidor." maneja seguridad en el equipo.
Digo....si en grupo de trabajo alguien cambia el nombre del servidor hay que redireccionar todos los equipos.

Cristhian Martínez

unread,
Jul 16, 2020, 4:21:45 PM7/16/20
to Comunidad de Visual Foxpro en Español
Justamente para evitar eso quería que se cargue el nombre del equipo servidor en una variable. Siempre hay alguno que se mete donde no debe.
Ya para cerrar el tema. Entonces no es posible hacer los que pretendo?

Gracias

Cristhian Martinez

Alvaro Castellar

unread,
Jul 16, 2020, 4:50:31 PM7/16/20
to publice...@googlegroups.com
Hola cristian usa ese codigo para pbtener el nombre del equipo,  creo que no supe entender tu inconveniente  espero este codigo te sirva:

goACC = Create("VEActiveConnectionsController")
goACC.SharedFolder = Sys(5)+Sys(2003)
cEstacion = goacc.WORKSTATIONID


aqui te mando el codigo:


Define Class VEActiveConnectionsController As Custom
*
SharedFolder = ".\"  && Ubicacion de la carpeta compartida a utilizar para crear los archivos de marca
MaxConnections = 0   && Nro. máximo de conexiones permitidas
WorkstationID = ""   && ID de la estacion. Si no se indica, se asume el nombre del equipo.
MarkFileExt = "ACM"  && Extension de los archivos de marca. Si no se indica se asume .ACM
LastError = ""   && Texto del ultimo error ocurrido
checkConnectionEvery = 0  && Frecuencia (en minutos) para la verificacion del archivo de marca (0 = nunca)
onConnectionLost = ""     && Codigo a ejecutar si la conexion con el archivo de marca se pierde
Hidden nFH   && Handle del archivo de marca correspondiente al proceso actual
Hidden oTimer1       && Timer para verificacion de estado de conexion


* Class constructor
* Constructor de la clase
*
Proc Init()
*
This.WorkstationID = Allt(Left(Sys(0),At("#",Sys(0)) - 1))
This.nFH = 0
This.oTimer1 = Create("VEACCTimer")
This.oTimer1.Enabled = .F.
*
Endproc


* GetCurrentMarkFile
* Devuelve el nombre y ruta del archivo de marca correspondiente
* a la estacion actual
*
Proc GetCurrentMarkFile()
*
Local cMarkFile
cMarkFile=Forceext(This.WorkstationID,This.MarkFileExt)
cMarkFile=Forcepath(cMarkFile,This.SharedFolder)
cMarkFile=Lower(cMarkFile)

Return cMarkFile
*
Endproc


* GetActiveConnectionsCount
* Devuelve el nro. de conexiones concurrentes activas. Esto se logra
* contanto cuantos archivos existentes en la carpeta compartida aun
* estan bloqueados por otro proceso.
*
Proc GetActiveConnectionsCount()
*
Local nActiveCount,nCount,i,cFile,nFH
Local Array aFiles[1]
nCount=Adir(aFiles,Addbs(This.SharedFolder)+"*."+This.MarkFileExt)
nActiveCount = 0

For i=1 To nCount
*
* Se obtiene el nombre y ubicacion del archivo de marca a validar
cFile=Lower(Forcepath(aFiles[i,1],This.SharedFolder))

* Se intenta abrir el archivo de marca para escritura
nFH=Fopen(cFile,1)

* Si no se pudo abrir el archivo significa que hay un proceso activo
* que aun lo tiene bloqueado, por lo que se cuenta como una conexion
* activa, de lo contrario se cierra el archivo y se elimina pues
* corresponde a una conexion que termino anormalmente (ya que si
* hubiera terminado normalmente, el archivo habria sido borrado por
* la aplicacion directamente).
If nFH < 0
nActiveCount=nActiveCount + 1
Else
Fclose(nFH)
Erase (cFile)
Endif
*
Endfor


Return nActiveCount
*
Endproc


* Connect
* Determina si hay conexiones disponibles y procede a crear
* un archivo de marca. El metodo devuelte:
*
* 1  si se pudo crear la conexion
* 0  si no hay conexiones disponibles
* -1 la estacion ya esta conectada
* -2 si no se pudo crear el archivo de marca
*
Proc Connect()
*
* Se determina la cantidad de conexiones activas
Local nActiveCount
nActiveCount = This.GetActiveConnectionsCount()

* Si no hay mas conexiones disponibles, se cancela
* en este punto. Se utiliza >= y no solo = por razones
* de programacion defensiva.
If nActiveCount >= This.MaxConnections
This.LastError = "No hay conexiones disponibles"
Return 0
Endif

* Si ya exite un archivo de marca para la estacion, se
* cancela pues se asume que el programa ya esta en
* ejecucion en la estacion
Local cMarkFile
cMarkFile = This.GetCurrentMarkFile()
If File(cMarkFile)
This.LastError = "Esta estación ya está conectada al programa Armagedon"
Return -1
Endif


* Se crea el de marca
This.nFH = Fcreate(cMarkFile)
If This.nFH < 0
This.LastError = "No se pudo crear el archivo " + cMarkFile
Return -2
Endif

* Si se indico un intervalo para verificar la conexion, se configura el timer y se inicia
If This.checkConnectionEvery > 0
This.oTimer1.Set(This)
Endif

Return 1
*
Endproc



* Disconnect
* Libera el archivo de marca correspondiente al proceso actual
*
Proc Disconnect()
*
* Si no hay un archivo de marca creado, se cancela
If This.nFH = 0
Return
Endif

* Se cierra y elimina el archivo de marca
Local cMarkFile
cMarkFile = This.GetCurrentMarkFile()
Fclose(This.nFH)
Erase (cMarkFile)

* Se libera el timer de verificacion
This.oTimer1.Clear()
*
Endproc

Proc foo
Fclose(This.nFH)
Endproc

* IsAlive
* Determina si el archivo de marca aun es valido
*
Proc IsAlive
*
* Si no hay un archivo de marca creado, se cancela
If This.nFH = 0
Return .F.
Endif

Return Fflush(This.nFH)
*
Endproc
*
Enddefine


* VEACCTimer
* Timer de verificacion de conexion para VEActiveConnectionController
*
Define Class VEACCTimer As Timer
*
Target = Null

Procedure Set(poTarget)
This.Target = poTarget
This.Interval = poTarget.checkConnectionEvery * 60 * 1000
This.Enabled = .T.
Endproc

Procedure Timer
This.Enabled = .F.

If This.Target.IsAlive()
This.Enabled = .T.
Return
Endif
If !Empty(This.Target.onConnectionLost)
Local cCmd
cCmd = This.Target.onConnectionLost
If " 06.00" $ Version()
&cCmd
Else
Execscript(cCmd)
Endif
Endif
Endproc

Procedure Clear
This.Enabled = .F.
This.Target = Null
Endproc
*
Enddefine


--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito a un tema del grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/publicesvfoxpro/KhclowIBg98/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/994a223c-5efd-44e8-98ef-ef86bb166c29n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages