Fórum atualizar tabela acces em rede... #183726
23/09/2003
0
Olá, estou desenvolvendo um sistema e estou utilizando banco de dados acces, eu utilizo para conexão o componente ADOConnection1 e ADOTABLE ligada ao ADOConnection1, quando gravo um registro, preciso atualizá-lo na rede para isso uso:
with DM.tCliente do
begin
Post;
Refresh;
end;
o problema é que o refresh não funciona, você sabe como posso fazer isso???
soda limonada
balceiro@bol.com.br
with DM.tCliente do
begin
Post;
Refresh;
end;
o problema é que o refresh não funciona, você sabe como posso fazer isso???
soda limonada
balceiro@bol.com.br
Balceiro
Curtir tópico
+ 0
Responder
Posts
24/09/2003
Mmtoor
Prezado colega:
Gostaria de colocar uma explanação menor, mas os seus questionamentos não permitiriam isso.
Assim sendo, informo que, uma aplicação que permite o acesso multiusuário a uma tabela corre um sério risco: o de dois ou mais usuários simultaneamente editarem o mesmo registro, sem que um siaba que o outro está editando.
Com Paradox, o Delphi bloqueia o registro que está sendo editado, impedindo que outro usuário o edite enquanto a modificação está sendo feita. É um bloqueio pessimista. O registro só é desbloqueado quando o usuário grava a modificação.
Já o Access trabalha de modo diferente. Dois usuários podem editar o mesmo registro simultaneamente. Mas se um deles salvar a modificação feita, o outro não poderá mais salvar as suas modificações. É um bloqueio otimista.
Uma mensagem será apresentada, ou seja, o access alerta que o registro foi modificado por outro usuário, quando vc tenta gravar o registro cuja imagem não corresponda mais a realidade.
Após receber esta mensagem você deve cancelar a edição feita, chamando o método cancel do componente table.
Quando vc cancela a edição, automaticamente a tabela é relida, e as modificações feitas pelo outro usuário aparecem em seu registro.
Observe que você só é alertado na primeira vez que tenta gravar um registro que foi modificado sem vc saber. Se, após a mensagem, vc tentar salvar suas modificações, irá conseguir.
A messagem de erro mencionada que será apresentada estará em inglês, e, infelizmente ainda nos dias de hoje, a maioria dos usuários e operadores de computador não conhecem este idiioma.
Assim sendo, cabe fazer um tratamento nesta mensagem no evento OnPostError do objeto table ou query utilizado. Este evento ocorre sempre que um erro aparece ao editarmos a tabela e possui a seguinte síntase:
OnPostError(DataSet: TdataSet; E: EdataBaseError;varAction:TdataAction);
O parâmetro E é um objeto da classe EdataBaseError, ou seja, equivale à exceção gerada. Toda classe de exceções possui propriedades e métodos comuns, entre eles a propriedade Message, que determina a mensagem a ser apresentada, do tipo string.
Portanto, para modificarmos a mensagem oferecida quando ocorre um erro na tentativa de gravação de um registro modificado, basta digitarmos o seguinte código:
Procedure Tform1.Table1PostError(DataSet: TdataSet; E: EdataBaseError; var Action: TdataAction);
Begin
E.Message:= ‘Registro modificado por outro usuário! Sua edição será cancelada e o registro atualizado!’;
Table1.cancel;
End;
Aproveitamos então para chamar o método cancel do componente table.
Você também deve proporcionar em sua aplicação a oportunidade do usuário reler os dados do registro, sempre que desejar.
Para isso, conforme vc mesmo já colocou, utilize o método refresh do componente table ou query.
Este método relê o registro, colocando nos componentes de visualização de dados os valores atuais.
O mais interessante que a releitura destes dados seja realizada de forma automática.
Esta automatização de refresh pode ser feita com um Ttimer.
Um cuidado deve ser tomado neste evento. A releitura dos dados se dá através do método refresh, só que ele aciona o método post, gravando na tabela o que esta sendo editado, ou seja, se vc estiver editando um registro e, de tempos em tempos o método refresh é chamado, as modificações são salvas imediatamente, quer vc queira ou não, o que não é nenhum pouco conveniente.
Para impedir, ou seja, contornar isso, usamos a função DBIIsRecordLocked, da API do BDE. Esta função verifica se o registro está bloqueado. Se estiver, ou seja, se vc estiver editando-o, o método refresh não é chamado para sua máquina.
Esta função não funciona para as outras máquinas que não estão editando o registro, portanto, elas executarão o método refresh normalmente.
A função DBIIsRecordLocked possui dois parâmetros. O primeiro refere-se à propriedade Handle da tabela, e o segundo a uma variável booleana que armazena o resultado da função.
Se o registro estiver bloqueado, a variável booleana retornará True.
Você deve acrescentar a unit BDE na cláusula Uses da seção Interface para poder utilizar a função DBIIsRecordLocked.
Para colocar isso em prática, coloquemos um timer no form (se quiser implementar pode inserir também um label). Um intervalo razoável para o timert seria de 5000 (5 segundos).
No evento Ontimer insira o seguinte código (não se esquecendo de adicionar a unit BDE na cláusula Uses da seção Interface).
Procedure Tform1.Timer1.Timer(Sender : Object);
Var
Editando: bool;
Begin
DBIIsRecordLocked(Table1.Handle, editando);
If editando = False Then
Begin
Table1.refresh;
Label1.Caption:= ‘Dados atualizados em ‘+TimerToStr(Now);
End;
End;
Obs: Caso, na abertura do seu sistema haja muita latência haverá uma mensagem de erro pois o evento refresh será chamado e a tabela ainda não estará aberta. Basta clicar em OK e prosseguir, ou, se preferir, aumentar o tempo para refresh;
Devo informar ao colega que. Mesmo com todos estes cuidados ainda pode haver necessidade de mais tratamentos.
Espero ter ajudado.
MMTOOR2003
Gostaria de colocar uma explanação menor, mas os seus questionamentos não permitiriam isso.
Assim sendo, informo que, uma aplicação que permite o acesso multiusuário a uma tabela corre um sério risco: o de dois ou mais usuários simultaneamente editarem o mesmo registro, sem que um siaba que o outro está editando.
Com Paradox, o Delphi bloqueia o registro que está sendo editado, impedindo que outro usuário o edite enquanto a modificação está sendo feita. É um bloqueio pessimista. O registro só é desbloqueado quando o usuário grava a modificação.
Já o Access trabalha de modo diferente. Dois usuários podem editar o mesmo registro simultaneamente. Mas se um deles salvar a modificação feita, o outro não poderá mais salvar as suas modificações. É um bloqueio otimista.
Uma mensagem será apresentada, ou seja, o access alerta que o registro foi modificado por outro usuário, quando vc tenta gravar o registro cuja imagem não corresponda mais a realidade.
Após receber esta mensagem você deve cancelar a edição feita, chamando o método cancel do componente table.
Quando vc cancela a edição, automaticamente a tabela é relida, e as modificações feitas pelo outro usuário aparecem em seu registro.
Observe que você só é alertado na primeira vez que tenta gravar um registro que foi modificado sem vc saber. Se, após a mensagem, vc tentar salvar suas modificações, irá conseguir.
A messagem de erro mencionada que será apresentada estará em inglês, e, infelizmente ainda nos dias de hoje, a maioria dos usuários e operadores de computador não conhecem este idiioma.
Assim sendo, cabe fazer um tratamento nesta mensagem no evento OnPostError do objeto table ou query utilizado. Este evento ocorre sempre que um erro aparece ao editarmos a tabela e possui a seguinte síntase:
OnPostError(DataSet: TdataSet; E: EdataBaseError;varAction:TdataAction);
O parâmetro E é um objeto da classe EdataBaseError, ou seja, equivale à exceção gerada. Toda classe de exceções possui propriedades e métodos comuns, entre eles a propriedade Message, que determina a mensagem a ser apresentada, do tipo string.
Portanto, para modificarmos a mensagem oferecida quando ocorre um erro na tentativa de gravação de um registro modificado, basta digitarmos o seguinte código:
Procedure Tform1.Table1PostError(DataSet: TdataSet; E: EdataBaseError; var Action: TdataAction);
Begin
E.Message:= ‘Registro modificado por outro usuário! Sua edição será cancelada e o registro atualizado!’;
Table1.cancel;
End;
Aproveitamos então para chamar o método cancel do componente table.
Você também deve proporcionar em sua aplicação a oportunidade do usuário reler os dados do registro, sempre que desejar.
Para isso, conforme vc mesmo já colocou, utilize o método refresh do componente table ou query.
Este método relê o registro, colocando nos componentes de visualização de dados os valores atuais.
O mais interessante que a releitura destes dados seja realizada de forma automática.
Esta automatização de refresh pode ser feita com um Ttimer.
Um cuidado deve ser tomado neste evento. A releitura dos dados se dá através do método refresh, só que ele aciona o método post, gravando na tabela o que esta sendo editado, ou seja, se vc estiver editando um registro e, de tempos em tempos o método refresh é chamado, as modificações são salvas imediatamente, quer vc queira ou não, o que não é nenhum pouco conveniente.
Para impedir, ou seja, contornar isso, usamos a função DBIIsRecordLocked, da API do BDE. Esta função verifica se o registro está bloqueado. Se estiver, ou seja, se vc estiver editando-o, o método refresh não é chamado para sua máquina.
Esta função não funciona para as outras máquinas que não estão editando o registro, portanto, elas executarão o método refresh normalmente.
A função DBIIsRecordLocked possui dois parâmetros. O primeiro refere-se à propriedade Handle da tabela, e o segundo a uma variável booleana que armazena o resultado da função.
Se o registro estiver bloqueado, a variável booleana retornará True.
Você deve acrescentar a unit BDE na cláusula Uses da seção Interface para poder utilizar a função DBIIsRecordLocked.
Para colocar isso em prática, coloquemos um timer no form (se quiser implementar pode inserir também um label). Um intervalo razoável para o timert seria de 5000 (5 segundos).
No evento Ontimer insira o seguinte código (não se esquecendo de adicionar a unit BDE na cláusula Uses da seção Interface).
Procedure Tform1.Timer1.Timer(Sender : Object);
Var
Editando: bool;
Begin
DBIIsRecordLocked(Table1.Handle, editando);
If editando = False Then
Begin
Table1.refresh;
Label1.Caption:= ‘Dados atualizados em ‘+TimerToStr(Now);
End;
End;
Obs: Caso, na abertura do seu sistema haja muita latência haverá uma mensagem de erro pois o evento refresh será chamado e a tabela ainda não estará aberta. Basta clicar em OK e prosseguir, ou, se preferir, aumentar o tempo para refresh;
Devo informar ao colega que. Mesmo com todos estes cuidados ainda pode haver necessidade de mais tratamentos.
Espero ter ajudado.
MMTOOR2003
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)