deixar um campo com mascara aceitar branco????

Delphi

24/06/2005

Colegas..

Tenho um clientdataset com vários fields, e um deles é um campo data. Este campo tem máscar de data..

se o usuário inserir uma data e gravar no banco de dados e depois quiser deixá-la em branco dá erro na máscara..

Como faço para que este campo aceite valor em branco..

No banco de dados o campo não está configurado pára not null..

veja que se gravar a primeira vez em branco não dá erro..

Agradeço a atenção de todos


Cabelo

Cabelo

Curtidas 0

Respostas

Marco Salles

Marco Salles

24/06/2005

como esta sua mascara...


GOSTEI 0
Tnaires

Tnaires

24/06/2005

Olá
Já enfrentei esse problema. Tente o seguinte:
- escreva essa procedure no seu programa (acima da cláusula private):
procedure TFrmPadrao.EdtDataChange(Sender: TObject);
  var Edit: TDBEdit;
begin
  Edit := (Sender as TDBEDit);
  if (Edit.DataSource.DataSet.State in [dsInsert, dsEdit]) and (Edit.Text = ´  /  /    ´) then
    Edit.Field.Clear;
end;

- aponte essa procedure para o evento OnChange do TDBEdit associado ao seu campo data.
Vc pode colocar essa procedure no form padrão do seu sistema, e sair apontando os eventos dos DBEdits necessários nos forms filhos.
Não sei se há maneira mais simples, mas foi a maneira q eu encontrei.
Abraços

P.S. - a máscara q eu usei foi ´!99/99/9999;1; ´


GOSTEI 0
Cabelo

Cabelo

24/06/2005

[quote:6f4241a447=´Marco Salles´]como esta sua mascara...[/quote:6f4241a447]

!99/99/00;1;



Olá Já enfrentei esse problema. Tente o seguinte: - escreva essa procedure no seu programa (acima da cláusula private):
procedure TFrmPadrao.EdtDataChange(Sender: TObject);
  var Edit: TDBEdit;
begin
  Edit := (Sender as TDBEDit);
  if (Edit.DataSource.DataSet.State in [dsInsert, dsEdit]) and (Edit.Text = ´  /  /    ´) then
    Edit.Field.Clear;
end;
- aponte essa procedure para o evento OnChange do TDBEdit associado ao seu campo data. Vc pode colocar essa procedure no form padrão do seu sistema, e sair apontando os eventos dos DBEdits necessários nos forms filhos. Não sei se há maneira mais simples, mas foi a maneira q eu encontrei. Abraços P.S. - a máscara q eu usei foi ´!99/99/9999;1; ´


Colega.. mas estou usando um DBGrid e não um DBEdit, e esta rotina irá fazer a verificação todas as vezes que mexer no campo, o que perde e muita a performance quando estiver trabalhando on-line..

deve haver uma outra forma de resolver este problema..

mesmo assim muito obrigado..


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

!99/99/00;1;

Tente tirar os zeros


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

!99/99/00;1; Tente tirar os zeros


Talvez no seu caso não resolva... :cry: :cry: :cry:

Colega.. mas estou usando um DBGrid e não um DBEdit,


Bem sugiro que escreva o seguinte código no evento OnsetText DOCampo

Exemplo:
procedure TForm1.Table1DataSetText(Sender: TField; const Text: String);
begin
if Text =  ´  /  /  ´ then
  sender.clear
else
 Sender.AsDateTime:= StrToDate(Text);
end;


[b:8c53e5d6fb]p:s para a mascara ]!99/99/00;1;[/b:8c53e5d6fb]

Se funcionar ou parcialmente funcionar esta rotina pode ser alterada e modificada segundo a sua necessidade especifica...


GOSTEI 0
Maxadens

Maxadens

24/06/2005

no evento OnSetText do campo vc coloca o codigo seguinte:

procedure TForm1.TabelaCampoSetText(Sender: TField;
const Text: String);
begin
if Text = ´ / / ´ then
Tabela.campo.clear
else
Tabela.campo := StrToDate(text);
end;

Inclusive, você pode tratar erros de datas inválidas nesse evento que vai ficar legal.


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

no evento OnSetText do campo vc coloca o codigo seguinte: procedure TForm1.TabelaCampoSetText(Sender: TField; const Text: String); begin if Text = ´ / / ´ then Tabela.campo.clear else Tabela.campo := StrToDate(text); end; Inclusive, você pode tratar erros de datas inválidas nesse evento que vai ficar legal.


