PDA

Ver la Versión Completa : Diseño de sistema en RED LAN


pelikno
02-05-2012, 14:45:59
Hola gente, gracias de ante mano, y quería ver si me podían ayudar a organizar mi sistema en red.
Tengo una maquina la cual sera el servidor del sistema y tendria el ejecutable con la base de datos firebird. Las componentes para conectar a la base son interbase (databse,transaction) y para el AMB dbgrid,datasourse y ibtable.
Quería saber si esta bien y que me recomiendan para poder manejar los abm correctamente entre los clientes y la información de la base se actualice bien , ya que probé altas y bajas de un cliente y hasta q no cierro el sistema en el otro, la grilla no me muestra los datos correctos.
La base la tengo conectada con una configuración remota por medio de la iplocal del servidor y la ruta donde se encuentra mi base.fdb.
Si me falta alguna información adicional para que me den una mano avisen.
Desde ya muchísimas gracias !!

MartinS
02-05-2012, 15:01:27
Hola pelikno: ¿Miraste el tutorial (http://www.clubdelphi.com/foros/showthread.php?t=68708) de Caral?. Ahi explica todo lo que necesitas y en cuanto a las actualizaciones de datos creo que el problema esta en la configuracion del componente de transacciones que también explica dicho tutorial.-

Saludos.-

pelikno
02-05-2012, 15:08:46
Hola pelikno: ¿Miraste el tutorial (http://www.clubdelphi.com/foros/showthread.php?t=68708) de Caral?. Ahi explica todo lo que necesitas y en cuanto a las actualizaciones de datos creo que el problema esta en la configuracion del componente de transacciones que también explica dicho tutorial.-

Saludos.-

Gracias ahi lo miro !!!

pelikno
02-05-2012, 15:26:15
Gracias ahi lo miro !!!

Lo vi pero es solamente para conectar la base firebird y yo lo que busco es ver si estoy haciendo bien el diseño de mi sistema para que funcione correctamente en red, estoy probando ejecutar el sistema desde otra maquina por medio de un acceso directo al .exe y arranca bien, me muestra los datos de la base, pero al modificar algo no me lo refleja los cambios en las otras maquinas, me explico ?
Ejecuto el sistema en las dos maquinas(servidor y cliente), luego del cliente elimino un registro y en la grilla del servidor no me lo refleja.
en el evento afterpost de mi tabla localidades coloque esto lo cual no genero ningun efecto.

localidades.ApplyUpdates;
localidades.Refresh;

Casimiro Notevi
02-05-2012, 15:37:33
Hola, creo que has vuelto a olvidar decir con qué componentes estás trabajando, entre otras cosas ;)
Lo que te acaban de recomendar es muy importante, tienes que verificar el tema de transacciones.
Además, tampoco te recomiendo que por internet trabajes de esa forma, debes tener el programa ejecutable en cada equipo/terminal y estos se conectarán al servidor donde está la base de datos.
También puedes trabajar como has indicado, accediendo al ejecutable en el servidor, pero entonces te recomiendo un VPN o un programa del estilo "terminal server".
Definitivamente, falta mucha más información de lo que estás haciendo, de cómo lo haces, de qué quieres conseguir exactamente, etc.

Por cierto, decías que era una conexión por internet y ahora dices que es una red local. Es muy diferente. Casi que no valen los consejos anteriores con el nuevo entorno que indicas.
Repito, información amplia, detallada y clara ;)

pelikno
02-05-2012, 15:45:52
Hola, creo que has vuelto a olvidar decir con qué componentes estás trabajando, entre otras cosas ;)
Lo que te acaban de recomendar es muy importante, tienes que verificar el tema de transacciones.
Además, tampoco te recomiendo que por internet trabajes de esa forma, debes tener el programa ejecutable en cada equipo/terminal y estos se conectarán al servidor donde está la base de datos.
También puedes trabajar como has indicado, accediendo al ejecutable en el servidor, pero entonces te recomiendo un VPN o un programa del estilo "terminal server".
Definitivamente, falta mucha más información de lo que estás haciendo, de cómo lo haces, de qué quieres conseguir exactamente, etc.

Por cierto, decías que era una conexión por internet y ahora dices que es una red local. Es muy diferente. Casi que no valen los consejos anteriores con el nuevo entorno que indicas.
Repito, información amplia, detallada y clara ;)
" firebird. Las componentes para conectar a la base son interbase (databse,transaction) y para el AMB dbgrid,datasourse y ibtable."
Por el tema de la conexion a internet, no hay , ya que es una conexion LAN como dice en el titulo.
Lo que quiero conseguir es que al realizar cambios en la base se me reflejen en todos tanto en el servidor como en los clientes.

Decime donde dije que era por internet asi lo modifico gracias ;)

MartinS
02-05-2012, 15:54:27
Podrias poner el codigo donde das el alta?. En algun lugar haces

TuTransaccion.commit;

Pd.: Yo sigo con que son las transacciones y con el permiso del compañero Casimiro pongo esto (www.intitec.com/varios/transacciones-0.2.6.pdf) que una vez me sugirio

pelikno
02-05-2012, 15:58:41
Mi ibtransaction esta configurada como el tutorial igual que la ibdatabase , sera alguna propiedad de las tablas que no esta correctamente seteada para que actualice los datos o se refresque correctamente ?, porque elimino un registro en la tabla localidades desde el cliente (el cual se ejecuta por medio de un acceso directo a la unidad compartida con el servidor en donde se encuentra miprograma.exe) y en la tabla localidades del servidor (es la maquina en la red lan la cual alberga el sistema y la base de datos firebird 2.5 y el dbms tambien) sigue figurando el registro supuestamente eliminado. Para que se vea la eliminación tengo que cerrar el sistema y volverlo abrir y ahí si se ven los cambios de la eliminación.

Casimiro Notevi
02-05-2012, 16:01:00
Decime donde dije que era por internet asi lo modifico gracias ;)
Aquí hablaste de conectar remotamente con la IP local, eso da a entender que la conexión es por internet .
Ya pude crear el instalador y conecte la base firebird remotamente con ip local



Pd.: Yo sigo con que son las transacciones y con el permiso del compañero Casimiro pongo esto (http://www.intitec.com/varios/transacciones-0.2.6.pdf) que una vez me sugirio
Sí, casi con total seguridad es problema de transacciones, y ese documento es el "padre nuestro" sobre las tracciones :)

pelikno
02-05-2012, 16:01:06
Podrias poner el codigo donde das el alta?. En algun lugar haces

TuTransaccion.commit;

Pd.: Yo sigo con que son las transacciones y con el permiso del compañero Casimiro pongo esto (www.intitec.com/varios/transacciones-0.2.6.pdf) que una vez me sugirio

Uso un dbNavigator para manipular la grilla, uso el append del navigator para crear un nuevo registro y edito los datos directamente de la grilla, luego guardo los cambios tb con el navigator.

Casimiro Notevi
02-05-2012, 16:06:54
Amigo pelikno, lo que comentas es asunto de las transacciones, el documento antes indicado es "primordial" en ese tema. Te aconsejo que lo leas y lo comprendas claramente para tener las ideas claras al respecto.
También haz una búsqueda por un tema que hemos tratado en otras ocasiones y tiene que ver con todo esto: post_event (http://www.janus-software.com/fbmanual/manual.php?book=psql&topic=102)
Se trata de hacer saltar un evento en la base de datos para hacer "algo" que requerimos, cosa que también te viene bien para este caso.

Edito: por cierto, parece que te estuvieras enfadando por que intentemos ayudarte :confused:

pelikno
02-05-2012, 16:13:26
Aquí hablaste de conectar remotamente con la IP local, eso da a entender que la conexión es por internet .


[/I]


Sí, casi con total seguridad es problema de transacciones, y ese documento es el "padre nuestro" sobre las tracciones :)

Por lo de internet, interpreto ip publica 190.x.x.x como Internet y local como por ejemplo 192.x.x.x ademas de LAN ( local area network) supuse que se interpretaria por el lado correcto, aunque creo que remotamente quiere decir que no se incia el sistema con el archivo ejecutable en la misma computadora sino se instancia desde otra ya sea LAN o WAN o alguna otra forma que no sea en la misma maquina.
Puede que sea un problema de interpretación y si me exprese mal pido disculpas y confirmo que es una red lan con la ip del servidor 192.168.1.226 y el cliente 192.168.1.227, el cliente tiene en el escritorio un acceso directo al .exe de mi aplicación en la carpeta compartida en el servidor

Por el lado de mi problema con los datos tiene que ser algo que me falte en el transaction o en las tablas. Pero el diseño esta correcto no ? me refiero a las componentes que utilizo para mi aplicación.

pelikno
02-05-2012, 16:17:28
Amigo pelikno, lo que comentas es asunto de las transacciones, el documento antes indicado es "primordial" en ese tema. Te aconsejo que lo leas y lo comprendas claramente para tener las ideas claras al respecto.
También haz una búsqueda por un tema que hemos tratado en otras ocasiones y tiene que ver con todo esto: post_event (http://www.janus-software.com/fbmanual/manual.php?book=psql&topic=102)
Se trata de hacer saltar un evento en la base de datos para hacer "algo" que requerimos, cosa que también te viene bien para este caso.

Edito: por cierto, parece que te estuvieras enfadando por que intentemos ayudarte :confused:

NOOOOOOO Casimiro al contrario !!! :eek: fue solo mala interpretación y en verdad agradezco tu tiempo y el del resto para darme una mano para solucionar el tema.
Segui el tutorial al pie de la letra y en una sola maquina funciona correctamente todo pero solamente en la manquina que realizo los cambios en la otra no veo nada distinto hasta que no cierro y vuelvo abrir el sistema. Al parecer porque se conecta y desconecta la base y se actualiza la info.

MartinS
02-05-2012, 16:19:21
Uso un dbNavigator para manipular la grilla, uso el append del navigator para crear un nuevo registro y edito los datos directamente de la grilla, luego guardo los cambios tb con el navigator.

Bueno. Creo que nunca use el DbNavigator para dar de alta un registro (aunque creo que solo lo estas usando para probar) y por lo tanto no se bien como captar que boton apreta el cliente. Lo que si puedes hacer y como para probar es en el evento que indicas "afterpost" poner así:

localidades.ApplyUpdates;
TuTransaccion.commitRetaining;
localidades.Refresh;


y en cuanto a componentes yo no uso IbTable, lo hago a traves de IbDataset pero creo que no esta mal como lo implementas.-

PD: Son las transacciones :p:D:D

Casimiro Notevi
02-05-2012, 16:23:24
PD: Son las transacciones :p:D:D

Son las transacciones, amigo pelikno :)

pelikno
02-05-2012, 16:31:58
Bueno. Creo que nunca use el DbNavigator para dar de alta un registro (aunque creo que solo lo estas usando para probar) y por lo tanto no se bien como captar que boton apreta el cliente. Lo que si puedes hacer y como para probar es en el evento que indicas "afterpost" poner así:

localidades.ApplyUpdates;
TuTransaccion.commitRetaining;
localidades.Refresh;


y en cuanto a componentes yo no uso IbTable, lo hago a traves de IbDataset pero creo que no esta mal como lo implementas.-

PD: Son las transacciones :p:D:D
Lo del navigator es para prueba :p, probe con lo que me dijiste y sigue igual, tengo que cerrar la aplicacion en el cliente para poder refrescar los cambios que hizo el servidor y viceversa :mad:.

MartinS
02-05-2012, 16:53:38
Imagino que estas haciendo referencia a traves del datasource al IbTable. Por eso yo uso IbDataset donde la consulta sale a partir de una sentencia SQL que se actualiza cada vez que se abre el formulario, por decirlo de alguna forma.

Por ejemplo

IbQuery1.close;
IbQuery1.Sql.Clear;
IbQuery1.Sql.Add(Select Apellido,Nombres,DNI,Direccion From Clientes);
ibQuery1.Sql.Open;

y para actualizar con un simple

IbQuery1.close;
IbQuery1.Open;

me funciona

pelikno
02-05-2012, 17:01:53
Imagino que estas haciendo referencia a traves del datasource al IbTable. Por eso yo uso IbDataset donde la consulta sale a partir de una sentencia SQL que se actualiza cada vez que se abre el formulario, por decirlo de alguna forma.

Por ejemplo

IbQuery1.close;
IbQuery1.Sql.Clear;
IbQuery1.Sql.Add(Select Apellido,Nombres,DNI,Direccion From Clientes);
ibQuery1.Sql.Open;

y para actualizar con un simple

IbQuery1.close;
IbQuery1.Open;

me funciona
si si tengo en la grilla,datasource y ibtable. Claro te funciona porque se realiza la consulta otra vez a la base con los datso actualizados, pero no entiendo porque con el ibtable no lo hace, le hice un trasaction.commit; y me cierra todas las tablas, como que rompe todo.

MartinS
02-05-2012, 17:07:05
si si tengo en la grilla,datasource y ibtable. Claro te funciona porque se realiza la consulta otra vez a la base con los datso actualizados, pero no entiendo porque con el ibtable no lo hace, le hice un trasaction.commit; y me cierra todas las tablas, como que rompe todo.

El commit solo cierra los dataset usa commitretaining. Igual debe quedar colgado algún procedimiento para hacer. A partir de aquí desconozco porque no hago nunca referencia al ibtable directo para mostrar datos, siempre uso Query's.

pelikno
02-05-2012, 17:09:40
El commit solo cierra los dataset usa commitretaining. Igual debe quedar colgado algún procedimiento para hacer. A partir de aquí desconozco porque no hago nunca referencia al ibtable directo para mostrar datos, siempre uso Query's.
Porque usas querys?

pelikno
02-05-2012, 17:15:59
El problema es que no se actualizan las tablas y no se porque !! :mad:

MartinS
02-05-2012, 17:22:14
Porque usas querys?

Simplemente porque no es recomendable ni necesario en cualquier sistema que se muestren todos los registros. Es decir, cuando un usuario busca algo en particular sabe lo que necesita ver y nosotros debemos darle mas o menos la estructura de busqueda para que no se nos dispare la memoria del programa. Imaginate si la tabla tiene un millon de registros por ejemplo. Entonces solo limito lo que quiero mostrar.
Por otro lado las consultas se ejecutan en el servidor y enviar todos (y digo todos) los datos por red puede ser demasiado engorroso y saturar todo facilmente. Por ello mis consultas son del tipo

IbQuery1.close;
IbQuery1.Sql.Clear;
IbQuery1.Sql.Add(Select Apellido,Nombres,DNI,Direccion From Clientes);
IbQuery1.Sql.Add(Where apellido = 'Perez')
ibQuery1.Sql.Open;

Donde solo traera los Perez
y si quiero editar un registro, primero lo busco y solo traigo el que me interesa

Mas o menos es así :o

En cuanto a las tablas si cerras y volves a abrir los cambios estan tiene que ser tema de refresco pero ahi como ya te dije mucho no se.:confused:

Casimiro Notevi
02-05-2012, 17:26:52
El problema es que no se actualizan las tablas y no se porque !! :mad:

Veamos:
Terminal 1: abres la ficha de artículos, buscas el artículo 'A001' y lo tienes en pantalla.
Terminal 2: abres la ficha de artículos, buscas el artículo 'A001' y lo tienes en pantalla.

En el terminal 1 modificas el precio del artículo. Haces 'post' y 'commitretaining'.
En el terminal 2 sigues viendo la pantalla con el precio anterior, si vuelves a buscar el mismo artículo entonces te aparecerá con el nuevo precio.
¿Es eso?

pelikno
02-05-2012, 17:30:09
Simplemente porque no es recomendable ni necesario en cualquier sistema que se muestren todos los registros. Es decir, cuando un usuario busca algo en particular sabe lo que necesita ver y nosotros debemos darle mas o menos la estructura de busqueda para que no se nos dispare la memoria del programa. Imaginate si la tabla tiene un millon de registros por ejemplo. Entonces solo limito lo que quiero mostrar.
Por otro lado las consultas se ejecutan en el servidor y enviar todos (y digo todos) los datos por red puede ser demasiado engorroso y saturar todo facilmente. Por ello mis consultas son del tipo

IbQuery1.close;
IbQuery1.Sql.Clear;
IbQuery1.Sql.Add(Select Apellido,Nombres,DNI,Direccion From Clientes);
IbQuery1.Sql.Add(Where apellido = 'Perez')
ibQuery1.Sql.Open;

Donde solo traera los Perez
y si quiero editar un registro, primero lo busco y solo traigo el que me interesa

Mas o menos es así :o

