ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

[resolvido] Validação Campos Vazios Tab Order Não Respeitado

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Sex Nov 17, 2017 3:57 pm    Assunto: [resolvido] Validação Campos Vazios Tab Order Não Respeitado Responder com Citação

Amigos, uso essa função para validar campos vazios.
Basta definir a TAG = 1 para tornar o campo obrigatório.
Não achei o motivo, mas não está respeitando o taborder para apresentar a mensagem

estou validando:

NOME tabborder = 0
PROFISSÃO taborder = 5
TELEFONE taborder = 20

E a mensagem lista:

NOME
TELEFONE
PROFISSÃO

Código:
function TFrmPacientes.ValidaCampos: Boolean;
var
  i: Integer;
  Msg: string;
  Foco: Boolean;
begin
  Result := False;
  Foco := False;
  Msg := EmptyStr;

  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i].ClassType = TLabeledEdit then
      if (TLabeledEdit(Components[i]).Tag = 1) and (TLabeledEdit(Components[i]).Text = EmptyStr) then
      begin
        Result := True;
        Msg := Msg + #13 + '-  ' + TLabeledEdit(Components[i]).ImeName;

        if Foco = False then
        begin
          TLabeledEdit(Components[i]).SetFocus;
          Foco := True;
        end;
      end;

  if Result = True then
    MessageDlg('Campo(s) obrigatório(s):' + #13 + #13 + Trim(Msg), mtError, [mbOk], 0);
end;


Editado pela última vez por renanbg em Seg Nov 20, 2017 3:53 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 2545
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 20, 2017 9:54 am    Assunto: Responder com Citação

Quando você percorre os componentes através do código:
Código:
for i := 0 to ComponentCount - 1 do

A ordem percorrida é aquela em que os componentes foram inseridos no form. O Taborder é ignorado nesta ordenação.

Para percorrer de acordo com o TabOrder, você pode usar o GetTabControlList para obter a lista de componentes ordenados pelo TabOrder.

Teste sua função assim:

Código:
function TFrmPacientes.ValidaCampos: Boolean;
var
  i: Integer;
  Msg: string;
  Foco: Boolean;
  lista: TList;
begin
  Result := False;
  Foco := False;
  Msg := EmptyStr;

  lista := TList.Create;
  try
    GetTabControlList(lista);

    for i := 0 to lista.Count - 1 do
      if TWinControl(lista[i]) is TLabeledEdit then
        if (TLabeledEdit(lista[i]).Tag = 1) and (TLabeledEdit(lista[i]).Text = EmptyStr) then
        begin
          Result := True;
          Msg := Msg + #13 + '-  ' + TLabeledEdit(lista[i]).ImeName;

          if Foco = False then
          begin
            TLabeledEdit(lista[i]).SetFocus;
            Foco := True;
          end;
        end;

    if Result = True then
      MessageDlg('Campo(s) obrigatório(s):' + #13 + #13 + Trim(Msg), mtError, [mbOk], 0);
  finally
    FreeAndNil(lista);
  end;
end;

_________________
''A persistência é o menor caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Seg Nov 20, 2017 10:45 am    Assunto: Responder com Citação

Hum, tem um probleminha.

Grava sem mostrar a mensagem de campos vazios.

Daí tentei com 2 componentes, mas da erro de listindex out of bonds

Código:
var
  i: Integer;
  Msg: string;
  Foco: Boolean;
  Lista: TList;
begin
  Result := False;
  Foco := False;
  Msg := EmptyStr;

  Lista := TList.Create;
  try
    GetTabControlList(Lista);

    for i := 0 to Lista.Count - 1 do
      if TWinControl(Lista[i]) is TLabeledEdit then
        if (TLabeledEdit(Lista[i]).Tag = 1) and (TLabeledEdit(Lista[i]).Text = EmptyStr) then
        begin
          Result := True;
          Msg := Msg + #13 + '-  ' + TLabeledEdit(Lista[i]).ImeName;

          if Foco = False then
          begin
            TLabeledEdit(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;

      if TWinControl(Lista[i]) is TDateTimePicker then
        if (TDateTimePicker(Lista[i]).Tag = 1) and (TDateTimePicker(Lista[i]).Date = Date) then
        begin
          Result := True;
          Msg := Msg + #13 + '-  ' + TDateTimePicker(Lista[i]).ImeName;

          if Foco = False then
          begin
            TDateTimePicker(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;

    if Result = True then
      MessageDlg('Campo(s) obrigatório(s):' + #13 + #13 + Trim(Msg), mtError, [mbOk], 0);
  finally
    FreeAndNil(Lista);
  end;
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 2545
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 20, 2017 11:37 am    Assunto: Responder com Citação

Pelo que vi no seu código, faltou colocar o tratamento de cada tipo dentro de um bloco Begin..End no loop do For.

Faça um teste com o código abaixo:

Código:
var
  i: Integer;
  Msg: string;
  Foco: Boolean;
  Lista: TList;
begin
  Result := False;
  Foco := False;
  Msg := EmptyStr;

  Lista := TList.Create;
  try
    GetTabControlList(Lista);

    for i := 0 to Lista.Count - 1 do
    begin
      if TWinControl(Lista[i]) is TLabeledEdit then
        if (TLabeledEdit(Lista[i]).Tag = 1) and (TLabeledEdit(Lista[i]).Text = EmptyStr) then
        begin
          Result := True;
          Msg := Msg + #13 + '-  ' + TLabeledEdit(Lista[i]).ImeName;

          if Foco = False then
          begin
            TLabeledEdit(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;

      if TWinControl(Lista[i]) is TDateTimePicker then
        if (TDateTimePicker(Lista[i]).Tag = 1) and (TDateTimePicker(Lista[i]).Date = Date) then
        begin
          Result := True;
          Msg := Msg + #13 + '-  ' + TDateTimePicker(Lista[i]).ImeName;

          if Foco = False then
          begin
            TDateTimePicker(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;
    end;

    if Result = True then
      MessageDlg('Campo(s) obrigatório(s):' + #13 + #13 + Trim(Msg), mtError, [mbOk], 0);
  finally
    FreeAndNil(Lista);
  end;
end;

_________________
''A persistência é o menor caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Seg Nov 20, 2017 12:26 pm    Assunto: Responder com Citação

Boa tarde.

Eu já havia tentado dessa forma, mas daí a validação dos campos é ignorada.
Ao invés do informar que tem algum campo vazio, o sistema já grava o registro.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 2545
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 20, 2017 1:21 pm    Assunto: Responder com Citação

Fiz alguns testes aqui e o percebi que o GetTabControlList funciona apenas quando os componentes estão diretamente no form.

Se os componentes estiverem em um container (PageControl, por exemplo) não funciona.

Alterei o GetTabControlList pelo GetTabOrderList e funcionou para ambos os casos.

Fiz umas modificações para ficar da maneira que uso.

Código:
function TFrmPacientes.ValidaCampos: Boolean;
var
  i: Integer;
  Msg: string;
  Foco: Boolean;
  Lista: TList;
begin
  Result := False;
  Foco := False;
  Msg := EmptyStr;

  Lista := TList.Create;
  try
    GetTabOrderList(Lista); // Alterei aqui

    for i := 0 to Lista.Count - 1 do
    begin
      if TControl(Lista[i]) is TLabeledEdit then
        if (TLabeledEdit(Lista[i]).Tag = 1) and (TLabeledEdit(Lista[i]).Text = EmptyStr) then
        begin
          Msg := Msg + #13 + '-  ' + TLabeledEdit(Lista[i]).Name;

          if Foco = False then
          begin
            TLabeledEdit(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;

      if TControl(Lista[i]) is TDateTimePicker then
        if (TDateTimePicker(Lista[i]).Tag = 1) and (TDateTimePicker(Lista[i]).Date = Date) then
        begin
          Msg := Msg + #13 + '-  ' + TDateTimePicker(Lista[i]).ImeName;

          if Foco = False then
          begin
            TDateTimePicker(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;
    end;

    if Msg <> EmptyStr then
    Begin
      MessageDlg('Campo(s) obrigatório(s):' + #13 + #13 + Trim(Msg), mtError, [mbOk], 0);
      Result := False;
    End
    else
      Result := True;
  finally
    FreeAndNil(Lista);
  end;
end;


Exemplo de uso:

Código:
  if ValidaCampos then
  begin
    ShowMessage('Gravar');
    // Coloque aqui o código para gravar
  end
  else
  begin
    // Campos zerados (não grave)
    ShowMessage('Não gravar');
  end;

_________________
''A persistência é o menor caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Seg Nov 20, 2017 1:49 pm    Assunto: Responder com Citação

No meu projeto atual não funciona de jeito nenhum.
Troquei a função antiga(que funcionava, mas não respeitava o taborder) por essa ultima que você postou e aparentemente o codigo é ignorado.

Criei um projeto novo e então funciona parcialmente. Digo parcialmente, pois não trata o datetimepicker.

A chamada faço assim:

Código:
  if not ValidaCampos then
    abort;


Mas tbm fiz como você falou e não mudou.

Vai entender
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 2545
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 20, 2017 2:03 pm    Assunto: Responder com Citação

Você chegou a testar a função para esta última que postei, trocando o GetTabControlList pelo GetTabOrderList?

Sobre não tratar o DateTimePicker, creio que possa ser devido a algum arredondamento da data com a hora.

Troque a parte do tratamento do DateTimePicker por este:

Código:
    if TControl(Lista[i]) is TDateTimePicker then
        if (TDateTimePicker(Lista[i]).Tag = 1) and
          (StrToDate(DateToStr(TDateTimePicker(Lista[i]).Date)) = Date) then
        begin
          Msg := Msg + #13 + '-  ' + TDateTimePicker(Lista[i]).ImeName;

          if Foco = False then
          begin
            TDateTimePicker(Lista[i]).SetFocus;
            Foco := True;
          end;
        end;

_________________
''A persistência é o menor caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Seg Nov 20, 2017 2:55 pm    Assunto: Responder com Citação

Não havia notado a alteração.

Desta nova forma funciona sim e nem precisa modificar o datetimepicker.

Unica coisa é um warning
Código:

[dcc32 Hint] UnPacientes.pas(877): H2077 Value assigned to 'TFrmPacientes.ValidaCampos' never used


Aponta para

Result := False; na quinta linha
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 2545
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 20, 2017 2:58 pm    Assunto: Responder com Citação

Faça um teste removendo esta linha, visto que o resultado é passado para função somente no final.
_________________
''A persistência é o menor caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
renanbg
Mestre
Mestre


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 956

MensagemEnviada: Seg Nov 20, 2017 3:27 pm    Assunto: Responder com Citação

Aí resolve e não dá nenhum problema.

Obrigado.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB