Ir para conteúdo
Fórum Script Brasil
  • 0

Duvidas com campos obrigatorios


claudyo

Pergunta

Bom pessoal, to com um problema em um form de cadastro, alguns campos são obrigatorios outros não ate ai td bem, mais tenho dois campos com uma peculiaridade, os campos de telefone, só um é obrigatorio mas pode ser qualker um dos dois, a consulta a ser feita posteriormente vai ser pelo n° de telefone então obrigatoriamente um deles tem q ser preechidos. alguém tem alguma ideia de como se faz isso, tipo o sistema me retorna uma mens caso os dois estejam em branco, e gravar o registo caso um deles esteja preenchido. Se alguém puder ajudar agradeço

Abraço a todos

Link para o comentário
Compartilhar em outros sites

24 respostass a esta questão

Posts Recomendados

  • 0

Bem, você pode testar no evento onExit dos campos para ver se estão preenchidos. Pode testar também em algum lugar onde salva as alterações, geralmente um botão.

Tipo assim:

if Length(Trim(mskedtTelefone.Text)) < 10 then

ShowMessage('Telefone não preenchido ou inválido!');

isso considerando um campo tipo maskedit com a seguinte máscara: (99)9999-9999.

Também pode fazer uma coisa mais segura ainda, colocando not null no campo lá no banco de dados e tratar isso no evento PostError no clientdataset dentro do datamodule, assim:

try

if E is EDatabaseError then

begin

if (pos('violates not-null', E.Message) <> 0) or (pos('must have a value', E.Message) <> 0) then

begin

ShowMessage('Campo Obrigatório não foi preenchido');

end

É isso. Espero ter ajudado.

Sergio

Link para o comentário
Compartilhar em outros sites

  • 0

Bem meu problema continua, me eskeci de menciona um problema, eu não consigo fazer inserao de dados se houver um campo em branco, mesmo configurando o campo da tabela no banco(Access2007) como não requerido na hora de fazer inserçao da erro, pra outros campos q tenho no meu form q não são obrigatorios eu já achei uma forma de contorna esse problema, mas pra esses dois em kestao é um pouco mais complicado, pois um deles é obrigatorios podendo ser qualker um deles, então preciso descobrir uma forma pra q quando um desses campos estiver preenchido o sistema ignore o outro em branco

Se mais alguém tiver alguma ideia é sempre bem vinda...fico aguardando

Abraço a todos

Link para o comentário
Compartilhar em outros sites

  • 0
Bem meu problema continua, me eskeci de menciona um problema,
sempre tem um porém... :D

claudyo, faltou também informar que componente você está utilizando para o acesso.

eu não consigo fazer inserao de dados se houver um campo em branco, mesmo configurando o campo da tabela no banco(Access2007) como não requerido na hora de fazer inserçao da erro,
por acaso você adicionou os campos (fields) ao dataset antes de fazer esta alteração no banco?

Se sim, então, acesse os fields (na janela object inspector) e defina a propriedade Required deles para False.

então preciso descobrir uma forma pra q quando um desses campos estiver preenchido o sistema ignore o outro em branco

Se mais alguém tiver alguma ideia é sempre bem vinda...

como você não poderá manter os dois campos como obrigatório, então prossivelmente você não terá como usar o OnPostError sugerido pelo colega sllc. Então, a primeira abordagem (testar no botão de gravação) seria mais aplicável.

Há ainda a possibilidade de você fazer esta validação no evento OnBeforePost do dataset - e neste caso, você testaria o campo do dataset (não o Edit ou maskedit...)

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Bem meu problema continua, me eskeci de menciona um problema,
sempre tem um porém... :D

claudyo, faltou também informar que componente você está utilizando para o acesso.

como você não poderá manter os dois campos como obrigatório, então prossivelmente você não terá como usar o OnPostError sugerido pelo colega sllc. Então, a primeira abordagem (testar no botão de gravação) seria mais aplicável.

Há ainda a possibilidade de você fazer esta validação no evento OnBeforePost do dataset - e neste caso, você testaria o campo do dataset (não o Edit ou maskedit...)

Abraços

Obrigado Micheus pela atençao.

Bom vamos la qt ao componente q uso pra conexao é um ADOconection e uma ADOQuery já add os fields e já tava todos com required false e o erro continua, o que devo fazer?? Tentar algum outro tipo de component de conexao ou existe alguma outra propriedade q devo alterar pra resolver isso???Qt a mens de erro q me retorna é exatamente essa "[Microsoft][Driver ODBC microsoft Access]Valor de precisao invalido".Sabe me dize porque isso ocorre???

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Bom vamos la qt ao componente q uso pra conexao é um ADOconection e uma ADOQuery já add os fields e já tava todos com required false e o erro continua, o que devo fazer?? Tentar algum outro tipo de component de conexao ou existe alguma outra propriedade q devo alterar pra resolver isso???Qt a mens de erro q me retorna é exatamente essa "[Microsoft][Driver ODBC microsoft Access]Valor de precisao invalido".
claudyo, pela mensagem você está usando driver ODBC (eu costumo usar MS Jet). Voce não poderia configurar seu ADOConnection para utilizar JET no lugar de ODBC e então testar?

Voce está passando algum parâmetro nesta ADOQuery?

Veja estes posts:

Erro ao inserir dados via ODBC e tableadapter -Valor de precisão inválido

General Sql Error

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

não consegui resolve o problema exatamente como eu keria segui as instruçoes do Micheus, colocando um driver msjet mas infelizmente deu o mesmo erro,mas achei uma soluçao meio tosca, mas na falta de outra..... Os campos não podem estar vazios tipo('') mas se eu trocar o valor pra um texto em branco(' ') ai eu consigo fazer inserçao o inconveniente é q tenho q mudar os tipos dos campos todos pra texto no banco pra não da imcopatibilidade com os campos numericos.Mas resolveu meu problema.

Obrigado a todos pela atençao e continuo contando com ajuda de todos já q vou precisar pra termina meu sistema.

Abraço a todos

Link para o comentário
Compartilhar em outros sites

  • 0
Os campos não podem estar vazios tipo('') mas se eu trocar o valor pra um texto em branco(' ') ai eu consigo fazer inserçao
claudyo, dê uma olhada se na estrutura das suas tabelas no MSAcces e veja se estes campos não estariam com a propriedade Permitir comprimento zero = Não - isto se encaixaria como motivo para esta sua solução funcionar, bem como o erro apresentado - experimente.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
olhei no meu banco os campos e todos permitem comprimento zero, se sabe alguma outra propriedade q possa ser mudada seria uma ajuda muito bem vinda..
claudyo, como você está fazendo esta inserção. Voce está utilizando componentes data-aware ligados ao dataset, ou está usando queries (com insert) parametrizadas?

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
olhei no meu banco os campos e todos permitem comprimento zero, se sabe alguma outra propriedade q possa ser mudada seria uma ajuda muito bem vinda..
claudyo, como você está fazendo esta inserção. Voce está utilizando componentes data-aware ligados ao dataset, ou está usando queries (com insert) parametrizadas?

Abraços

Eu uso queries com parametros, isso pode da problema???

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Eu uso queries com parametros, isso pode da problema???
claudyo, não deveria, mas diante do que você anda experimentando...

Apesar de talvez ficar um pouco trabalhoso (não sei quantos parâmetros você passa), ao invés de atribuir o valor de um Edit.Text vazio. Teste o valor antes de atribuir ao parâmetro e, se estiver em branco, não atribua ao parâmetro:

...
if Edit2.Text <> '' then
  ADOQuery1.Parameters.ParamByName('Fone').Value := Edit2.Text;
...
ou esta outra variante, onde garantimos que o valor do parâmetro está nulo:
...
if Edit2.Text <> '' then
  ADOQuery1.Parameters.ParamByName('Fone').Value := Edit2.Text
else
  ADOQuery1.Parameters.ParamByName('Fone').Value := null;
...

da forma como está agora, aparentemente os inserts estão sendo montados (pelo driver) mais ou menos assim:

INSERT Pessoa ('Codigo', 'Nome', 'Fone') VALUES (125, 'Pedro Amaro', '')

a idéia é forçar que os campos não informados sejam passados como nulos, ou seja, obter algo assim:

INSERT Pessoa ('Codigo', 'Nome', 'Fone') VALUES (125, 'Pedro Amaro', NULL)

Veja o que acontece.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Eu aki de novo Micheus hehe....

cara testei aki sua sujestao, fiz esse teste num outro form de cadastro de produto q vai te também dois campos onde só um é obrigatorio, podendo ser qualker um deles segue o codigo

procedure TfrmCadProd.gravadados;
begin
    with dm.qryCadProd do
   begin
    sql.Text:='insert into produto(nome, categoria, tamanho, volume, valor,)'+
    'Values (:pNome, :pCategoria, :pTamanho,:pValor,:pVolume, :pValor)';
    Parameters.ParamByName('pNome').Value:=edtNome.Text;
    Parameters.ParamByName('pCategoria').Value:=cboCategoria.KeyValue;
    if edtTamanho.text <> '' then
    Parameters.ParamByName('pTamanho').Value:=edtTamanho.text
    else
    Parameters.ParamByName('pTamanho').Value:= null;
    if edtVolume.text <> '' then
    Parameters.ParamByName('pVolume').Value:=edtVolume.text
    else
    Parameters.ParamByName('pVolume').Value:= null;
    Parameters.ParamByName('pValor').Value:=strTocurr(edtValor.text);
    Prepared:=true;
    ExecSql();
   end;
end;
procedure TfrmCadProd.btnSalvarClick(Sender: TObject);
var i : integer;
begin
     for i:=0 to componentCount-1 do
     begin
         if (TEdit(components[i]).Tag=1) and (TEdit(components[i]).text='') then
         begin
             application.MessageBox('Existem Campos Obrigatórios em Branco','Aviso',mb_iconInformation+mb_okcancel);
                TEdit(components[i]).SetFocus;
                exit;
         end;
     end;
     if (edtTamanho.Text='') and (edtVolume.Text='') then
          begin
           application.MessageBox('Informe o Tamanho ou Volume do Produto','Aviso',mb_iconInformation+mb_okcancel);
                edtTamanho.SetFocus;
                exit;
          end;
     gravadados;
end;

end.

Ai me retorna o seguinte erro "Objeto parameter definido incorretamente, as informaçoes são incorretas ou inconsistentes". Sabe porque isso ocorre?

Agradeço a atençao

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Ai me retorna o seguinte erro "Objeto parameter definido incorretamente, as informaçoes são incorretas ou inconsistentes". Sabe porque isso ocorre?
claudyo, dê uma olhada nesta linha de seu código:

sql.Text:='insert into produto(nome, categoria, tamanho, volume, valor,)'+

Conseguiu ver aquela "," perdida no final da instrução?

Hoje encontrei na mina pasta de testes, um código que tinha relação com sua dúvida inicial. Voltando aos meus posts encontrei este: Valor de precisao invalido (05/04/2008), onde havia sugerido uma procedure para a inicialização dos parâmetro procedure InitParam(Param :TParameter; Value :Variant); - Familiar?!

Me chateia o fato de termos discutido aqui, uma questão que já foi inicialmente tratada lá, sendo que segui tentando ajudar mas fiquei sem um retorno. É o tipo de coisa que desanima. <_<

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Claudio --

Ola micheus, te peço desculpas pelo q aconteceu, tive um problema particular e acabei deixando algumas coisas de lado inclusive esse projeto, sei q não justifica mas fica ai meu pedido de desculpas.

Qt a procedure q você havia me sugerido (InitParam) eu já tinha tentado mas ocorre o sseguinte. Se eu tenta compila dessa forma( Param.Value := Null) gera o erro ( identificador não declarado "Null"), se eu tenta assim ( Param.Value := 'Null') eu ate consigo mas se tenta chama essa procedure da imcompatibilidade de tipos(procedure e parameter) onde ta meu erro??

procedure Tdm.InitParam(Param: TParameter; Value: Variant);
begin
    if trim(Value)='' then
    Param.Value := 'Null'
    else
    Param.Value:=Value;
end;
Chamando a procedure
procedure TfrmCadProd.gravadados;
begin
    with dm.qryCadProd do
   begin
    sql.Text:='insert into produto(nome, categoria, tamanho, volume, valor)'+
    'Values (:pNome, :pCategoria, :pTamanho,:pValor,:pVolume, :pValor)';
    dm.initParam(Parameters.ParamByName('pNome').Value:=edtNome.Text;)
    dm.initParam(Parameters.ParamByName('pCategoria').Value:=cboCategoria.KeyValue;)
    dm.initParam(Parameters.ParamByName('pTamanho').Value:=edtTamanho.text;)
    dm.initParam(Parameters.ParamByName('pVolume').Value:=edtVolume.text;)
    dm.initParam(Parameters.ParamByName('pValor').Value:=strTocurr(edtValor.text);
    Prepared:=true;
    ExecSql();
   end;

essa procedure declarei no data module

Onde ta meu erro??

Link para o comentário
Compartilhar em outros sites

  • 0
Ola micheus, te peço desculpas pelo q aconteceu, tive um problema particular e acabei deixando algumas coisas de lado inclusive esse projeto, sei q não justifica mas fica ai meu pedido de desculpas.
Tudo bem, não esquenta não. Eu nem tenho mesmo que cobrar nada - eu é que tenho que me desculpar.

É que se você tivesse continuado daquele post, ao invés de ter aberto este, já teríamos ganho um bom tempo e eu poderia estar dando atenção a outro colega.

Qt a procedure q você havia me sugerido (InitParam) eu já tinha tentado mas ocorre o sseguinte. Se eu tenta compila dessa forma( Param.Value := Null) gera o erro ( identificador não declarado "Null"), se eu tenta assim ( Param.Value := 'Null') eu ate consigo mas se tenta chama essa procedure da imcompatibilidade de tipos(procedure e parameter) onde ta meu erro??
o erro está em não interpretar a mensagem. Veja que ela diz "identificador não declarado" e tendo eu posto ele naquela procedure, por certo que existe em algum lugar a declaração dele. Se você teclar F1 sobre ele, verá que está declarado na unit Variants que é naturalmente declarada na unit do projeto que tem a declaração de um form, mas não na de um datamodule. Logo, basta que você inclua ela na cláusula uses do seu datamodule.

E lembre-se, é NULL sem as áspas - com as aspas, você está passando uma string com o texto 'null'.

Veja como vai ficar.

Abraços

Editado por Micheus
Link para o comentário
Compartilhar em outros sites

  • 0
...fiz o que me sugeriu só q agora da erro de imcompatibilidade entre TParameter e Procedure e na frente disso aparece untyped pointer ou untyped parameter.
claudyo, mensagem estranha...

antes de mais nada, encontrei outro problema com com o seu código, além daquele envolvendo a vírgula. Olhando ele mais uma vez, observei que você informa no insert 5 colunas, mas passa 6 valores (values). :huh:

insert into produto(nome, categoria, tamanho, volume, valor)

Values (:pNome, :pCategoria, :pTamanho,:pValor,:pVolume, :pValor)

veja que tem um parâmetro pvalor sobrando...

Faça este ajuste e verifique o resultado. Caso este erro persista, você poderia ainda tentar informar em run-time o tipo de dados dos parâmetros - isto normalmente não é necessário, mas...

Eu não sou muito favorável a este médoto de acesso aos parâmetros ou campos (usar o array), porque dá margens a mudanças de ordem deles ou acrécimos, passarem despercebido e gerarem problemas futuros. Mas como a informação do SQL está sendo preparada em run-time e estamos vendo exatamente o que haverá no componente quando ativarmos ele, neste caso, a simplificação me parece mais vantajosa. Assim, sendo, para informar o tipo do parâmetro usamos a propriedade DataType conforme o caso - confira se usei os tipos certos (outros tipos, veja no help):

...
  Parameters[0].DataType := ftString;   // pNome
  Parameters[1].DataType := ftInteger;  // pCategoria
  Parameters[2].DataType := ftString;   // pTamanho
  Parameters[3].DataType := ftString;   // pVolume
  Parameters[4].DataType := ftFloat;    // pValor

  dm.initParam(Parameters.ParamByName('pNome').Value:=edtNome.Text;)
  dm.initParam(Parameters.ParamByName('pCategoria').Value:=cboCategoria.KeyValue;)
  dm.initParam(Parameters.ParamByName('pTamanho').Value:=edtTamanho.text;)
  dm.initParam(Parameters.ParamByName('pVolume').Value:=edtVolume.text;)
  dm.initParam(Parameters.ParamByName('pValor').Value:=strTocurr(edtValor.text);
...

obs: fazendo uma verificação em design-time, observei que sempre que tentava definir como ftCurrency, ele automaticamente era substituído por ftFloat.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus, o que acontece é q esse erro q te falei(imcompatibilidade entre TParameter e Procedure untyped pointer ou untyped parameter) aparece qd tento roda o programa(F9). não compila se eu chama a funçao InitParam, tive q tira ela pra roda. Agora um outro probleminha q eu acho q é simples, como se verifica se um DbLookupcombobox ta em branco eu até tinha feito e tinha dado certo mais deu um problema aki e não deu pra salva agora to tentando faze e não da certo. Faço assim

f varisnull (cboCategoria.KeyValue) then
            begin
               Application.Messagebox('Escolha uma Categoria Para o Produto','Aviso',mb_IconInformation+mb_ok);
               cboCategoria.SetFocus;
               exit;
            end;

e já tentei também assim

if (cboCategoria.kevalue:= null then

Mas em ambos os casos parece q essa linha é ignorada e da erro no banco por não ter uma categoria selecionada.

Como faço isso??

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Micheus, o que acontece é q esse erro q te falei(imcompatibilidade entre TParameter e Procedure untyped pointer ou untyped parameter) aparece qd tento roda o programa(F9). não compila se eu chama a funçao InitParam, tive q tira ela pra roda.
claudyo, eu devo estar ficando cego e você muito desatento.

Preste atenção ao seu código no post#16 (e que acabei copiando, ajustando outras coisas e não vi a káka que tinha nele. Vou por sem a tag para poder chamar a atenção ao que quero:

with dm.qryCadProd do

begin

sql.Text:='insert into produto(nome, categoria, tamanho, volume, valor)'+

'Values (:pNome, :pCategoria, :pTamanho,:pValor,:pVolume, :pValor)';

dm.initParam(Parameters.ParamByName('pNome').Value:=edtNome.Text;)

dm.initParam(Parameters.ParamByName('pCategoria').Value:=cboCategoria.KeyValue;)

dm.initParam(Parameters.ParamByName('pTamanho').Value:=edtTamanho.text;)

dm.initParam(Parameters.ParamByName('pVolume').Value:=edtVolume.text;)

dm.initParam(Parameters.ParamByName('pValor').Value:=strTocurr(edtValor.text);

Prepared:=true;

ExecSql();

end;

Conseguiu ver onde está o problema...

...e veja que InitParam deveria estar deste modo:

procedure Tdm.InitParam(Param: TParameter; Value: Variant);
begin
  if trim(Value)='' then
    Param.Value := Null
  else
    Param.Value:=Value;
end;
observe que a procedure deve receber dois parâmetros e note também de que tipo eles devem ser. estou postando ele devidamente corrigido aqui e, com certeza, erro de compilação não terá mais:
procedure TfrmCadProd.gravadados;
begin
  with dm.qryCadProd do
  begin
    sql.Text:='insert into produto(nome, categoria, tamanho, volume, valor)'+
              'Values (:pNome, :pCategoria, :pTamanho, pVolume, :pValor)';
    dm.initParam(Parameters.ParamByName('pNome'), edtNome.Text);
    dm.initParam(Parameters.ParamByName('pCategoria'), cboCategoria.KeyValue);
    dm.initParam(Parameters.ParamByName('pTamanho'), edtTamanho.text);
    dm.initParam(Parameters.ParamByName('pVolume'), edtVolume.text);
    dm.initParam(Parameters.ParamByName('pValor'), strTocurr(edtValor.text));
    Prepared := True;
    ExecSql;
  end;
end;
Agora um outro probleminha q eu acho q é simples, como se verifica se um DbLookupcombobox ta em branco eu até tinha feito e tinha dado certo mais deu um problema aki e não deu pra salva agora to tentando faze e não da certo. Faço assim
f varisnull (cboCategoria.KeyValue) then
begin
  Application.Messagebox('Escolha uma Categoria Para o Produto','Aviso',mb_IconInformation+mb_ok);
  cboCategoria.SetFocus;
  exit;
end;
experimente assim:
f VarIsNull(cboCategoria.KeyValue) or VarIsEmpty(cboCategoria.KeyValue) then
begin
  Application.Messagebox('Escolha uma Categoria Para o Produto','Aviso',mb_IconInformation+mb_ok);
  cboCategoria.SetFocus;
  exit;
end;

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Micheus, Infelizmente o erro persiste fiz como me sugeriu testei também fazendo algumas alteraçoes mas infelizmente o erro persiste, vou dar uma olhada em todo o codigo, revisar ele todo seguindo suas sugestoes pra ve se acho onde to errando e volto a postar resultados.

Origado pela atençao

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus, na query q uso pra inserir os dados coloquei na Propriedade Sql dela um 'Select * From Tabela', isso pode causar problema já q é uma query pra inserçao de dados e não de consulta?? Existe algum outro component pra inserir dados melhor q uma query?? porque depois de tantas tentativas começo a achar q essa query é q ta me dando problemas já q fiz td você me recomendou fazer e nada da certo.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0
na query q uso pra inserir os dados coloquei na Propriedade Sql dela um 'Select * From Tabela', isso pode causar problema já q é uma query pra inserçao de dados e não de consulta??
claudyo, você está dizendo que a query qryCadProd, contém uma instrução "select * ..." em design-time e depois você a reutiliza atribuindo? é isto?

Dependendo de que modo e quando você esteja usando a query com este select, pode até não haver problema, porque quando você atribui algo a sql.Text é como se o componente fosse reiniciado com os novos campos, parametros, ... (dependendo o caso)

Se for, porque você está usando deste modo então? você não está mesmo usando componentes data-awares (tipo TDBEdit, TDBComboBox,...)?

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Claudio --

Ola Micheus, enfim resolvi meu problema troquei meu adoQuery por um AdoTable e resolveu.É muito mais simples trabalha com AdoTable já q é só pra inserir dados

Só pra constar o codigo fivou assim

begin
   if not dm.tblCliente.active=true then
    dm.tblCliente.Active:=true;
    dm.tblCliente.Append;
    dm.tblClienteNome.Value:=edtNome.Text;
    dm.tblClienteRg.Value:=edtRg.text;
    dm.tblClienteCpf.Value:=edtCpf.Text;
    dm.tblClienteTelefoneRes.Value:=edtFone.text;
    dm.tblClienteTelefoneCel.Value:=edtCelular.text;
    dm.tblClienteLogradouro.Value:=edtLogradouro.Text;
    dm.tblClienteNumero.Value:=edtNumero.Text;
    dm.tblClienteComplemento.Value:=edtComplemento.Text;
    dm.tblClienteBairro.Value:=edtBairro.Text;
    dm.tblClienteCep.Value:=edtCep.Text;
    dm.tblCliente.Post;
end;

Obrigado pela atençao por todo esse tempo.

Grande abraço vlw

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...