Fórum Verificar se registro já existe #385060

29/08/2010

0

Pessoal

Estou tentando usar o ClientDataSet1.findKey mas não estou conseguindo, ele informa o
erro 'Unknown ISC error 0'.
Gostaria de saber como verifico se a venda já existe, e se existir, trazê-la.

...

With dm do
 Begin
  If TableVenda.findkey([TableVendaDocumento.value,TableVendaNumero.value]) then
     Begin
       M:=TableVendaDocumento.value;
       R:=TableVendaNumero.Value;
       TableVenda.cancel;
       TableVenda.FindKey([M,R]);
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       Db1.SetFocus;
     end
   Else
     Begin
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       TableVendaData.Value:=Date;
       Db1.SetFocus;
     end;
   end;


Li na internet que preciso setar o indice, mas o indice é a própria chave 'Documento e Numero'.
Caso precisasse setar um indice no ClientDataSet como seria ?.

Grato.


Marcos Roberto

Marcos Roberto

Responder

Posts

29/08/2010

Marco Salles

Pessoal

Estou tentando usar o ClientDataSet1.findKey mas não estou conseguindo, ele informa o
erro 'Unknown ISC error 0'.
Gostaria de saber como verifico se a venda já existe, e se existir, trazê-la.

...

With dm do
 Begin
  If TableVenda.findkey([TableVendaDocumento.value,TableVendaNumero.value]) then
     Begin
       M:=TableVendaDocumento.value;
       R:=TableVendaNumero.Value;
       TableVenda.cancel;
       TableVenda.FindKey([M,R]);
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       Db1.SetFocus;
     end
   Else
     Begin
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       TableVendaData.Value:=Date;
       Db1.SetFocus;
     end;
   end;


Li na internet que preciso setar o indice, mas o indice é a própria chave 'Documento e Numero'.
Caso precisasse setar um indice no ClientDataSet como seria ?.

Grato.


so uma curiosidade ... Vc esta utilizando dois campos para a pesquisa Porque ??? TableVendaNumero Não é Unico ??? Ou mesmo TableVendaDocumento tb não é unico ??? Porque que tem que encontrar os dois Juntos ???   Para setar este indice composto em tempo de designed ( tb da para fazer isto em RumTime ) Vc faz No Objecto Ispector selecione IndexDelfs .. clique na reticencias Na Caixa Editing clique no Botão Novo No Objecto Inspector deste Novo Item Selecione as proproiedades que vc quer .. de imediato são elas Fields >> Escreva os Nomes dos Campos separados por ponto e virgula Name >> Escolha um Nome para este Indice Veja que existem outras Opçoes interessantes em  options , vc define a caracteristica deste indice   No seu projeto qnd vc quiser usar este Indice vc faz   NomeDoSeiCds.IndexName:='NomeEscolhidoParaIndice';
Responder

Gostei + 0

29/08/2010

Pjrm1470

Existe duas maneiras de se fazer uma procura por um registro em um DataSet. - FindKey() - Locate()   Bem... você disse que não está conseguindo utilizar o findKey. Ja tentou usar o locate()? Não sei dizer como solucionar este erro, mas sei que posso lhe dar outra alternativa, pois nunca usei o findKey. sempre utilizo o Locate.   Normalmente quando mandamos procurar por alguma coisa, mandamos uma referencia e um valor de procura. Como a tabela vai saber qual valor você quer achar se você so passa as referências? rs.
if TableVenda.Locate('VendaDocumento', ValorDeBusca, []) then
ou
if TableVenda.Locate('VendaNumero', ValorDeBusca, []) then
  Fique a vontade para perguntar. Att, pjrm1470.
Responder

Gostei + 0

29/08/2010

Marcos Roberto

Marco Antonio

Fiz como vc falou, criei o indice e ainda não resolveu.
A tabela tem duas chaves que pode ser documento=NC e Numero='0001' ou Documento='NF' e Numero='0001'.
NC Nota ao Consumidor e NF Nota Fiscal para pessoa Juridica.

Este metodo funcionava qdo usava com paradox, agora no Firebird esta com este problema.
...


PJRM1470

Posso usar o Locate, mas como passo as duas chaves no locate ???? já tentei e dá erro no sintaxe.
....



grato pessoal


Responder

Gostei + 0

29/08/2010

Pjrm1470

Tente utilizar o Filter e Filtered do DataSet. Assim você consegue filtrar por várias condições. Faça o teste e me diga.
Responder

Gostei + 0

29/08/2010

Marco Salles

Marco Antonio

Fiz como vc falou, criei o indice e ainda não resolveu.
A tabela tem duas chaves que pode ser documento=NC e Numero='0001' ou Documento='NF' e Numero='0001'.
NC Nota ao Consumidor e NF Nota Fiscal para pessoa Juridica.

Este metodo funcionava qdo usava com paradox, agora no Firebird esta com este problema.
...


PJRM1470

Posso usar o Locate, mas como passo as duas chaves no locate ???? já tentei e dá erro no sintaxe.
....



grato pessoal


bem ... se vc criou esses indices corretamente   qnd vc fez   Seucds.IndexName:='SeuIndiceCompostoCriado';   Agora para usar o FindKey vc simplesmente faz   if cds.FindKey([edit1.Text,edit2.Text]) then   qualquer coisa else  outra coisa   Onde Edit1.text , edit2.text contem o dado que vc esta procurando respectivamente   Aqui a busca é simultanea e é END ... Ou os Dois ou nada Feito   entendeu ???
Responder

Gostei + 0

30/08/2010

Eriley Barbosa

Não precisa usar o Findkey, pode usar o Locate com VarArrayOf, exemplo: DataSet.Locate('CAMPO1;CAMPO2', VarArrayOf(['String','String2']), []); With dm do
 Begin
  If TableVenda.Locate('Documento;Numero', VarArrayOf([TableVendaDocumento.value,TableVendaNumero.value]), []) then
     Begin
       M:=TableVendaDocumento.value;
       R:=TableVendaNumero.Value;
       TableVenda.cancel;
       TableVenda.Locate('Documento;Numero', VarArrayOf([M,R]), []) ;
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       Db1.SetFocus;
     end
   Else
     Begin
       venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
       TableVendaData.Value:=Date;
       Db1.SetFocus;
     end;
   end;
Responder

Gostei + 0

30/08/2010

Marco Salles

eu comentei do findKey pq o autor do tópico o usa . Resta comentar que o Locate funciona mas so é recomendável para pequenos Range de dados do ClientDataSet. Para Volumes maiores de dados é alta perfomace que se utilize Indices em Memória juntamente com os métodos SetKey seguido do GotoKey .
Responder

Gostei + 0

30/08/2010

Marcos Roberto


Eriley

Na linha

" If TableVenda.Locate('Documento;Numero',VarArrayOf([TableVendaDocumento.value,TableVendaNumero.value]),[]) then"

está dando os seguintes erros

[DCC Error] untVenda.pas(217): E2066 Missing operator or semicolon
[DCC Error] untVenda.pas(217): E2001 Ordinal type required
[DCC Error] untVenda.pas(217): E2010 Incompatible types: 'Integer' and 'AnsiString'


Tô sem entender nada !!!

Responder

Gostei + 0

31/08/2010

Leonardo Bertolini

Bom, não conheço a estrutura da sua aplicação mas vou sugeria uma alternativa ao problema.

Se vc quer verificar se a venda já existe, crie uma função que de um select no banco passando na cláusula where os codigos referente a venda.

Vc também pode rodar um loop no ClientDataSet e testar os campos para ver se algum registro bate com a venda.

Bom, lógico isso depende do tamanho da sua aplicação e da quantidade de registros envolvidos nessa tabela.

espero ter ajudado, abraços.

twitter.com/leobertolini
Responder

Gostei + 0

31/08/2010

Marcos Roberto

Leonardo

Pensando no que vc me passou, gostaria de tirar esta outra dúvida:

No formulario de Vendas os DbEdit´s estão relacionados com a CDSVenda, ou seja DBedit1 é o CDSVendaNUMERO.value quando da ativação do form um insert é feito neste CDS, então teremos um ponteiro indicando um novo registro.
Agora, quando usar a função para verificar se esta venda já existe e retornar um null o formulário perderá as informações já digitadas não é.


1) Poderia então eu fazer esta função dando o select em outro CDS para não bagunçar este form????
2) Como normalmente é feito esses forms ?: colocamos DBEdit´s ou simplesmente Edit´s e depois atribuir
todos Edit´s para a tabela e dar o post.
 

Grato 


Responder

Gostei + 0

31/08/2010

Leonardo Bertolini

Bom Marcos seguinte,
Existem várias formas de exibir dados pro usuário, alguns de desenvolvedores preferem utilizar simples edit's e atribuir o valor do campo ao edit....  outros preferem componentes DB que ja trazem direto o valor do campo.
Acredito que a primeira opção tenha uma performance melhor, mas dependendo do tamanho da sua aplicação torna-se irrelevante.
Quanto a sua verificação se a venda já existe, com certeza seria melhor usar um outro DataSet para verificar se a venda existe (nao usar os mesmo DataSet que esta relacionado aos edit's do form).

Qual tipo de conexão ao BD vc utiliza ?  ADO ? DBExpress ? Zeos ?  qual BD é ?

Responder

Gostei + 0

31/08/2010

Leonardo Bertolini

Completando a resposta.... 

Assim se este outro DataSet não retornar nenhum registro vc sabe que a venda não existe, e ai vc pode fazer o que quiser dependendo do resultado.
Como tirar do modo de inserção o seu ClientDataSet
CDS.Cancel;
Responder

Gostei + 0

31/08/2010

Marcos Roberto

Leonardo

Valeu pela dica, vou verificar se o registro existe noutra CDS.

Uso Delphi 2010, DBExpress e Firebird.

SqlConnection, TClientDataSet, TSqlDataSet, TDataSetProvider e DataSource


Abraço.



Cara, outro problema: Quando insiro o terceiro item da venda dá um erro de chave violada, sendo que na tabela tem o seguinte trigger;

AS BEGIN
      IF(NEW."CODIGO" IS NULL) THEN NEW."CODIGO" = GEN_ID("GEN_TITEMVEN_CODIGO",1);
    END

Onde preciso mexer para fazer valer este trigger, com as outras tabelas sem mestre-detalhe não dão este erro.


Responder

Gostei + 0

31/08/2010

Leonardo Bertolini

Cara...  vi que vc usa a trigger para gerar a um sequencial....  mas me manda a estrutura da sua tabela informando quais sao as chaves primarias. ou se é so uma.
Responder

Gostei + 0

31/08/2010

Eriley Barbosa

Quais os tipos das variaveis M e R? Quais os tipos dos campos Documento e Numero?
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar