Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Diseño de sistema en RED LAN (https://www.clubdelphi.com/foros/showthread.php?t=78586)

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

Código Delphi [-]
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

Cita:

Empezado por Casimiro Notevi (Mensaje 431677)
Código Delphi [-]
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
Código Delphi [-]
[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

Cita:

Empezado por Casimiro Notevi (Mensaje 431679)
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 <--- click ahí ---
Y este enlace también lo puse antes.

MartinS 03-05-2012 16:38:28

Hola nuevamente:

esto:

Código Delphi [-]
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

Código Delphi [-]
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:

Código SQL [-]
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:

Código Delphi [-]
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

Cita:

Empezado por MartinS (Mensaje 431684)
Hola nuevamente:

esto:

Código Delphi [-]
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

Código Delphi [-]
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:

Código SQL [-]
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:

Código Delphi [-]
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

Cita:

Empezado por MartinS (Mensaje 431688)
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:

Código SQL [-]
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 [-]
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

Cita:

Empezado por MartinS (Mensaje 431690)
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 [-]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 [-]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ó)

Código Delphi [-]
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

Código SQL [-]
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

Código Delphi [-]
localidades.Transaction.CommitRetaining;

Pone de acuerdo a tu componente IbTransaction, es decir:

Código Delphi [-]
CostumerData.IbTransaction.CommitRetainig

pelikno 03-05-2012 18:59:31

Cita:

Empezado por MartinS (Mensaje 431696)
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 [-]localidades.Transaction.CommitRetaining;


Pone de acuerdo a tu componente IbTransaction, es decir:

Código Delphi [-]CostumerData.IbTransaction.CommitRetainig

los comente a los dos
Código Delphi [-]
 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

Cita:

Empezado por pelikno (Mensaje 431706)
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


La franja horaria es GMT +2. Ahora son las 19:08:32.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi