Usando o Controle TextBox - Validação 


O Visual Basic 6.0 fornece um novo evento que podemos utilizar para verificar a entrada de dados na interface do usuário. Creio que o controle mais utilizado para entrada de dados seja o famoso Text Box, por isso vamos nos ater a ele, embora todos os controles de controle do usuário possuam o evento Validate.

O evento Validate é disparado quando um controle está para perder o foco. Se você já usou o evento LostFocus para fazer validação a nível de controle deverá estar sentindo arrepios , mas diferentemente do evento LostFocus o evento Validate permite que você mantenha o foco em um campo que falhou em uma regra de validação evitando assim o loop contínuo...

Falar é fácil , vamos mostrar como a coisa funciona. Vamos supor que você tem  um campo numérico , pode ser o CEP , no seu formulário que não permita a entrada de valores com menos de 8 dígitos( 99999-999) . O código para validação neste caso ficaria mais ou menos assim:

Private Sub txtcep_Validate(Cancel As Boolean)
    If Len(txtcep.Text) < 8 Then
       MsgBox "Informe um Cep Válido.", vbExclamation, " CEP Inválido "
       Cancel = True       ' aqui esta o pulo do gato , o foco não se move
    End If
End Sub

A coisa funciona assim: Quando o usuário digitar um valor com menos de 8 digitos ( len(txtcep.text) < 8 ), o sistema emitira a mensagem e definirá o parâmetro Cancel como True impedindo que o foco saia do controle.

É bom ter em mente que o evento Validate é inicializado por padrão; se você não quiser que um centro controle inicialize o evento Validate terá que definir a propriedade CausesValidation para False.

Tornando a entrada de dados mais rápida

Se você sente saudades daquele seu aplicativo feito em Clipper ( ou qualquer programa DOS ) quando o quesito é a rapidez na entrada de dados (digitação mesmo) talvez a dica dada a seguir o alente um pouco.

Para agilizar na entrada de dados você pode avançar o foco de uma caixa de texto para a próxima evitando assim que o usuário pressione a tecla TAB/ENTER . Para obter o efeito usamos o evento Change do controle juntamente com o evento Setfocus. Abaixo temos o código para uma formulário que possui quatro campos : nome, endereço, cidade e telefone.

Private Sub txtnome_Change()
   If Len(txtnome.Text) >= 30 Then
        txtendereco.SetFocus   'muda o foco para o proximo campo
   End If
End Sub


Private Sub txtendereco_Change()
    If Len(txtendereco.Text) >= 30 Then
        txtcidade.SetFocus   'muda o foco para o proximo campo
    End If
End Sub

Private Sub txtcidade_Change()
    If Len(txtcidade.Text) >= 20 Then
        txttelefone.SetFocus   'muda o foco para o proximo campo
     End If
End Sub

Quando a quantidade de campos justificar você pode trabalhar com um array de controles para facilitar o seu trabalho. Para alterar o exemplo anterior criando um array de controles , atribua a todas as caixas de texto a mesma propriedade Name; Atribuiremos aqui o nome txtdados a todas as caixas de texto.  Assim para o exemplo acima teríamos:

Private Sub txtdados_Change(Index As Integer)
Dim bavancar As Boolean

Select Case Index
    Case 0 ' nome
        If Len(txtdados(Index).Text) >= 30 Then
             bavancar = True
       End If
     Case 1 ' endereco
        If Len(txtdados(Index).Text) >= 30 Then
             bavancar = True
       End If
     Case 2 ' cidade
        If Len(txtdados(Index).Text) >= 20 Then
             bavancar = True
        End If
     Case Else
         bavancar = False
End Select

If bavancar = True Then
       txtdados(Index + 1).SetFocus  ' Avança p/proximo campo
End If

End Sub

Talvez os campos escolhidos não tenham sido os mais apropriados para o exemplo, mas a idéia e mostrar como a coisa funciona. Aproveitando a facilidade dos array de controles  veja como é simples codificar a seleção automática quando o controle recebe o foco (GotFocus) :

Private Sub txtdados_GotFocus(Index As Integer)
      With txtdados(Index)
          .SelStart = 0
          .SelLength = Len(.Text)
     End With
End Sub

Os control arrays são objetos e possuem os seguintes métodos:

Metoodo Retorna
Count O número de items do controle
LBound O índice do primeiro elemento do controle.
UBound O índice do último elemento do controle.
Item(n) O elemento n do controle.

A leitura do código pode ficar prejudicada se a quantidade de controles for grande e se os campos relacionados envolveram operações entre si. Para minimizar o efeito e tornar a coisa mais compreensiva podemos usar a seguinte notação:

Const QUANTIDADE = 1
Const PRECO = 2
Const TOTAL = 3
Private Sub Text1_Change(index As Integer)
     If Text1(QUANTIDADE).Text <> "" And Text1(PRECO).Text <> "" Then
          Text1(TOTAL).Text = Format$(Val(Text1(QUANTIDADE).Text) * _
               Val(Text1(PRECO).Text))
     End If
End Sub

Aqui enumeramos os três Text Box relacionando-os com o campo aos quais estão vinculados: QUANTIDADE, PRECO E TOTAL. O resto acho que você já entendeu...

Outra vantagem dos controles de arrays e que podemos interagir com os cada controle usando uma instrução do tipo For / Next. Por exemplo para limpar o conteúdo de todos os controles Text Box de um formulário podemos usar:

For i = txtFields.LBound To txtFields.UBound
 
   txtFields(i).Text = ""
Next

Um método melhor é usar a instrução Each...Next e tem a seguinte sintaxe:

Dim ctrl As Control
For Each ctrl In txtFields
     ctrl.Text = ""
Next

Você pode também declarar uma variável objeto e usá-la no loop :

Dim tb As TextBox
For Each tb In txtFields
     tb.Text = ""
Next
 
Outra coisa interessante é que podemos criar controles em tempo de execução . Por exemplo , podemos  usar
o comando Load para criar itens nos controles Text Box , assim:
 
Load txtFields(4)
 
Neste caso o controle txtFields(4) não deve existir ou um erro irá ocorrer. Para ter
certeza disto convém usar o método Ubound, assim:
 
Load txtFields(txtFields.UBound + 1)

Para destruir o elemento que você criou em tempo de execução basta usar o comando Unload,
assim:
 
Unload txtFields(4)

Fiquei por aqui.     (leia também o artigo :  Validação e crítica de dados )