Verificar se registro já existe
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.
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
Curtidas 0
Respostas
Marco Salles
29/08/2010
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';
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.
GOSTEI 0
Pjrm1470
29/08/2010
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.
ou
Fique a vontade para perguntar.
Att,
pjrm1470.
if TableVenda.Locate('VendaDocumento', ValorDeBusca, []) thenif TableVenda.Locate('VendaNumero', ValorDeBusca, []) thenGOSTEI 0
Marcos Roberto
29/08/2010
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
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
GOSTEI 0
Pjrm1470
29/08/2010
Tente utilizar o Filter e Filtered do DataSet.
Assim você consegue filtrar por várias condições.
Faça o teste e me diga.
GOSTEI 0
Marco Salles
29/08/2010
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 ???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
GOSTEI 0
Eriley Barbosa
29/08/2010
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;
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;
GOSTEI 0
Marco Salles
29/08/2010
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 .
GOSTEI 0
Marcos Roberto
29/08/2010
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 !!!
GOSTEI 0
Leonardo Bertolini
29/08/2010
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
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
GOSTEI 0
Marcos Roberto
29/08/2010
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
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
GOSTEI 0
Leonardo Bertolini
29/08/2010
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 é ?
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 é ?
GOSTEI 0
Leonardo Bertolini
29/08/2010
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;
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;
GOSTEI 0
Marcos Roberto
29/08/2010
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.
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.
GOSTEI 0
Leonardo Bertolini
29/08/2010
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.
GOSTEI 0
Eriley Barbosa
29/08/2010
Quais os tipos das variaveis M e R?
Quais os tipos dos campos Documento e Numero?
GOSTEI 0
Marcos Roberto
29/08/2010
Leonardo
Chave Primaria DOCUMENTO e NUMERO;
CREATE TABLE TVENDAS (
DOCUMENTO CHAR(3),
NUMERO VARCHAR(6),
TIPOVENDA INTEGER,
DATA DATE,
NUMEMPRESA CHAR(1),
NUMCFOP CHAR(4),
CONF T_YESNO /* CHAR(1) */,
PARCELA INTEGER,
DTENTREGA DATE,
QTDNOTA FLOAT,
QTDENTR FLOAT,
CUPOM VARCHAR(6),
PAGAMENTO INTEGER,
NUMOCCURSITEM INTEGER,
CLIENTE INTEGER,
VENDEDOR INTEGER,
DESCONTO DOM_VALOR /* DECIMAL(15,2) */,
VRLDESCONTO DOM_VALOR /* DECIMAL(15,2) */,
TROCO DOM_VALOR /* DECIMAL(15,2) */,
RECEBIDO DOM_VALOR /* DECIMAL(15,2) */,
VALOR DOM_VALOR /* DECIMAL(15,2) */,
TOTAL DOM_VALOR /* DECIMAL(15,2) */,
EMDINHEIRO DOM_VALOR /* DECIMAL(15,2) */,
EMCHEQUE DOM_VALOR /* DECIMAL(15,2) */,
EMCARTAO DOM_VALOR /* DECIMAL(15,2) */,
EMTICKET DOM_VALOR /* DECIMAL(15,2) */
);
Chave Primaria CODIGO
CREATE GENERATOR "GEN_TITEMVEN_CODIGO";
CREATE TABLE TITEMVEN (
CODIGO INTEGER,
ITEM INTEGER,
DOCUMENTO CHAR(3),
NUMERO VARCHAR(6),
CODPRODUTO FLOAT,
QUANTIDADE FLOAT,
DATA DATE,
OBS VARCHAR(25),
DESCRPRODUTO VARCHAR(50),
CONF FLOAT,
DESCONTO INTEGER,
PRODUTO2 VARCHAR(15),
CUPOM VARCHAR(6),
NUMNOTA INTEGER,
TOTAL DOM_VALOR /* DECIMAL(15,2) */,
CUSTO DOM_VALOR /* DECIMAL(15,2) */,
VLRDESCONTO DOM_VALOR /* DECIMAL(15,2) */
);
vlw;
GOSTEI 0
Marcos Roberto
29/08/2010
Eriley
segue;
procedure TFrmVenda.EditNumeroExit(Sender: TObject);
Var
M:String;
R:String;
VarArrayOF :array[1..2] of string;
begin
dm.TableVendaNUMERO.Value := Zeros(dm.TableVendaNUMERO.Value,6); ///preenche zeros a esquerda
dm.TableVenda.IndexName := 'IDX_DOC';
With dm do
Begin
If TableVenda.FindKey([TableVendaDocumento.value,TableVendaNumero.value]) then
Begin
showmessage('ja existe');
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
showmessage('Nova Venda');
venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
TableVendaData.Value:=Date;
Db1.SetFocus;
end;
end;
end;
Grato;
segue;
procedure TFrmVenda.EditNumeroExit(Sender: TObject);
Var
M:String;
R:String;
VarArrayOF :array[1..2] of string;
begin
dm.TableVendaNUMERO.Value := Zeros(dm.TableVendaNUMERO.Value,6); ///preenche zeros a esquerda
dm.TableVenda.IndexName := 'IDX_DOC';
With dm do
Begin
If TableVenda.FindKey([TableVendaDocumento.value,TableVendaNumero.value]) then
Begin
showmessage('ja existe');
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
showmessage('Nova Venda');
venda(Db1,Db2,Db3,EditDocumento,EditNumero,Editdata,DbGridVenda);
TableVendaData.Value:=Date;
Db1.SetFocus;
end;
end;
end;
Grato;
GOSTEI 0
Eriley Barbosa
29/08/2010
Você conseguiu resolver isso?
GOSTEI 0
Marcos Roberto
29/08/2010
Eriley
Resolvi com o locate conforme vc enviou.
Preciso dar como "Resolvido" este tópico e não estou conseguindo.
Valeu pela Ajuda
GOSTEI 0