En cuanto a las tablas si cerras y volves a abrir los cambios estan tiene que ser tema de refresco pero ahi como ya te dije mucho no se.:confused:
Entiendo lo que pasa que ente caso la tabla de localidades para dar de alta un inmueble por lo tanto tiene que estar todas porque no se sabe a priori cual es la correcta.
Me podrías decir de las opciones del transaction cual seria la correcta en este caso para cuando realizo un cambio que no espere para hacer commit y se realice al instante ?:o

pelikno
02-05-2012, 17:46:41
Veamos:
Terminal 1: abres la ficha de artículos, buscas el artículo 'A001' y lo tienes en pantalla.
Terminal 2: abres la ficha de artículos, buscas el artículo 'A001' y lo tienes en pantalla.

En el terminal 1 modificas el precio del artículo. Haces 'post' y 'commitretaining'.
En el terminal 2 sigues viendo la pantalla con el precio anterior, si vuelves a buscar el mismo artículo entonces te aparecerá con el nuevo precio.
¿Es eso?
Todo correcto excepto que para ver el nuevo precio en la terminal 2 tengo que cerrar mi aplicacion y volver a ejecutar y ahi si me muestra actualizada la base, como que se tiene que desconectar para poder actualizar la tabla no se porque :confused:

pelikno
02-05-2012, 18:04:17
ademas la base si se actualiza porque por ejemplo
-terminal 1 agrego la localida con codigo 2 la grilla muestra
cod nombre
1 loc1
2 loc2


-la terminal 2 muestra o sea no se actualizo
cod nombre
1 loc1

-la terminal 2 intento agregar localidad con codigo 2 me tira error de primarykey o sea que si se agrego en la base pero la tabla no lo refleja :confused:

pelikno
02-05-2012, 18:21:57
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin

CustomerData.IBTransaction1.CommitRetaining;
CustomerData.ibdatabase.ApplyUpdates([localidades]);
localidades.ApplyUpdates;
localidades.Active:=false;
localidades.Active:=true;
localidades.Refresh;


end;

Estado de mi transaction
active = true
defaultaction =tacommit
defauldatabase = ibdatabase
Idletimer = 0
name =ibtransaction
params = read_committed
rec_version
nowait
tag = 0

estado de mi base de datos
connected= true
databasename = 192.168.1.226:C:\Documents and Settings\virtualbox\Escritorio\misistema\mibase.FDB
defaultransaction = IBTransaction
Idletimer = 0
loginpromt = false
name = ibdatabase
params = user_name=SYSDBA
password=masterkey
sql_role_name=3
lc_ctype=ISO8859_1
sqldialect = 3
tag = 0
traceflags = todas en false

----------------------------------
las ibtables tiene como database =CustomerData.ibdatabase y no se de alguna propiedad que tenga que modificar para que se actualice como tiene la componenete tquery la propiedad requestlive.

MartinS
02-05-2012, 18:29:57
A ver vamos por parte dijo JACK :D:D

Yo para los datos uso un TDataModule y este el procedimiento cuando se crea (pone en uses IniFiles)


procedure TDm.DataModuleCreate(Sender: TObject);
Var BaseDeDatos: String;
IniFile: TIniFile;
begin
// Obtiene la ruta y el nombre de la base de datos
IniFile := TIniFile.Create(ExtractFilePath(Application.ExeName)+'BDatos.ini');
BasedeDatos := IniFile.ReadString('BD','Path','');
If BasedeDatos = '' then
ShowMessage('Error al cargar Base de Datos') else
BaseGeneral.DatabaseName := BaseDeDatos;
end;

Lo que hace es leer un archivo .ini que se encuentra en el mismo directorio del ejecutable tomando la ruta de la base de datos

Dentro del .ini (BDatos.ini) tiene solo esto (Cliente/servidor):

[BD]
Path=":C:\Desarrollos\RegistroGeneral\MASTERBASE.FDB"

y en la maquina cliente por decirlo de alguna manera tengo en un directorio la copia del ejecutable pero el ini de esa maquina dice esto:

[BD]
Path="10.151.129.138:C:\Desarrollos\RegistroGeneral\MASTERBASE.FDB"

donde esa IP es donde esta la Base de datos.

Resumiendo tengo dos ejecutables, uno en el cliente/servidor y otro en el cliente pero con diferente Ini. No se si me explico.-
Proba algo similar

pelikno
02-05-2012, 18:36:32
A ver vamos por parte dijo JACK :D:D

Yo para los datos uso un TDataModule y este el procedimiento cuando se crea (pone en uses IniFiles)


procedure TDm.DataModuleCreate(Sender: TObject);
Var BaseDeDatos: String;
IniFile: TIniFile;
begin
// Obtiene la ruta y el nombre de la base de datos
IniFile := TIniFile.Create(ExtractFilePath(Application.ExeName)+'BDatos.ini');
BasedeDatos := IniFile.ReadString('BD','Path','');
If BasedeDatos = '' then
ShowMessage('Error al cargar Base de Datos') else
BaseGeneral.DatabaseName := BaseDeDatos;
end;

Lo que hace es leer un archivo .ini que se encuentra en el mismo directorio del ejecutable tomando la ruta de la base de datos

Dentro del .ini (BDatos.ini) tiene solo esto (Cliente/servidor):

[BD]
Path=":C:\Desarrollos\RegistroGeneral\MASTERBASE.FDB"

y en la maquina cliente por decirlo de alguna manera tengo en un directorio la copia del ejecutable pero el ini de esa maquina dice esto:

[BD]
Path="10.151.129.138:C:\Desarrollos\RegistroGeneral\MASTERBASE.FDB"

donde esa IP es donde esta la Base de datos.

Resumiendo tengo dos ejecutables, uno en el cliente/servidor y otro en el cliente pero con diferente Ini. No se si me explico.-
Proba algo similar
Si probe copiar el ejecutable en el escritorio de la terminal y le coloque a la base de datos la ip del servidor, si no me equivoco es lo mismo que hiciste vos nada mas que no tomo la ip de un archivo. y no me actualiza cuando agrego algo me tira error de primary key

MartinS
02-05-2012, 18:36:51
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin

CustomerData.IBTransaction1.CommitRetaining;
CustomerData.ibdatabase.ApplyUpdates([localidades]);
localidades.ApplyUpdates;
localidades.Active:=false;
localidades.Active:=true;
localidades.Refresh;


end;



El commitRetaining va despues del applyupdates.

MartinS
02-05-2012, 18:38:40
Si probe copiar el ejecutable en el escritorio de la terminal y le coloque a la base de datos la ip del servidor, si no me equivoco es lo mismo que hiciste vos nada mas que no tomo la ip de un archivo. y no me actualiza cuando agrego algo me tira error de primary key

¿Y como hiciste eso? Por codigo?.. no entiendo?

pelikno
02-05-2012, 18:46:59
¿Y como hiciste eso? Por codigo?.. no entiendo?
en la configuracion de la base le puse directamente la ip del servidor de mi aplicacion o sea 192.168.1.226, cuando se ejecuta en el servidor mi aplicacion es como la ip loopback porque se direcciona la base a la misma maquina, pero cuando se hace desde el cliente , la base apunta a la ip 192.168.226 cuando la localhost es 192.168.1.224 me explico ?
La ip de la base se la seteo directamente con 192.168.1.226:C:\Documents and Settings\virtualbox\Escritorio\misistema\mibase.FDB

pelikno
02-05-2012, 18:58:54
El commitRetaining va despues del applyupdates.

No actualiza :mad: con ese cambio

Casimiro Notevi
02-05-2012, 19:20:25
Si usas los componentes IBX, yo nunca usé eso de "applyupdates" :confused:

En el evento afterpost del dataset debes hacer el commit, algo así:

procedure TDMmain.QRcentrosCosteAfterPost(DataSet: TDataSet);
begin
DataSet.Transaction.CommitRetaining;
end;

pelikno
02-05-2012, 19:44:34
Si usas los componentes IBX, yo nunca usé eso de "applyupdates" :confused:

En el evento afterpost del dataset debes hacer el commit, algo así:

procedure TDMmain.QRcentrosCosteAfterPost(DataSet: TDataSet);
begin
DataSet.Transaction.CommitRetaining;
end;

CustomerData es mi datamodule
y esto es lo que esta en el evento afterpost de mi ibtable

CustomerData.ibtransaction.ApplyUpdates;
Localidades.refresh;


sigue haciendo lo mismo, es como si desde la base de datos no les mande el aviso que se modificaron los datos y se vuelva a mostrar en la grilla, doy de alta una localidad con codigo 4 en una terminal y en la otra no la veo hasta que no cierro la aplicacion y la vuelvo abrir

