must apply updates before refreshing data
Olá pessoal, procurei no forum e entendi o erro, ok, mas agora peço uma dica, sugestão para o seguinte:
Antes: Uso Delphi 7,dbexpress, firebird 1.5.
1) Tenho um form com o TSqlQuery, TDataSetProvider, TClientDataset, TDatasource e um dbgrid; ==> até aqui ok !
2) No clientdataset adicionei os fields e criei um novo campo com a descrição STATUS - string - tamanho 1 - field type DATA, a finalidade deste campo é que quando o usuário dar um duplo clique no registro selecionado, eu faço assim no evento dblclick do grid:
CQ.Edit;
if CQStatus.asString = ´N´ then
CQStatus.asString := ´S´
else
CQStatus.asString := ´N´;
CQ.Post;
obs: CQ é o name do Clientdataset
3) No evento do Grid - OnDrawColumnCell, tenho uma função para colorir a linha do grid caso o field STATUS = ´S´;
4) Até aqui tudo bem, tudo funciona, o caso é que seu eu precisar e preciso utilizar o refresh no clientdataset ele vem o erro:
must apply updates before refreshing data
Também não posso utilizar CLOSE e OPEN no clientdataset, pois se fizer isto ele perde o que o usuário já selecionou, entenderam ?
Como realizar um refresh neste clientdataset sem perder os registros selecionados, se alguem ja fez algo semelhante por favor, agradeço se puder me ajudar.
César
Antes: Uso Delphi 7,dbexpress, firebird 1.5.
1) Tenho um form com o TSqlQuery, TDataSetProvider, TClientDataset, TDatasource e um dbgrid; ==> até aqui ok !
2) No clientdataset adicionei os fields e criei um novo campo com a descrição STATUS - string - tamanho 1 - field type DATA, a finalidade deste campo é que quando o usuário dar um duplo clique no registro selecionado, eu faço assim no evento dblclick do grid:
CQ.Edit;
if CQStatus.asString = ´N´ then
CQStatus.asString := ´S´
else
CQStatus.asString := ´N´;
CQ.Post;
obs: CQ é o name do Clientdataset
3) No evento do Grid - OnDrawColumnCell, tenho uma função para colorir a linha do grid caso o field STATUS = ´S´;
4) Até aqui tudo bem, tudo funciona, o caso é que seu eu precisar e preciso utilizar o refresh no clientdataset ele vem o erro:
must apply updates before refreshing data
Também não posso utilizar CLOSE e OPEN no clientdataset, pois se fizer isto ele perde o que o usuário já selecionou, entenderam ?
Como realizar um refresh neste clientdataset sem perder os registros selecionados, se alguem ja fez algo semelhante por favor, agradeço se puder me ajudar.
César
Cesarpir
Curtidas 0
Respostas
Bon Jovi
15/10/2004
Em que momento do código ou evento vc ta chamando o Refresh? Se puder, mostre o máximo possível de código relacionado ao problema que fica mais fácil.
GOSTEI 0
Rômulo Barros
15/10/2004
Sempre que estamos trabalhando com o ClientDataset, os dados são armazenados em [b:1e447aff0e]CACHE[/b:1e447aff0e] e ficam na memória do computador. Para realizar um [b:1e447aff0e]REFRESH[/b:1e447aff0e] no ClientDataSet, é necesário que não exista nenhuma atualização pendente em [b:1e447aff0e]CACHE[/b:1e447aff0e]. No seu código, pelo q percebi, vc está realizando o [b:1e447aff0e]POST[/b:1e447aff0e] e os dados estão sendo gravados em [b:1e447aff0e]CACHE[/b:1e447aff0e], mas não no banco de dados. Por isso, ao realizar um [b:1e447aff0e]REFRESH[/b:1e447aff0e](ainda existindo atualizacoes em memória), ocorre o erro. Para solucionar o problema, segue:
CQ.Edit;
if CQStatus.asString = ´N´ then
CQStatus.asString := ´S´
else
CQStatus.asString := ´N´;
CQ.Post;
CQ.ApplyUpdates(0);
Assim, o [b:1e447aff0e]ApplyUpdates[/b:1e447aff0e] pega as atualizações em [b:1e447aff0e]CACHE[/b:1e447aff0e] e manda tudo para o banco de dados. A partir de agora, vc já pode dá um [b:1e447aff0e]REFRESH[/b:1e447aff0e] no ClientDataSet.
[u:1e447aff0e][b:1e447aff0e]OBS:[/b:1e447aff0e][/u:1e447aff0e] É sempre bom verificar se ApplyUpdates(0) > 0, evitando assim q erros pendentes fiquem armazenados em [b:1e447aff0e]CACHE[/b:1e447aff0e] ou verificando se DELTA > 0 ;
:wink:
CQ.Edit;
if CQStatus.asString = ´N´ then
CQStatus.asString := ´S´
else
CQStatus.asString := ´N´;
CQ.Post;
CQ.ApplyUpdates(0);
Assim, o [b:1e447aff0e]ApplyUpdates[/b:1e447aff0e] pega as atualizações em [b:1e447aff0e]CACHE[/b:1e447aff0e] e manda tudo para o banco de dados. A partir de agora, vc já pode dá um [b:1e447aff0e]REFRESH[/b:1e447aff0e] no ClientDataSet.
[u:1e447aff0e][b:1e447aff0e]OBS:[/b:1e447aff0e][/u:1e447aff0e] É sempre bom verificar se ApplyUpdates(0) > 0, evitando assim q erros pendentes fiquem armazenados em [b:1e447aff0e]CACHE[/b:1e447aff0e] ou verificando se DELTA > 0 ;
:wink:
GOSTEI 0
Cesarpir
15/10/2004
Não adiantou eu já tentei isto antes amigo:
CQ.Edit;
if CQSta.asString = ´S´ then
CQSta.asString := ´N´
else
CQSta.asString := ´S´;
CQ.Post;
CQ.ApplyUpdates(0); // acrescentei esta linha que vc disse mas não deu
Olha a select abaixo vê se ajuda um pouco, só falta corrigir este ficaria perfeito, utilizo esta técnica para outros projetos, mas sempre me deparo com este problema, se resolver aí fico feliz:
// é uma tabela de cheques, esta fica no componente TSQLQUERY
SELECT CHEBAN,
CHEAGE,
CHECON,
CHENUM,
CHEVAL,
CHEDAT,
CHEBOM,
CHETIT,
CHESTA,
CHEEXT,
CLICOD,
EMPCOD,
FORCOD,
PAGNUM,
PAVVEN,
(CAST(´N´ AS CHAR(1))) STA -> este campo não faz parte eu crio ele na sql para fazer aquela troca de cor no grid (é uma gambi)
FROM CHEQUES
WHERE PAGNUM = 0 OR PAGNUM IS NULL
ORDER
BY CHEBOM
O objetivo como já disse é listar todos os cheques disponiveis para o usuário, caso ele queira ele pode incluir, existe um botão incluir no form que chama o cadastro do cheque na volta da inclusão preciso atualizar o grid, é ai que mora o problema, quando ele inclui um novo cheque teria que atualizar através de um refresh ou close e open, o problema é que se ele já selecionou algum cheque anteriormente através do duplo clique e executo o edit e post no clientdataset, ai dá o erro !
Usei post ao invés de applyupdates(0) porque sei que somente atualiza o componente, não quero e nem é o objetivo atualizar o banco, entendeu ?
Agora se existir outra forma, agradeço a atenção, é uma coisa que aparentemente parecia simples, tá complicando ::))
Se tivesse como passar sem este erro.
É como se fosse uma table de memória, acredito eu não é ?
Abráços e obrigado
César
CQ.Edit;
if CQSta.asString = ´S´ then
CQSta.asString := ´N´
else
CQSta.asString := ´S´;
CQ.Post;
CQ.ApplyUpdates(0); // acrescentei esta linha que vc disse mas não deu
Olha a select abaixo vê se ajuda um pouco, só falta corrigir este ficaria perfeito, utilizo esta técnica para outros projetos, mas sempre me deparo com este problema, se resolver aí fico feliz:
// é uma tabela de cheques, esta fica no componente TSQLQUERY
SELECT CHEBAN,
CHEAGE,
CHECON,
CHENUM,
CHEVAL,
CHEDAT,
CHEBOM,
CHETIT,
CHESTA,
CHEEXT,
CLICOD,
EMPCOD,
FORCOD,
PAGNUM,
PAVVEN,
(CAST(´N´ AS CHAR(1))) STA -> este campo não faz parte eu crio ele na sql para fazer aquela troca de cor no grid (é uma gambi)
FROM CHEQUES
WHERE PAGNUM = 0 OR PAGNUM IS NULL
ORDER
BY CHEBOM
O objetivo como já disse é listar todos os cheques disponiveis para o usuário, caso ele queira ele pode incluir, existe um botão incluir no form que chama o cadastro do cheque na volta da inclusão preciso atualizar o grid, é ai que mora o problema, quando ele inclui um novo cheque teria que atualizar através de um refresh ou close e open, o problema é que se ele já selecionou algum cheque anteriormente através do duplo clique e executo o edit e post no clientdataset, ai dá o erro !
Usei post ao invés de applyupdates(0) porque sei que somente atualiza o componente, não quero e nem é o objetivo atualizar o banco, entendeu ?
Agora se existir outra forma, agradeço a atenção, é uma coisa que aparentemente parecia simples, tá complicando ::))
Se tivesse como passar sem este erro.
É como se fosse uma table de memória, acredito eu não é ?
Abráços e obrigado
César
GOSTEI 0
Bon Jovi
15/10/2004
E onde está CQ.Refresh afinal?
GOSTEI 0
Sergiomatos
15/10/2004
Colega pelo que entendi vc cria uma campo temporario em ClientDataset para representar a selecao dos registros pelos usuario, mas este campo nao existe no seu banco de dados.
Para que o Delphi nao considere o campo STATUS para atualizacao no banco de dados vc precisa informar que o campo STATUS nao precisa ser alterado no banco de dados por ser temporario.
Para isso defina a ProviderFlags = [] para o campo STATUS.
Dessa forma o delphi nao vai armazenar alteracoes no cache para o campo e vc poderá chamar refresh sem erros.
Para que o Delphi nao considere o campo STATUS para atualizacao no banco de dados vc precisa informar que o campo STATUS nao precisa ser alterado no banco de dados por ser temporario.
Para isso defina a ProviderFlags = [] para o campo STATUS.
Dessa forma o delphi nao vai armazenar alteracoes no cache para o campo e vc poderá chamar refresh sem erros.
GOSTEI 0
Cesarpir
15/10/2004
Valeu amigo, nossa depois de tanto tempo ::))), vou testar aqui para ver se funciona, muito obrigado
César
César
GOSTEI 0