Ajuda em montar código
O código, se possível, seria para reconhecer se vai dar o erro, se sim, pegaria o último valor da tabela e adicionaria 1 e gravaria. Na internet achei esse código e tentei coloca-lo funcional para mim, mas dá erro de compatibilidade entre String e Integer já que o campo de código é alfanumerico.
try dm01.tbl_servico.Post; except on E:EDBEngineError do if E.Errors[0].ErrorCode = 9729 then dm01.tbl_servicoOS_COD.AsInteger := dm01.tbl_servicoOS_COD.AsInteger + 1; end;
Alguém pode me ajudar?
Carlos Magno
Respostas
Luiz Menin
26/11/2012
Adicione um TQuery.
SQLQuery.Close;
SQLQuery.SQL.Clear;
SQLQuery.SQL.Add('SELECT MAX(CODIGO) AS TOTAL FROM TABELA');
SQLQuery.ExecSQL();
SQLQuery.Open;
iMaxCod := SQLQuery.FieldByName('TOTAL').AsInteger + 1;
Atribui o valor da variavel criada (iMaxCod) ao campo código.
Espero ter ajudado.
Carlos Magno
26/11/2012
var codi:String[6]; begin dm01.tbl_servaux.Last; dm01.tbl_servicoOS_COD.AsString := inttostr(dm01.tbl_servauxOS_COD.AsInteger + 1); while Length(dm01.tbl_servicoOS_COD.AsString) <6 do codi:='0' + dm01.tbl_servicoOS_COD.AsString; dm01.tbl_servico.Post;
Luiz Menin
26/11/2012
Luiz Menin
26/11/2012
Carlos Magno
26/11/2012
Claudia Nogueira
26/11/2012
codi := dm01.tbl_servicoOS_COD.AsString; while Length(codi ) <6 do codi:='0' + dm01.tbl_servicoOS_COD.AsString;
var codi:String[6]; begin dm01.tbl_servaux.Last; dm01.tbl_servicoOS_COD.AsString := inttostr(dm01.tbl_servauxOS_COD.AsInteger + 1); while Length(dm01.tbl_servicoOS_COD.AsString) <6 do codi:='0' + dm01.tbl_servicoOS_COD.AsString; dm01.tbl_servico.Post;
Carlos Bernardo
26/11/2012
try dm01.tbl_servico.Post; except on E:EDBEngineError do if E.Errors[0].ErrorCode = 9729 then dm01.tbl_servicoOS_COD.AsInteger := dm01.tbl_servicoOS_COD.AsInteger + 1; end;
Amigo vamos tentar assim :
Cria uma funcao que retorne o proximo numero livre...
function retorna_maxCodigo : string;
var
QRY :TQuery;
begin
Qry := TQuery.Create(self);
with qry do
TRY
DatabaseName := SEU_ALIAS;
sql.Add('Select max(OS_COD) as CODMAX from nomedatabela');
Open;
Result := formatfloat('000000',Qry.FieldByName('CODMAX').Asfloat + 1);
FINALLY
QRY.free;
END;
end;antes de dar o POST vc usa assim
dm01.tbl_servicoOS_COD.AsString := retorna_maxCodigo;
dm01.tbl_servicos.POST;
A unit DBTables, tem que estar declarada na clausula Uses
Alisson Santos
26/11/2012
Se ele for campo inteiro como creio que seja ele não vai gravar os zeros na frente então ao invés de ficar 000123 ele vai aparecer apenas o 123, para que ele apareça os zeros na frente o campo tem que ser string.
Da maneira que nosso amigo acima está informando não precisa colocar os zeros e sim apenas trazer como resultado o campo adicionando +1.
Carlos Magno
26/11/2012
Qry := TQuery.Create(self);
Erro reportado: Undeclared indentifier: 'self';
Carlos Magno
26/11/2012
Carlos Magno
26/11/2012
Como faço para adicionar os zeros?
Segue o código, favor verificar se esta certo:
dm01.qr_servcodMAXOFOS_COD.AsString; dm01.tbl_servicoOS_COD.AsString := IntToStr(dm01.qr_servcodMAXOFOS_COD.AsInteger + 1); dm01.tbl_servico.Post;
William
26/11/2012
dm01.tbl_servicoOS_COD.AsString := FormatFloat('0000', dm01.qr_servcodMAXOFOS_COD.AsInteger + 1);
Carlos Bernardo
26/11/2012
troca essa linha Qry := TQuery.Create(self);
por essa Qry := TQuery.Create(nil);
Carlos Magno
26/11/2012
Assim que concluir os testes eu retorno para dizer se deu certo ou não.
Carlos Magno
26/11/2012
Carlos Magno
26/11/2012
Carlos Magno
26/11/2012
Luiz Menin
26/11/2012
Carlos Magno
26/11/2012
dm01.qr_servcod.Open; //abre a query
dm01.qr_servcod.Refresh; //dá um refresh para buscar o último número
dm01.qr_servcodMAXOFOS_COD.AsString;
dm01.tbl_servicoOS_COD.AsString := FormatFloat('000000',dm01.qr_servcodMAXOFOS_COD.AsInteger + 1); //adiciona mais 1 ao último número
dm01.tbl_servico.Post; //grava
dm01.qr_servcod.Close; //fecha a query
Luiz Menin
26/11/2012
var
iCont : Integer;
begin
dm01.qr_servcod.Open; //abre a query
dm01.qr_servcod.ExecSQL();
iCont := dm01.qr_servcodMAXOFOS_COD.AsInteger + 1;
dm01.tbl_servicoOS_COD.AsString := FormatFloat('000000', iCont); //adiciona mais 1 ao último número
dm01.tbl_servico.Post; //grava
dm01.qr_servcod.Close; //fecha a query
end;
Carlos Magno
26/11/2012
Cannot perform this operation on an open dataset
e não gravou nada
Luiz Menin
26/11/2012
dm01.qr_servcod.Close; dm01.qr_servcod.ExecSQL(); dm01.qr_servcod.Open;
Carlos Magno
26/11/2012
Luiz Menin
26/11/2012
Carlos Magno
26/11/2012
Luiz Menin
26/11/2012
Carlos Bernardo
26/11/2012
dm01.tbl_servicoOS_COD.AsString := FormatFloat('000000', dm01.qr_servcodMAXOFOS_COD.AsInteger + 1);
Deve evitar esse erro...
Carlos Magno
26/11/2012
Var Cod:String[6]; begin dm01.tbl_servico.open; if dm01.tbl_servico.IsEmpty then cod:='000001' else begin dm01.tbl_servico.Last; Cod:=IntToStr(dm01.tbl_servicoOS_COD.AsInteger + 1); while Length(Cod)<6 do cod:='0'+ Cod; end; dm01.tbl_servico.Append; dm01.tbl_servicoOS_COD.Value:=Cod; end;
Carlos...vou tentar sua forma, mas não entendi o porque colocar no evento BeforePost se o código acima está justamente antes de concluir o Post
Fico no aguardo....
Luiz Menin
26/11/2012
Não sei como funciona tua aplicação, mas acredito que só o Open e o Append seja suficiente;
dm01.tbl_servico.Open; dm01.tbl_servico.Append;
Se você utiliza essa formatação no campo código, então utilize somente no botão salvar.
Carlos Magno
26/11/2012
Aproveitando, como faço para, no botão salvar e após aplicar o Post, dar um refresh na tabela?
Luiz Menin
26/11/2012
Após o post deve ser atualizada a tabela.
dm01.tbl_servico.Refresh;
Carlos Magno
26/11/2012
Gilvanio Gonçalves
26/11/2012
campo codigo de sua tabela alphanumerico, vc deseja que contenha zeros antes do codigo certo;
supondo que vc vai usar o codigo em um botão com o nome novo ou incluir ok?
procedure TForm1.Button1Click(Sender: TObject);
Var
Cod:String[5];{ cria uma variável para incrementar}
begin
dm01.tbl_servico.Open;
if dm01.tbl_servico.IsEmpty { verifica se a tabela está vazia}
then cod:='00001'
else
begin
dm01.tbl_servico.Last; { posiciona no último registro da tabela}
Cod:=IntToStr(dm01.tbl_servicoOS_COD.AsInteger + 1); { pega o valor do último OS_Cod, que é string, considera- o como inteiro, adiciona mais 1 e por fim, armazena na variável Cod invertendo de inteiro para string}
while Length(Cod)<5 do {enquanto o tamanho de cod for menor que 5, acrescenta.
cod:='0'+ Cod; // um zero a esquerda de cod}
end;
dm01.tbl_servico.Append; {inclui um registro em branco no final da tabela }
dm01.tbl_servicoOS_COD.Value:=Cod;
end;no botão gravar do mesmo form este codigo:
dm01.tbl_servico.Post;
caso precise atualizar os dados para uma grid no caso, apos o comando post use o refresh.
exemplo:
dm01.tbl_servico.Post;
dm01.tbl_servico.Refresh;tendo um botão para cancelar :
dm01.tbl_servico.Cancel;
no evento onclose de seu form :
dm01.tbl_servico.Cancel dm01.tbl_servico.Close;
agora quanto ao erro Key Violation, que é violação na tabela, toda tabela em banco paradox tem que ter
um campo com chave primária obrigatório.
vc pode criar um campo com o nome (cod) type + de autoincremento e em key * marcando como campo primário.
ficando assim este campo como chave primária que é obrigatorio ter em tabela paradox.
caso deseja vc pode colocar o campo OS_COD como primário evita-se dados repeditos. isto fica ao seu critério.
erro de access violation, quando esta tentando gravar um registro com o mesmo codigo na mesma tabela.
bém é isto, pra vc que usa paradox pode usar os codigos sem medo de errar, caso vc tenha outras mensagens de erros
post que iremos te ajudar.
quanto ao uso de query,sql, pelo que li nos exemplos dos colegas e as suas tentativas sem entender o que esta fazendo,
aconselho a vc usar o exemplo como passei que usa-se tabela, depois vc estuda a fundo o uso de query, sql, try, except etc.
at+
Carlos Magno
26/11/2012
O campo OS_COD já esta como primário. O que eu busco é solucionar o problema de duas maquinas utilizarem o mesmo banco em rede simultaneamente e, caso as duas maquinas forem iniciar um cadastro ao mesmo tempo, não venha dar esse erro de KEY VIOLATION.
Um sistema que a loja já usa a algum tempo, observei varias vezes que, ao se iniciar um cadastro em uma das máquinas e a outra também iniciar, gera o mesmo código, mas ao salvar, a máquina que clicou no botão salvar primeiro grava os dados com aquele código e a outra gera um novo número consecutivo ao salvo pela máquina anterior.
Eu até podia pedir ajuda o programador que fez esse sistema pois ele é da minha cidade, o problema é que já faz uns 4 meses que o homem desapareceu do mapa e ninguém consegue contacta-lo.
Gilvanio Gonçalves
26/11/2012
O campo OS_COD já esta como primário. O que eu busco é solucionar o problema de duas maquinas utilizarem o mesmo banco em rede simultaneamente e, caso as duas maquinas forem iniciar um cadastro ao mesmo tempo, não venha dar esse erro de KEY VIOLATION.
Um sistema que a loja já usa a algum tempo, observei varias vezes que, ao se iniciar um cadastro em uma das máquinas e a outra também iniciar, gera o mesmo código, mas ao salvar, a máquina que clicou no botão salvar primeiro grava os dados com aquele código e a outra gera um novo número consecutivo ao salvo pela máquina anterior.
Eu até podia pedir ajuda o programador que fez esse sistema pois ele é da minha cidade, o problema é que já faz uns 4 meses que o homem desapareceu do mapa e ninguém consegue contacta-lo.
o que vc citou no que vc observou esta errado em questão de visualização para o usuario, dois micros
mostrando que a OS que sera gravada é com o codigo 010,e claro que quem gravar primeiro, gravara
010, e esta que gravou ao clicar no botão novo o proximo pra ele será 011, o que este programador fez
é uma rotina que verifica na tabela qual é o ultimo codigo da tabela para poder gravar o proximo
acrescentando mais 1. assim o segundo usuario tem no form o codigo 010, somente como exibição,
mas ao gravar, gravará o 011, pois o anterior gravou o 010, erro somente na exibição do novo
codigo, mas gravação correta, sem key violation.
Quanto ao key violation como te disse é devido estar tentando gravar o mesmo codigo(duplicidade)
na mesma tabela, justamente por ser primario, onde não aceita duplicidade, seria assim :micro 1 ,
esta para gravar o codigo 005, o micro 2 esta no mesmo instante a gravar o mesmo codigo.
crie uma campo em sua tabela com o nome cod type autoincremento e primario.
desmarque a opção * primario do campo OS_COD, assim vc eliminrá o erro key violation.
observe que no codigo que te passei o codigo que será gravado na tabela fica reservado
em uma variavel, ele só sera gravado ao clicar no botão gravar.
sendo assim se um usuario uniciar uma nova os com o codigo 0007 e outro usuario iniciar
uma nova os ao mesmo tempo, todos dois terá o codigo 0007, devido o codigo estar ainda em uma variavel
e não na tabela, provocando o key violation para o ultimo usuario que clicar em gravar, pois como pode observar
todos dois irão gravar o codigo 0007, tendo seu campo OS_COD como primário, que é justamente para evitar
duplicidade.
e vc tirando ele de primario o que vai acontecer , gravação de registro com codigo em duplicidade, sem key violation.
o que pode ser feito é mudar a rotina para reservar o codigo na tabela.
se micro1 iniciou uma nova OS e o ultimo codigo da tabela gravado é 0006, no form exibirá 0007
como sendo o proximo, e na tabela no campo codigo já conterá o codigo 0007, somente o codigo, os outros dados
somente ao clicar em gravar, para caso o usuario cancele a OS antes de gravar o codigo 0007 será removido da tabela.
desta forma se micro1 iniciou uma nova Os, qualquer outros micros que der inicio a uma nova os ao mesmo tempo,
não irá gravar codigo em duplicidade.
espero que tenha entendido.
caso não saiba mudar a rotina, avise que tentaremos te ajudar.
at+
Gilvanio Gonçalves
26/11/2012
no codigo que te passei(rotina).
vai ter o mesmo procedimento que ve observou nos micros.
vc desmarcaando o campo OS_COD como primario. e criando uma campo cod type autoincremento e * primario
ele só servira para que a tabela contenha um campo primario, como disse em paradox
é nescessario em todas as tabelas um campo primario.
desmarcando o campo OS_COD como primario não haverá erro de key violation.
mas a exibição do codigo do form sera 0005, no micro 1 e 0005 no micro2 ou 3 etc.
sendo que quem gravar primeiro e clicar no botão novo terá o codigo 0006 como o proximo.
a possibilidade de duplicidade é praticamente impossivel, pois sempre um usuario dará o comando
de gravar antes um do outro.
assim, vc pode usar a rotina que te passei que funcionará como vc observou no sistema
do outro programador.
at+
Carlos Magno
26/11/2012
Gilvanio Gonçalves
26/11/2012
se voce deseja como vi no primeiro post seu que OS_COD contenha zeros a esquerda
e seguindo o exemplo que te passei ele, não pode ser autoincremento amigo,
pois no codigo a rotina é que faz ele ser incrementado sempre com mais 1
e ele dever ser alphanumerico mesmo, devido vc querer zeros a esquerda do codigo
e não pode ser primario,
{crie um campo primario e autoincremento em sua tabela como já citei, e pronto}
seu sistema funcionará como o do outro programador.
bém como vc mudou o campo para alphanumerico, refaça dele ele no fields da taabela
e faça um novo add. dele, para que sue sistema atulize ele para alphanumerico.
campo autoicremento, é incrementado automaticamente pela tabela
ao receber gravação de um registro, é automatico, se deixar assim
vc Não poderá usar o codigo que te passei.
e ele sendo primario, não aceita duplicidade.
vc pode até usar como autoincremento desde que não seja primario, lembrando
que assim o codigo que te passei não pode ser usado.
Carlos Magno
26/11/2012
1 - Isso vai resolver o problema de KEY VIOLATION?
2 - Posso apenas adicionar um campo na tabela para o autoincremento e coloca-lo como primário?
3 - Caso não, como passar os dados já existentes na tabela para a nova tabela criada?