[b:eeef0667a9]Foi o que eu disse em minha última citação[/b:eeef0667a9]


GOSTEI 0
Maxadens

Maxadens

24/06/2005

O Marco... falta de atenção minha! :D
Mas valeus!


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Colegas..

Funciona perfeitamente..

O Problema é que este evento funciona como o evento keypress do edit..


Faz a verificação em todas as vezes que mexo no grid, e não posso trabalhar assim, pois tenho muitos campos e além de tudo trabalha on-line, o que acarreta na perda de performance.

Não existe nenhuma máscara que me permite brancos?


GOSTEI 0
Tnaires

Tnaires

24/06/2005

Caro Cabelo,
Eu, e talvez outros colegas do fórum, recorremos a esta ´gambiarra´ justamente pq esse problema [b:26a410d092]parece[/b:26a410d092] ser uma espécie de bug da validação de máscaras da VCL do Delphi. Talvez vc tenha q procurar uma outra suíte de componentes q não apresente esse problema.


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Entendí, mas estou pior ainda..rsrsrs

Trabalho com CLX, nem VCL é..

Vou pesquisar um pouco, qualquer coisa posto aquí se encontrar algo..

Obrigado pela atenção de todos.


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Sobe.. :lol:

alguém?


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

Amigo cabelo, eu não to entendendo algums detalhes em sua ´pstagem
Se voce for mais puder me esclarecer melhor eu agradeço

O Problema é que este evento funciona como o evento keypress do edit..


Faz a verificação em todas as vezes que mexo no grid


Mas se voce esta mexendo no Grid ele tem que fazer a verificação.. É errado isto :?: :?: :?:

Por outro lado , ele tem que verificar [size=18:3086488c2d][b:3086488c2d]somente[/b:3086488c2d][/size:3086488c2d] o campo do Registro que esta selecionado...Veja que se voce explicar esses passos Melhor podem aparecer dicas de [b:3086488c2d]desabilitar e habilitar o evento onsetText no momento certo[/b:3086488c2d]... Assim , teste de verificações desnecessários , não acontecerão...

Por exemplo..Toda vez que o dataSource muda de estado Habilita o evento OnsetText... Ou coisa do tipo , toda vez que a coluna do Grid Correspondente recebe o foco.. Vamos supor que seu campo Data esta no Grid na cluna 3...[b:3086488c2d] Note uma idéia do código[/b:3086488c2d]


procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
if (DbGrid1.SelectedIndex=3)and(O Estado e de edicao ou Irserção) Then
  begin
    Habilita o evento OnsetText;
  end
else
  Desabilita o evento onsetText
end;


[b:3086488c2d]Entendeu aonde eu quero chegar... [/b:3086488c2d]Acho que desta forma é possível voce minimizar os efeitos de uma chamda desnecessária a um evento

Se voce não souber como fazer para habilitar e desabilitar um [b:3086488c2d]evento , post ai[/b:3086488c2d]

Mas tb gostaria de sua observaçoes pois ate agora não entendi muito bem o que se esta passando... Eu lembro que este evento onsetText é realizado muitas vezes quando se esta desenhando no Grid.. Fora iisto eu to sem entender


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Marcos..

é o seguinte..

Todas as vezes que mexo em uma linha do grid, tenho que gravar os dados em um vetor do tipo record, mas esta gravação é muito rápida. Tenho que percorrer todos os campos na hora de gravar, linha a linha, e isto irá fazer dispara o evento OnSelText, o quê iria causar muita perda de performance..pois iria verificar os campos, mesmo os já verificados a cada post, todos os registros.. entendeu?

por isso não posso usar o evento, já que ele iria, neste caso, funcionar como o keypress do edit..

Tem ceretza que não existe uma máscara que opere com valores em branco?


GOSTEI 0
Marlon Spiess

Marlon Spiess

24/06/2005

Uma idéia, em vez de validar no seu grid, faça a validação no field dentro da table, no onValidate. Assim só passará pela rotina se vc modificar alguma informação do field.


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

Tenho que percorrer todos os campos na hora de gravar, linha a linha, e isto irá fazer dispara o evento OnSelText, o quê iria causar muita perda de performance..pois iria verificar os campos, mesmo os já verificados a cada post, todos os registros.. entendeu


[b:d329a8200a]Mas quando esta situação ocorrer o Evento OnsetText deve estar desabilitado[/b:d329a8200a]...

Cara eu to dizendo que voce deve habilitar o evento OnsetTex somente na situação que o Campo [b:d329a8200a]Recebe o Foco [/b:d329a8200a]e quando a tabela [b:d329a8200a]esta[/b:d329a8200a] no modo de edição ou de iserção... Depois que o foco sai do Campo do registro atual , o evento onsetText é desabilitado.. Ai voce pode percorrer a tabela de baixo para cima e de cima para baixo que a verificação não vai mais ocorrer..... So isso cara.


GOSTEI 0
Cabelo

Cabelo

24/06/2005

O vetor percorre o grid todo e todos os registros, inclusive o campo com a máscara, e não deve fazer comparação nenhuma, pois terei 8 campos tipo data e mais 5 tipo float, todos com máscara.. registro a registro, imagina como iria ficar lento.

A idéia do Marlon, me parece mais viável, já que só iria fazer a comparação no evento onvalidate do Field.

Marco eu preciso de varrer todas as vezes o grid, e não a tabela, só o grid, exatamente como ele está, pois faço uma comparação futura e gravo as alterações necessárias para o formato do grid e dos dados.

Portanto acho que usar o evento onSelText, me faria perder performance..

Bom pelo menos isto é ao meu ver, ainda não fiz nenhum teste..


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

En nun to te entendendo ou voce não ta me entendendo. Mas deixa quieto.

Marco eu preciso de varrer todas as vezes o grid, e não a tabela, só o grid, exatamente como ele está,
[b:0b31beed43]Que varra , mas com o evento OnsetText Desabilitado[/b:0b31beed43]


Quanto a fazer testes No enento OnValidade Para o seu caso muito provavelmente não vai dar resultado esperado, pois a mensagem sera gerada antes mesmo do evento onvalidade ser disparado...

Boa sorte....


GOSTEI 0
Michelli88

Michelli88

24/06/2005

Para resolver esse problema, eu mando gravar no banco uma data default, 01/01/1900. Na hora de mostrar, se a data for igual a esse valor, eu mostro vazio. :roll:


GOSTEI 0
Cabelo

Cabelo

24/06/2005

[quote:e5bf7b2407=´Marco Salles´]En nun to te entendendo ou voce não ta me entendendo. Mas deixa quieto.

Marco eu preciso de varrer todas as vezes o grid, e não a tabela, só o grid, exatamente como ele está,
[b:e5bf7b2407]Que varra , mas com o evento OnsetText Desabilitado[/b:e5bf7b2407]


Quanto a fazer testes No enento OnValidade Para o seu caso muito provavelmente não vai dar resultado esperado, pois a mensagem sera gerada antes mesmo do evento onvalidade ser disparado...

Boa sorte....[/quote:e5bf7b2407]

Rsss..

Acho que não estamos nos entendendo..

seguinte :

Quano o vetor varrer o grid o campo vai receber foco, portanto irá ativar o evento SelText em todos os regstros.. certo?

Quanto à sua idéia Michelli88

Para resolver esse problema, eu mando gravar no banco uma data default, 01/01/1900. Na hora de mostrar, se a data for igual a esse valor, eu mostro vazio. :roll:


Acredito ser também um ´exercício´ desnecessário, pois iria ter que fazer a verificação em todos os registros, portanto no meu caso, isto não é muito legal de se fazer, por que trabalho com o banco de dados On-Line.

Se algum de vocês tiverem outras idéias, postem aí..

Marco.. talvez eu que não esteja te entendendo.. poste mais informações.. por favor..

Um abraço a todos


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

Quano o vetor varrer o grid o campo vai receber foco, portanto irá ativar o evento SelText em todos os regstros.. certo?


Porque :?: :?: :?: Eu acho que ele so recebe o foco quando se clica nele ou quando quando se da um enter nele.. O Fato de varrer a grid internamente , atraves de algum algoritimo , não credencia o Foco para o Campo......


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Então..

mas o problema é o seguinte..

o evento não é do grid e sim do dataset.. portanto dispara sempre que o vetor verificar os campos..


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

mas o problema é o seguinte.. o evento não é do grid e sim do dataset.. portanto dispara sempre que o vetor verificar os campos..


Sim , o evento nao é do grid , ele é do dataset.. OK

Mas ele so dispara se tiver habilitado, se não tiver habilitado ele não dispara;... Então desabilite o evento
.. Voce sabe desabilitar o evento onsetText :?: :?: :?:


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Sei sim.. é só fazer uma simples verificação no evento oncolenter do grid certo?

O problema é que teria que fazer várias verificações, pois tenho uns 15 campos com máscara entre datas e valores float...

Como disse anteriormente, isto acarretará numa grande perda de performance..


GOSTEI 0
Guilherme

Guilherme

24/06/2005

nao deu tempo para ler o topicio todo mais nao seria melhor vc fazer na ´mao´
copy(string,0,2)+´/´+copy(string,3,2)+´/´+copy(string,5,4)



GOSTEI 0
Catunda

Catunda

24/06/2005

caro colega Cabelo...
Trabalho muito com dbgrid em meus programas e ja sofri muito com esse problema e depois de muito pesquisar a forma mais prática e simples de resolver foi utilizando a tecla Delete qdo quero limpar a data.
Para isso utilizo o evento OnKeyUp do DBGrid. Abaixo está como eu utilizo em um dos sistemas e nunca foi notada nenhuma diferença de performance.

procedure TFormParcelas_Iptu_1.DBGrid1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key=vk_delete)and(not(dbgrid1.Columns.Items[DBGrid1.SelectedIndex].ReadOnly)) then
begin
Query1.Edit;
dbgrid1.SelectedField.Clear;
end;
end;


GOSTEI 0
Cabelo

Cabelo

24/06/2005

Colega..

Sua dica atende perfeitamente às minhas necessidades, não há perda nenhuma na performance, mesmo on-line, já que este evento está ligado ao grid e não ao dataset.

Muito obrigado, e obrigado também ao Marco, que se desdobrou a tentar me ajudar, valeu mesmo..

Tenho a solução deste problema, mas lanço aí um desafio...

Será que isto é um BUG do delphi?????

Como resolver este problema simplesmente usando Máscaras??


GOSTEI 0
Marco Salles

Marco Salles

24/06/2005

Beleza . E sempre bom aprender... Mas me responda por gentileza. Quando voce estiver no campo data e o usuário dar bacspace no campo data ate deixa-lo em branco e logo em seguida ele dar um tab , não ira dar erro :?: :?: :?: :?: .. Voce tb não deveria fazer um tratamento para a tecla BacSpace :?: :?: :?:


GOSTEI 0
Guilherme

Guilherme

24/06/2005

e ai cabelo !!!
mais qual das dicas resolveu seu problema ???
tem uma outra maneira de fazer isso ou o usuario aperta ESC e passa para frente ou no on exit vc testa ce esta completo caso nao esteja vc simula a tecla ESC !!!


GOSTEI 0
Cabelo

Cabelo

24/06/2005

[quote:16c373449f=´Marco Salles´]Beleza . E sempre bom aprender... Mas me responda por gentileza. Quando voce estiver no campo data e o usuário dar bacspace no campo data ate deixa-lo em branco e logo em seguida ele dar um tab , não ira dar erro :?: :?: :?: :?: .. Voce tb não deveria fazer um tratamento para a tecla BacSpace :?: :?: :?:[/quote:16c373449f]

É verdade Marco... mas agora.. usando este evento no grid, no meu caso posso fazer quantas verificações quiser, pois o evento será disparado somente quando der um Insert, ou edit.. e não como iria acontecer antes, todas as vezes que passar pelo campo data..

Só lembrando do emu vetor.. ele irá colocar o dataset em modo de edição, mas não irá disparar o evento do grid.. entendeu?

e ai cabelo !!! mais qual das dicas resolveu seu problema ??? tem uma outra maneira de fazer isso ou o usuario aperta ESC e passa para frente ou no on exit vc testa ce esta completo caso nao esteja vc simula a tecla ESC !!!


Esta

caro colega Cabelo... Trabalho muito com dbgrid em meus programas e ja sofri muito com esse problema e depois de muito pesquisar a forma mais prática e simples de resolver foi utilizando a tecla Delete qdo quero limpar a data. Para isso utilizo o evento OnKeyUp do DBGrid. Abaixo está como eu utilizo em um dos sistemas e nunca foi notada nenhuma diferença de performance. procedure TFormParcelas_Iptu_1.DBGrid1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Key=vk_delete)and(not(dbgrid1.Columns.Items[DBGrid1.SelectedIndex].ReadOnly)) then begin Query1.Edit; dbgrid1.SelectedField.Clear; end; end;


Pois se comportou exatamente como eu precisava..

Mesmo assim, não se esqueçam, está lançado o desafio..

COMO FAZER PARA UM CAMPO COM MÁSCARA ACEITAR BRANCOS?


GOSTEI 0
Cabelo

Cabelo

24/06/2005

sobe.. :(


GOSTEI 0
Cabelo

Cabelo

24/06/2005

sobe de novo.... :(


GOSTEI 0
POSTAR