pelikno
02-05-2012, 19:45:15
Sera problema de delphi 5 y las componentes interbase ?
Voy a ver si puedo compilar con delphi 10 a ver que pasa porque es algo muy simple lo que quiero hacer y no se que pasa que no anda y me estoy volviendo loco.

Casimiro Notevi
02-05-2012, 19:54:53
Sera problema de delphi 5 y las componentes interbase ?

No, no es problema de delphi ni de los componentes, es problema de las confirmaciones de transacciones, ya te lo hemos repetido constantemente un montón de veces :confused:

¿Pero has probado lo que te hemos comentado?
:confused::confused::confused:

pelikno
02-05-2012, 22:28:33
No, no es problema de delphi ni de los componentes, es problema de las confirmaciones de transacciones, ya te lo hemos repetido constantemente un montón de veces :confused:

¿Pero has probado lo que te hemos comentado?
:confused::confused::confused:

si si probe todo, fijate en los post anteriores que puse el codigo exactamente como lo tengo en el delphi ademas de la configuracion de las componentes.

Casimiro Notevi
02-05-2012, 22:32:21
si si probe todo,

¿Y qué resultados has obtenido?, ¿bien?, ¿algún mensaje?, ¿cómo has hecho la prueba?, ¿con qué código?...

pelikno
02-05-2012, 23:20:57
¿Y qué resultados has obtenido?, ¿bien?, ¿algún mensaje?, ¿cómo has hecho la prueba?, ¿con qué código?...

ningun resultado :( hace lo mismo, o me actualiza, ahora estoy tratanto de compilar con delphi 2010 a ver si cambia pero no me conecta a la base remota estoy fijandome porque

egostar
02-05-2012, 23:38:46
ningun resultado :( hace lo mismo, o me actualiza, ahora estoy tratanto de compilar con delphi 2010 a ver si cambia pero no me conecta a la base remota estoy fijandome porque

Y estas usando la base de datos correcta ¿? A alguien que conozco (el primo del amigo de la prima del amigo de mi prima) le pasó eso, estuvo dos días buscando el error y la conexión la tenia a la base de pruebas y no la de producción :mad:

Saludos

Casimiro Notevi
02-05-2012, 23:41:17
Desde hace 14 años uso IBX con delphi 5, una gestión de cientos de clientes con centenares de terminales conectados a un servidor firebird.
No necesitas probar con otro delphi ni con otros componentes. El resultado va a ser el mismo.

pelikno
03-05-2012, 01:21:28
Y estas usando la base de datos correcta ¿? A alguien que conozco (el primo del amigo de la prima del amigo de mi prima) le pasó eso, estuvo dos días buscando el error y la conexión la tenia a la base de pruebas y no la de producción :mad:

Saludos

si si la base es la correcta, ya que en la terminal 1 agrego un registro en la tabla y para verlo en la terminal 2 tengo que apretar el boton refresh del dbnavigator

pelikno
03-05-2012, 01:22:59
Desde hace 14 años uso IBX con delphi 5, una gestión de cientos de clientes con centenares de terminales conectados a un servidor firebird.
No necesitas probar con otro delphi ni con otros componentes. El resultado va a ser el mismo.
Si eso es verdad pero no se como hacer ya, es como que si no apreto el boton refresh del navigator los datos de la grilla en las terminales no se actualiza, solo lo ve el que hizo el cambio.
Como ejecutas tu aplicacion en los clientes con el ejecutable o con acceso directo al ejecutable comartido en el servidor?

Casimiro Notevi
03-05-2012, 01:36:11
A ver, a ver...
Terminal 1: tienes un dbgrid asociado a un dataset y ese dataset es un ibtable.
Terminal 2: en ese mismo dbgrid->dataset (ibtable), añades un nuevo registro... en el otro (terminal 1) debes refrescar el dbgrid (o sea, el ibtable) para que se vea el nuevo registro.

Si estás haciendo eso, entonces... es que eso es normal, eso es así.

Ahora bien, si sales de esa pantalla en el terminal 1 y vuelves a entrar, entonces verás el nuevo registro que se ha añadido en el terminal 2. ¿Es así?

MartinS
03-05-2012, 02:02:52
Si eso es verdad pero no se como hacer ya, es como que si no apreto el boton refresh del navigator los datos de la grilla en las terminales no se actualiza, solo lo ve el que hizo el cambio.
Como ejecutas tu aplicacion en los clientes con el ejecutable o con acceso directo al ejecutable comartido en el servidor?

Hola nuevamente. Hice una siesta y el tema sigue!! :p

Yo te propongo que pongas un par de DbEdit, un DbGrid, y unos Tbotton que graben, eliminen y demas para ver que hacen (Todo por codigo).

Si tenes algun problema con como hacer esto en un rato vuelvo. Me voy a inspirar por ahi :rolleyes:

Saludos

pelikno
03-05-2012, 02:19:49
Hola nuevamente. Hice una siesta y el tema sigue!! :p

Yo te propongo que pongas un par de DbEdit, un DbGrid, y unos Tbotton que graben, eliminen y demas para ver que hacen (Todo por codigo).

Si tenes algun problema con como hacer esto en un rato vuelvo. Me voy a inspirar por ahi :rolleyes:

Saludos

jajaj gracias idolo, ahora lo pruebo ya que hace mas de 6 horas que estoy con esto !!!!! :(

pelikno
03-05-2012, 02:43:22
procedure TForm1.ButtonappendClick(Sender: TObject);
begin
localidades.Append;
end;

procedure TForm1.ButtonpostClick(Sender: TObject);
begin
localidades.Post;
end;


procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining;
localidades.Refresh;
end;

end;

Puse dos botones para las altas y saque el dbnavigator, ahora cuando hago un alta en una terminal, en la grilla de la otra no se actualiza. tengo configurada la base y transaction de la misma forma que el tutorial pero en vez de poner localhost puse la ip 192.168.1.103:c:\misistema\mibase.fdb que es donde se encuantra el sistema con la base, tengo instalado en el servidor firebird 2.5 claasicserver igual que en la terminal para que no le falte ningun dll ni nada. Alguna idea ?

Delphius
03-05-2012, 03:19:07
Yo tengo algunas ideas pero creo que no te van a gustar:
1) Vuelve al principio del hilo y lee lo que pusiste y lo que te han venido diciendo los compañeros con calma, tranquilidad.
2) Repítase el paso 1) hasta que los nervios hayan desaparecido
3) Inspire y exhale profundamente 10 veces. Resople, deja que todo el aire salga de tus pulmones.
4) Cierra los ojos, despeja tu cabeza... no pienses en código... ni en base de datos... no pienses en nada.
5) Abre los ojos, vuelve a leer de nuevo el hilo desde el comienzo.
6) Lance una buena puteada al que le dió estas intrucciones.
7) Una vez ya que se haya descargado vuelva a leer y a seguir en serio las recomendaciones de los compañeros.
8) Vuelva al paso 7) hasta que se haya cansado
9) Una vez que se haya enojado de nuevo. Vuelvase a las recomendaciones del los compañeros. Agarre la biblia de las transacciones que le han recomendado. Apréndasela como el padre nuestro.
10) Aprenda de una vez que el sistema no es un adivino. ¿Como carajos se supone que por arte de magia aparezca lo cambiado en una aplicación en otra? SIEMPRE, PERO SIEMPRE se lleva a cabo un REFRESCO de datos. Los datos no aparecerán por arte de magia. "Algo" le debe indicar a la aplicación que los datos han cambiado; o bien debe implementarse que cada x tiempo se refresquen los datos.
10) Aprende sobre los eventos de firebird. Están diseñados para esto. El servidor notifica a TODOS los clientes con un evento. Luego los clientes capturan este evento y es responsabilidad de éstos en hacer luego lo que necesiten. Para el caso REFRESCAR. En la documentación oficial de Firebird hay un paper que es casi una obligación leerse. Como vez, OBVIAMENTE sea cual fuese la forma... magia no hay.

¿Quieres que aparezcan los datos? ¡Debes refrescar! Ya sea que cierres las forma y vuelvas a abrir, vuelvas a cerrar y abrir el data set... o vuelvas a ejecutar la consulta para traer los datos... Lo que haces en A se queda en A. Si B to Z necesitan saber lo que hizo A le deben "preguntar" al server.... Después de todo, es el quien en verdad sabe que cosas se han hecho.
Me parece a mi que no tienes ni idea de como es que funciona la arquitectura cliente/servidor.

Dependiendo del nivel de aislamiento de las transacciones podrás ver más o menos registros. Cuando haces un CommitRetaing mantienes la transacción abierta PARA ESE CLIENTE, PARA ESE DATASET. Más eso no quiere decir que los demás inmediatamente van a saberlo. ENTIENDELO DE UNA VEZ.

11) ¿Que carajos haces mezclando ApplyUpdate con un trabajo que no tiene nada que ver? ApplyUpdates solo sirve cuando se trata de un trabajo a nivel caché. Es decir, todo se hace en forma localmente de manera temporal y luego se vuelca todo en la base de datos, es casi parecido a como trabajar con TClientDataSet.
Si no tienes en la propiedad CacheUpdates en true estas haciendo algo que no tendrá efecto en nada porque naturalmente, no hay que actualizar.

12) Ya no le sigas más... mejor ve a otra cosa. Duerme. En cuanto tengas la cabeza en blanco recién vuelve.

13) No nos interesa el tiempo que te demores, aqui no hay urgencias asi que da lo mismo que te demores 50 días que te lleve 4 horas. La desesperación a la taberna, y te tomas una cerveza para pasar el mal sabor. No apures lo que no se puede apurar. Tu estas bloqueado y seguirás así si no te resignas a aceptar que por hoy ya no más.

14) Aprende a reconocer tus batallas, hasta cuando puedes y cuando no.
15) Putea de nuevo. Dale, ¡que te encanta!
16) Vuelve al inicio del hilo... ¿Ya leíste toda la documentación que te recomendaron o vas a seguir en la negación?

Saludos,
PD: 16 ideas de como no agradar a nadie. 16 maneras de como despertar a alguien... Depende de como lo desee mirar uno. :D

pelikno
03-05-2012, 04:22:57
Yo tengo algunas ideas pero creo que no te van a gustar:
1) Vuelve al principio del hilo y lee lo que pusiste y lo que te han venido diciendo los compañeros con calma, tranquilidad.
2) Repítase el paso 1) hasta que los nervios hayan desaparecido
3) Inspire y exhale profundamente 10 veces. Resople, deja que todo el aire salga de tus pulmones.
4) Cierra los ojos, despeja tu cabeza... no pienses en código... ni en base de datos... no pienses en nada.
5) Abre los ojos, vuelve a leer de nuevo el hilo desde el comienzo.
6) Lance una buena puteada al que le dió estas intrucciones.
7) Una vez ya que se haya descargado vuelva a leer y a seguir en serio las recomendaciones de los compañeros.
8) Vuelva al paso 7) hasta que se haya cansado
9) Una vez que se haya enojado de nuevo. Vuelvase a las recomendaciones del los compañeros. Agarre la biblia de las transacciones que le han recomendado. Apréndasela como el padre nuestro.
10) Aprenda de una vez que el sistema no es un adivino. ¿Como carajos se supone que por arte de magia aparezca lo cambiado en una aplicación en otra? SIEMPRE, PERO SIEMPRE se lleva a cabo un REFRESCO de datos. Los datos no aparecerán por arte de magia. "Algo" le debe indicar a la aplicación que los datos han cambiado; o bien debe implementarse que cada x tiempo se refresquen los datos.
10) Aprende sobre los eventos de firebird. Están diseñados para esto. El servidor notifica a TODOS los clientes con un evento. Luego los clientes capturan este evento y es responsabilidad de éstos en hacer luego lo que necesiten. Para el caso REFRESCAR. En la documentación oficial de Firebird hay un paper que es casi una obligación leerse. Como vez, OBVIAMENTE sea cual fuese la forma... magia no hay.

¿Quieres que aparezcan los datos? ¡Debes refrescar! Ya sea que cierres las forma y vuelvas a abrir, vuelvas a cerrar y abrir el data set... o vuelvas a ejecutar la consulta para traer los datos... Lo que haces en A se queda en A. Si B to Z necesitan saber lo que hizo A le deben "preguntar" al server.... Después de todo, es el quien en verdad sabe que cosas se han hecho.
Me parece a mi que no tienes ni idea de como es que funciona la arquitectura cliente/servidor.

Dependiendo del nivel de aislamiento de las transacciones podrás ver más o menos registros. Cuando haces un CommitRetaing mantienes la transacción abierta PARA ESE CLIENTE, PARA ESE DATASET. Más eso no quiere decir que los demás inmediatamente van a saberlo. ENTIENDELO DE UNA VEZ.

11) ¿Que carajos haces mezclando ApplyUpdate con un trabajo que no tiene nada que ver? ApplyUpdates solo sirve cuando se trata de un trabajo a nivel caché. Es decir, todo se hace en forma localmente de manera temporal y luego se vuelca todo en la base de datos, es casi parecido a como trabajar con TClientDataSet.
Si no tienes en la propiedad CacheUpdates en true estas haciendo algo que no tendrá efecto en nada porque naturalmente, no hay que actualizar.

12) Ya no le sigas más... mejor ve a otra cosa. Duerme. En cuanto tengas la cabeza en blanco recién vuelve.

13) No nos interesa el tiempo que te demores, aqui no hay urgencias asi que da lo mismo que te demores 50 días que te lleve 4 horas. La desesperación a la taberna, y te tomas una cerveza para pasar el mal sabor. No apures lo que no se puede apurar. Tu estas bloqueado y seguirás así si no te resignas a aceptar que por hoy ya no más.

14) Aprende a reconocer tus batallas, hasta cuando puedes y cuando no.
15) Putea de nuevo. Dale, ¡que te encanta!
16) Vuelve al inicio del hilo... ¿Ya leíste toda la documentación que te recomendaron o vas a seguir en la negación?

Saludos,
PD: 16 ideas de como no agradar a nadie. 16 maneras de como despertar a alguien... Depende de como lo desee mirar uno. :D

las cosas que probe fueron las que pusieron con la mejor voluntad casimiro y martins que lamentablemente no tuve solucion, por eso puse en este hilo toda la info para que me ayuden a saber cual es el problema, se como funciona un cliente servidor , por eso como estoy migrando esta aplicacion que con sqlserver funcionaba correctamente,configurando los odbc de windows y utilizando los drivers del mismo. Por eso quiero ahora hacer lo mismo pero con firebird , estoy usando interbase para conectar y ejecuto el sistema desde las terminales directamente desde el ejecutable, tengo claro que el problema es con la base y los commits o algo que no le informa a los clientes de los cambios en la base , por ese motivo es que abri este hilo para saber si el diseño y las componentes utilizadas eran las correctas.
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
//CustomerData.IBTransaction1.CommitRetaining;
//localidades.Transaction.CommitRetaining;
localidades.Close;
localidades.Open;
localidades.Refresh;
end;
esto lo unico que hace es actualizar los datos pero de la terminal la cual se modifico. Puede ser por instalar mal firebird en los clientes ?

pelikno
03-05-2012, 04:38:15
http://www.delphiaccess.com/forum/delphi/como-comprobar-si-hay-cambios-en-los-registros-de-una-base-de-datos/
En ese hilo tratan un poco del tema y al parecer es como decia todo lo que realizan las terminales no se informa a los clientes a no ser que sea por algun evento para informarles del cambio. Uds que tienen aplicaciones conectadas con firebird cliente/servidor como hacen para informar de cambios en la base ??

Casimiro Notevi
03-05-2012, 09:16:59
Creo que no has leido todo lo que hemos contestado :confused:

MartinS
03-05-2012, 12:26:48
http://www.delphiaccess.com/forum/delphi/como-comprobar-si-hay-cambios-en-los-registros-de-una-base-de-datos/
En ese hilo tratan un poco del tema y al parecer es como decia todo lo que realizan las terminales no se informa a los clientes a no ser que sea por algun evento para informarles del cambio. Uds que tienen aplicaciones conectadas con firebird cliente/servidor como hacen para informar de cambios en la base ??

Entonces el tema estaba resuelto desde el principio? :eek: y lo que necesitabas era como que automáticamente al modificar un registro del servidor y/o cliente se reflejara sin hacer absolutamente nada en el cliente y/o servidor?

pelikno
03-05-2012, 13:10:33
Creo que no has leido todo lo que hemos contestado :confused:
Si por eso pregunto el commitRetaining es el evento que commitea y avisa que se actualien los clientes ? porque sigue sin actualizar, no encuentro la forma.

pelikno
03-05-2012, 13:13:01
Entonces el tema estaba resuelto desde el principio? :eek: y lo que necesitabas era como que automáticamente al modificar un registro del servidor y/o cliente se reflejara sin hacer absolutamente nada en el cliente y/o servidor?
El tema no lo solucione ya que no puedo actualizar mas que a la terminal que realiza los cambios, como hacen uds para hacer un commit en la base he informe a los clientes de los cambios para actualizar porque abrir y cerrar el dataset lo unico que afecta es a la aplicacion local y no al resto de las terminales

pelikno
03-05-2012, 13:42:49
1- instale firebird 2.5 CS en la maquina servidor
2-instale firebird 2.5 solo cliente en una terminal
3- coloque en la maquina servidor una carpeta con el ejecutable y la base de datos
4- comparti esa carpeta en internet
5-en la terminal ejecute el sistema directamente de la carpeta compartida del servidor
6-ejecute mi aplicacion tb en el servidor
7-doy de alta un registro con el servidor el cual no se ve reflejado en la terminal.
8-quiero dar de alta el mismo registro en la terminal ya que no figura pero me tira error de primary key, o sea que si se hizo el commit en la base pero la terminal no se entero.

El punto 8 como lo puedo solucionar ?

Casimiro Notevi
03-05-2012, 14:12:53
Amigo, insisto, no has leido todo lo que hemos escrito :confused:

pelikno
03-05-2012, 14:21:26
A ver, a ver...
Terminal 1: tienes un dbgrid asociado a un dataset y ese dataset es un ibtable.
Terminal 2: en ese mismo dbgrid->dataset (ibtable), añades un nuevo registro... en el otro (terminal 1) debes refrescar el dbgrid (o sea, el ibtable) para que se vea el nuevo registro.

Si estás haciendo eso, entonces... es que eso es normal, eso es así.

Ahora bien, si sales de esa pantalla en el terminal 1 y vuelves a entrar, entonces verás el nuevo registro que se ha añadido en el terminal 2. ¿Es así?

Te referias a eso que no lei?. Si lo vi, pero como hago para solucionarlo ya que no esta bueno, por medio de un trigger en la base o con un timer que refesque las grillas o algo que cuente los registros de las tablas en la base !! :D

Casimiro Notevi
03-05-2012, 14:22:49
No, te hablo del documento sobre las transacciones y también sobre post_event.
Además del funcionamiento cliente/servidor.

pelikno
03-05-2012, 14:36:36
Si usas los componentes IBX, yo nunca usé eso de "applyupdates" :confused:

En el evento afterpost del dataset debes hacer el commit, algo así:

procedure TDMmain.QRcentrosCosteAfterPost(DataSet: TDataSet);
begin
DataSet.Transaction.CommitRetaining;
end;


Esto lo realizo !! procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining; // si dejo DataSet.Transaction.CommitRetaining; no compila
end;

pelikno
03-05-2012, 14:38:50
Sobre las transacciones como tendria que ser la configuracion?, porque anteriormente puse como la tenia configurada a la base y a la transaccion.

parametros de la transaction
read_commited
rec_version
nowait

Casimiro Notevi
03-05-2012, 15:51:54
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining; // si dejo DataSet.Transaction.CommitRetaining; no compila
end;


Tiene que compilar. Mal vamos si no compila eso.

pelikno
03-05-2012, 15:52:53
Para no seguir dando vueltas, hay alguien que use firebirds y aplicacion cliente servidor que pueda actualizar los dataset de las terminales sin tener que hacerlo por codigo con un dataset.refresh;

Casimiro Notevi
03-05-2012, 15:55:05
Amigo, disculpa que te lo diga, pero está claro, no te enteras :confused:

pelikno
03-05-2012, 16:00:45
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining; // si dejo DataSet.Transaction.CommitRetaining; no compila
end;


Tiene que compilar. Mal vamos si no compila eso.

con dataset te referis al parametro enviado al after pos ? porque me tira este error
[ERROR] UMain.pas(94):Undeclared Identifier: 'Transaction'

y supongo que es porque un tdataset comun no tiene una transaction.

pelikno
03-05-2012, 16:30:20
Amigo, disculpa que te lo diga, pero está claro, no te enteras :confused:

Casi ... Perdon pero no entiendo a me entero como dicen uds jaja otros sistemas que tengo funcionando tienen un boton actualizar lo que no me gusta por eso queria hacerlo mas automatico el tema del refresco de los datos pero no puedo :cool:

Casimiro Notevi
03-05-2012, 16:36:46
Creo que es la tercera vez ;)... mira sobre post_event (http://www.clubdelphi.com/foros/search.php?searchid=2637378) <--- click ahí ---
Y este enlace (http://www.janus-software.com/fbmanual/manual.php?book=psql&topic=102) también lo puse antes.

MartinS
03-05-2012, 16:38:28
Hola nuevamente:

esto:

procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining; // si dejo DataSet.Transaction.CommitRetaining; no compila
end;

estaria mal a mi entender si localidades es un IbTable ya que el commit se hace sobre el componente IbTransaction

Te voy a poner una unidad completa de un ejemplito bien sencillo sobre el alta de un cliente

unit UAlta;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Mask, DBCtrls;

type
TPalta = class(TForm)
BGrabar: TButton;
BSalir: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
DBEdit1: TDBEdit;
DBEdit2: TDBEdit;
DBEdit3: TDBEdit;
DBEdit4: TDBEdit;
StatusBar1: TStatusBar;
DBEdit5: TDBEdit;
BNuevo: TButton;
procedure FormShow(Sender: TObject);
procedure BSalirClick(Sender: TObject);
procedure BGrabarClick(Sender: TObject);
procedure BNuevoClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Palta: TPalta;

implementation

uses UDm;

{$R *.dfm}

procedure TPalta.BSalirClick(Sender: TObject);
begin
Dm.Clientes.Cancel;
Dm.Transaccion.RollbackRetaining;
end;

procedure TPalta.BGrabarClick(Sender: TObject);
begin
Try
Dm.ClientesID.AsInteger := 0;
Dm.Clientes.Post;
Dm.Transaccion.CommitRetaining;
Dm.Clientes.Append;
DBEdit1.SetFocus;
Except
Dm.Clientes.Cancel;
Dm.Transaccion.RollbackRetaining;
ShowMessage('Error de escritura');
End;
end;

procedure TPalta.BNuevoClick(Sender: TObject);
begin
Dm.Clientes.Append;
end;

procedure TPalta.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Dm.Transaccion.InTransaction then
Dm.Transaccion.RollbackRetaining;
end;

procedure TPalta.FormShow(Sender: TObject);
begin
DBEdit1.SetFocus;
end;

end.

Resumiendo:
Dm es un TDataModule
Clientes es un IbTable
Transaccion es un IbTransaction

Para que puedas actualizar en tiempo real por decirlo de alguna manera a todos los clientes vas a tener que crear un trigger que genere un evento, algo asi:

CREATE TRIGGER POST_NEW_REG FOR CLIENTES
ACTIVE AFTER INSERT
POSITION 0
AS
BEGIN

POST_EVENT 'new_reg';
END

que se disparara cada vez que se ingrese uno en este caso y capturar ese evento con el componente IBEvent para que realice la correspondiente actualizacion de la grilla.

En la unidad del TDataModule (Dm) puse esto:

unit UDm;

interface

uses
SysUtils, Classes,IniFiles,Forms,Dialogs, DB, IBDatabase, IBCustomDataSet,
IBTable, IBEvents;

type
TDM = class(TDataModule)
Transaccion: TIBTransaction;
BaseGeneral: TIBDatabase;
Clientes: TIBTable;
ClientesID: TIntegerField;
ClientesAPELLIDOS: TIBStringField;
ClientesNOMBRES: TIBStringField;
ClientesFNAC: TDateField;
ClientesDOMICILIO: TIBStringField;
ClientesLOCALIDAD: TIBStringField;
SClientes: TDataSource;
IBEvents1: TIBEvents;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure IBEvents1EventAlert(Sender: TObject; EventName: string;
EventCount: Integer; var CancelAlerts: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
DM: TDM;

implementation

{$R *.dfm}

procedure TDM.DataModuleCreate(Sender: TObject);
Var BaseDeDatos: String;
IniFile: TIniFile;
begin
// Obtiene la ruta y el nombre de la base de datos
IniFile := TIniFile.Create(ExtractFilePath(Application.ExeName)+'BDatos.ini');
BasedeDatos := IniFile.ReadString('BD','Path','');
If BasedeDatos = '' then
ShowMessage('Error al cargar Base de Datos') else
Begin
Try
BaseGeneral.DatabaseName := BaseDeDatos;
BaseGeneral.Connected := True;
Transaccion.Active := True;
Clientes.Open;
// IBEvents1.Events.Clear;
// IBEvents1.Events.Add('new_reg');
// IBEvents1.RegisterEvents;
Except
ShowMessage('No se puede conectar el servidor...');
End;
End;
end;

procedure TDM.DataModuleDestroy(Sender: TObject);
begin
Transaccion.Active := False;
BaseGeneral.Connected := False;
Clientes.Close;
// IBEvents1.UnRegisterEvents;
end;

procedure TDM.IBEvents1EventAlert(Sender: TObject; EventName: string;
EventCount: Integer; var CancelAlerts: Boolean);
begin
{ if EventName = 'new_reg' then
Begin
ShowMessage('Edito');
SClientes.DataSet.Refresh;
End; }
end;

end.

Comentado esta el codigo para el IbEvent


Saludos.- y espero que vayamos orientando hacia alguna parte

Delphius
03-05-2012, 16:46:47
17) Vuelva a leer este hilo de atrás para adelante... quizá si lo hacemos "al verré" se entiende la cosa :D :p

Saludos,

pelikno
03-05-2012, 17:08:36
Hola nuevamente:

esto:

procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
localidades.Transaction.CommitRetaining; // si dejo DataSet.Transaction.CommitRetaining; no compila
end;

estaria mal a mi entender si localidades es un IbTable ya que el commit se hace sobre el componente IbTransaction

Te voy a poner una unidad completa de un ejemplito bien sencillo sobre el alta de un cliente

unit UAlta;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Mask, DBCtrls;

type
TPalta = class(TForm)
BGrabar: TButton;
BSalir: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
DBEdit1: TDBEdit;
DBEdit2: TDBEdit;
DBEdit3: TDBEdit;
DBEdit4: TDBEdit;
StatusBar1: TStatusBar;
DBEdit5: TDBEdit;
BNuevo: TButton;
procedure FormShow(Sender: TObject);
procedure BSalirClick(Sender: TObject);
procedure BGrabarClick(Sender: TObject);
procedure BNuevoClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Palta: TPalta;

implementation

uses UDm;

{$R *.dfm}

procedure TPalta.BSalirClick(Sender: TObject);
begin
Dm.Clientes.Cancel;
Dm.Transaccion.RollbackRetaining;
end;

procedure TPalta.BGrabarClick(Sender: TObject);
begin
Try
Dm.ClientesID.AsInteger := 0;
Dm.Clientes.Post;
Dm.Transaccion.CommitRetaining;
Dm.Clientes.Append;
DBEdit1.SetFocus;
Except
Dm.Clientes.Cancel;
Dm.Transaccion.RollbackRetaining;
ShowMessage('Error de escritura');
End;
end;

procedure TPalta.BNuevoClick(Sender: TObject);
begin
Dm.Clientes.Append;
end;

procedure TPalta.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Dm.Transaccion.InTransaction then
Dm.Transaccion.RollbackRetaining;
end;

procedure TPalta.FormShow(Sender: TObject);
begin
DBEdit1.SetFocus;
end;

end.

Resumiendo:
Dm es un TDataModule
Clientes es un IbTable
Transaccion es un IbTransaction

Para que puedas actualizar en tiempo real por decirlo de alguna manera a todos los clientes vas a tener que crear un trigger que genere un evento, algo asi:

CREATE TRIGGER POST_NEW_REG FOR CLIENTES
ACTIVE AFTER INSERT
POSITION 0
AS
BEGIN

POST_EVENT 'new_reg';
END

que se disparara cada vez que se ingrese uno en este caso y capturar ese evento con el componente IBEvent para que realice la correspondiente actualizacion de la grilla.

En la unidad del TDataModule (Dm) puse esto:

unit UDm;

interface

uses
SysUtils, Classes,IniFiles,Forms,Dialogs, DB, IBDatabase, IBCustomDataSet,
IBTable, IBEvents;

type
TDM = class(TDataModule)
Transaccion: TIBTransaction;
BaseGeneral: TIBDatabase;
Clientes: TIBTable;
ClientesID: TIntegerField;
ClientesAPELLIDOS: TIBStringField;
ClientesNOMBRES: TIBStringField;
ClientesFNAC: TDateField;
ClientesDOMICILIO: TIBStringField;
ClientesLOCALIDAD: TIBStringField;
SClientes: TDataSource;
IBEvents1: TIBEvents;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure IBEvents1EventAlert(Sender: TObject; EventName: string;
EventCount: Integer; var CancelAlerts: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
DM: TDM;

implementation

{$R *.dfm}

procedure TDM.DataModuleCreate(Sender: TObject);
Var BaseDeDatos: String;
IniFile: TIniFile;
begin
// Obtiene la ruta y el nombre de la base de datos
IniFile := TIniFile.Create(ExtractFilePath(Application.ExeName)+'BDatos.ini');
BasedeDatos := IniFile.ReadString('BD','Path','');
If BasedeDatos = '' then
ShowMessage('Error al cargar Base de Datos') else
Begin
Try
BaseGeneral.DatabaseName := BaseDeDatos;
BaseGeneral.Connected := True;
Transaccion.Active := True;
Clientes.Open;
// IBEvents1.Events.Clear;
// IBEvents1.Events.Add('new_reg');
// IBEvents1.RegisterEvents;
Except
ShowMessage('No se puede conectar el servidor...');
End;
End;
end;

procedure TDM.DataModuleDestroy(Sender: TObject);
begin
Transaccion.Active := False;
BaseGeneral.Connected := False;
Clientes.Close;
// IBEvents1.UnRegisterEvents;
end;

procedure TDM.IBEvents1EventAlert(Sender: TObject; EventName: string;
EventCount: Integer; var CancelAlerts: Boolean);
begin
{ if EventName = 'new_reg' then
Begin
ShowMessage('Edito');
SClientes.DataSet.Refresh;
End; }
end;

end.

Comentado esta el codigo para el IbEvent


Saludos.- y espero que vayamos orientando hacia alguna parte

:D Gracias martins, tenia las componentes IBEvent pero no sabia como utilizarlas bien igual que el trigger de la base !!!!!

MartinS
03-05-2012, 17:17:54
Bueno parece que vamos encontrando el rumbo. Igual los tengo comentados (Lo de IbEvents) porque no se cual es la razon que se queda pensando el sistema en red. Seguramente hay algo que estoy mal pero ya alguien va a comentar.

Saludos

pelikno
03-05-2012, 17:48:36
Bueno parece que vamos encontrando el rumbo. Igual los tengo comentados (Lo de IbEvents) porque no se cual es la razon que se queda pensando el sistema en red. Seguramente hay algo que estoy mal pero ya alguien va a comentar.

Saludos
Cree los trigers pero el IBEvents no me los capta, puse el debuger y no pasa nunca, tengo seteada la databse en IBEvent, algo mas hay que hacer ?

MartinS
03-05-2012, 18:21:00
Hagamos una cosa: Pone el codigo del trigger y vemos porque no setee nada raro en el componente solo le asigne la Database, Tambien lo cree en el datamodule no se si tendra algo que ver.

A tener en cuenta:

CREATE TRIGGER POST_NEW_REG FOR CLIENTES
ACTIVE AFTER INSERT
POSITION 0
AS
BEGIN

POST_EVENT 'new_reg';
END

new_reg es el nombre del evento envia la base de datos y que captaremos, y en el evento OnEventAlert del IbEvents hacemos la pregunta

procedure TDM.IBEvents1EventAlert(Sender: TObject; EventName: string;
EventCount: Integer; var CancelAlerts: Boolean);
begin
if EventName = 'new_reg' then
Begin
// ShowMessage('Nuevo registro');
SClientes.DataSet.Refresh;
End;
end;

donde preguntamos si viene el evento new_reg hacemos el refresco del datasource que enlaza la grilla (Ojo parece que diferencia mayusculas de minusculas - Me pasó)

pelikno
03-05-2012, 18:28:45
Hagamos una cosa: Pone el codigo del trigger y vemos porque no setee nada raro en el componente solo le asigne la Database, Tambien lo cree en el datamodule no se si tendra algo que ver.

A tener en cuenta:

Código SQL [-] (http://www.clubdelphi.com/foros/#)CREATE TRIGGER POST_NEW_REG FOR CLIENTES ACTIVE AFTER INSERT POSITION 0 AS BEGIN POST_EVENT 'new_reg'; END


new_reg es el nombre del evento envia la base de datos y que captaremos, y en el evento OnEventAlert del IbEvents hacemos la pregunta

Código Delphi [-] (http://www.clubdelphi.com/foros/#)procedure TDM.IBEvents1EventAlert(Sender: TObject; EventName: string; EventCount: Integer; var CancelAlerts: Boolean); begin if EventName = 'new_reg' then Begin // ShowMessage('Nuevo registro'); SClientes.DataSet.Refresh; End; end;

donde preguntamos si viene el evento new_reg hacemos el refresco del datasource que enlaza la grilla (Ojo parece que diferencia mayusculas de minusculas - Me pasó)


procedure TCustomerData.IBEvents1EventAlert(Sender: TObject;
EventName: String; EventCount: Integer; var CancelAlerts: Boolean);
begin
if EventName = 'new_reg' then
begin
Umain.Form1.inmuebles.Refresh;
Umain.Form1.localidades.Refresh;
end;

MartinS
03-05-2012, 18:31:42
y el del trigger?

pelikno
03-05-2012, 18:40:54
CREATE OR ALTER TRIGGER LOCALIDADES_POS FOR LOCALIDADES
ACTIVE AFTER INSERT POSITION 0
AS
begin
post_event 'new_reg';
end

este es el triger que cree con ibexpert en la tabla localidades

MartinS
03-05-2012, 18:51:20
Debería funcionar. :confused:.
Volvemos a las transacciones (El evento solo se ejecuta si hay un commit o CommitRetainging);

En ese evento de AfterPost del IbTable no pongas

localidades.Transaction.CommitRetaining;

Pone de acuerdo a tu componente IbTransaction, es decir:

CostumerData.IbTransaction.CommitRetainig

pelikno
03-05-2012, 18:59:31
Debería funcionar. :confused:.
Volvemos a las transacciones (El evento solo se ejecuta si hay un commit o CommitRetainging);

En ese evento de AfterPost del IbTable no pongas

Código Delphi [-] (http://www.clubdelphi.com/foros/#)localidades.Transaction.CommitRetaining;


Pone de acuerdo a tu componente IbTransaction, es decir:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)CostumerData.IbTransaction.CommitRetainig



los comente a los dos
procedure TForm1.localidadesAfterPost(DataSet: TDataSet);
begin
//localidades.Transaction.CommitRetaining;
// CustomerData.IBTransaction1.CommitRetaining;
end;

Pero hace el post de todas formas, porque cierro mi aplicacion y al volver abrirla estan los cambios guardados, supongo que sera en el momento de cerrar que commitea

pelikno
03-05-2012, 20:07:06
Funcionoooooooooooooooooooooooooooo :D:D:D:D:D:D!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Gracias gente por su tiempo y martins idolo por el codigo, lo que buscaba era eso el trigger de firebird que dispare el evento para actualizar los clientes anda de puta madre , muchisimas gracias !!!! :D:D:D

Delphius
03-05-2012, 20:47:29
Funcionoooooooooooooooooooooooooooo :D:D:D:D:D:D!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Gracias gente por su tiempo y martins idolo por el codigo, lo que buscaba era eso el trigger de firebird que dispare el evento para actualizar los clientes anda de puta madre , muchisimas gracias !!!! :D:D:D

:mad: Claro, claro... eso no te lo habían dicho ¿verdad? Que yo sepa desde el comienzo te habían comentado de que empezaras a leer sobre los eventos, te remitieron enlaces al material. Pero tu si que estas hacerte el ciego cuando te conviene. Porque como ha dicho Casi, lees pero no te enteras.
Das la impresión de que lo que estabas buscando con todo esto es que viniera alguien con el código

MartinS
03-05-2012, 22:31:38
Gracias gente por su tiempo y martins idolo por el codigo, lo que buscaba era eso el trigger de firebird que dispare el evento para actualizar los clientes anda de puta madre , muchisimas gracias !!!!


Bueno, al fin :D:D:D me alegro. Llevo 80 POST, SI!!! OCHENTA :eek: pero llego el resultado

Merezco un ascenso :p:p Jeje,

Saludos.-

Delphius
04-05-2012, 02:16:35
Bueno, al fin :D:D:D me alegro. Llevo 80 POST, SI!!! OCHENTA :eek: pero llego el resultado

Merezco un ascenso :p:p Jeje,

Saludos.-
Tienes que dirigirte a la Taberna, en horario comercial según hora de Zimbabwe, dejar tus datos en la planilla, y recién canjear tus posts + 2,50 pesos y te ganas la calcomanía que dice "Yo tuve paciencia y resolví una duda en ClubDelphi". :D

Luego con 500 posts y 5 pesos te llevas la gorra, con 1000 y 20 pesos la remera. :D

Saludos,

Casimiro Notevi
04-05-2012, 02:29:38
Lo "gracioso" es que ya en las primeras respuestas se indicó que era cuestión de transacciones y se indicó también que hiciera uso de post_event.

MartinS
04-05-2012, 04:21:38
Lo "gracioso" es que ya en las primeras respuestas se indicó que era cuestión de transacciones y se indicó también que hiciera uso de post_event.

Si, lastima que casi lo tome como personal :mad:. No podia ser que no entraran las transacciones y nunca se me cruzo por la cabeza que queria un refresco automatico.- Ahora me dejo los problemas a mi con el tema de los eventos que de paso acabo de postear una duda, espero que no se dilate tanto jaja, :D:D

Saludos

Casimiro Notevi
04-05-2012, 10:15:03
El problema es que no se explicaba bien y no lo comprendíamos, en fin, como dice Neftalí: a mejores preguntas, mejores respuestas.

pelikno
04-05-2012, 14:13:42
Lo "gracioso" es que ya en las primeras respuestas se indicó que era cuestión de transacciones y se indicó también que hiciera uso de post_event.
Si lo que paso fueron confusiones muchos post preguntando por distintas cosas primero lo de internet, depues que no puse las componentes que usaba, depues que no me entendian bien lo que necesitaba y luego creo que lo del post_event lo colocaste junto con el evento afterpost del dataset y eso me hizo pensar que hablabas del after post ya que no aclarabas que era una sentencia del dbms para disparar eventos, y depues me decian que no entendia como trabajaba cliente/servidor, y demas cosas que hacia mal que eso me genero mas confuciones, creo que lo ideal no era mostrar el codigo como le agradezco a martins pero si aclarar que existe una centencia post_event que utiliza el motor de base de datos para disparar un evento a las bases por medio de un trigger el cual puede ser captado por una componenete especial llamada ibevent y de esa forma refrescar cuando se genere un nuevo cambio en la base, con eso solo creo que se me solucionaban todos los problemas aunque tenga que investigar como configurar todo eso.
Las transacciones estaban bien configurardas porque yo ya tenia el commitretains en el evento after post ya que informe que en las terminales me daba error de primarykey al querer agregar el mismo dato que no se refrescaba, por lo tanto el commit si se realizaba.

pelikno
04-05-2012, 14:23:26
Bueno, al fin :D:D:D me alegro. Llevo 80 POST, SI!!! OCHENTA :eek: pero llego el resultado

Merezco un ascenso :p:p Jeje,

Saludos.-
Si si muchas gracias , igual por lo de no imaginar que queria un refresco automatico, lo dije varias veces que no me actualizaba los datos en las terminales al modificar la base y eso era lo que queria , incluso use un timer que me genero problemas porque obviamente me actualizaba a cada rato y eso no lo queria asi, lo que buscaba es que en cada cambio de la base las terminales se actualicen solas que es en si lo que llegamos hacer a lo ultimo con el post_event Abrazo grande !! y gracias.

pelikno
04-05-2012, 19:16:01
Bueno parece que vamos encontrando el rumbo. Igual los tengo comentados (Lo de IbEvents) porque no se cual es la razon que se queda pensando el sistema en red. Seguramente hay algo que estoy mal pero ya alguien va a comentar.

Saludos

Pudiste ver eso porque a mi me funciono bien !!

MartinS
04-05-2012, 22:23:17
Hola. Aun no, vi toda la documentación y parece que es como se hace. Hoy en la mañana (Hora de Argentina - ahora 17:24) hice una prueba y el cliente se moría pensando, creo que es el equipo o bien la red o el sistema operativo. igual no le di mucha importancia porque programado el componente pareciera que esta bien. Me postearon un par de sugerencia como habras visto pero es la documentacion que vi e implemente para resolver tu problema de actualizacion. Veremos que pasa.

Saludos.-