Notifications
Clear all

Problema em pesquisa com data

7 Posts
2 Usuários
0 Reactions
1,135 Visualizações
(@carloshvb)
Posts: 99
Trusted Member
Topic starter
 

Boa tarde pessoal,

O caso é o seguinte, sobrou pro estagiário aqui criar um sistema em VBA para um programa de geração de ideias.
O caso é que sou bem iniciante em programação e me pediram para fazer algo relativamente complicado. Eu consegui 99% adaptando códigos de tutoriais e modelos que encontrei na net. Mas agora estou com alguns erros que não consigo resolver.

1º) No formulário de pesquisa eu criei um campo que filtra os nomes automaticamente, e as datas caso solicitado através do código abaixo:

'Filtrar somente pelas Datas Inicial e Final
Private Sub cbtSo2Dts_Click()
    Dim Tmp As Long
    Dim i As Long
    Dim sDtIni As Date
    Dim sDtFim As Date
    
    Tmp = smpPesquisa.lstLista.ListItems.Count
    
        If datai = "" Then
                MsgBox "Digite uma Data Valida", , "Data Inicial Obrigatória !!!"
                datai.SetFocus
            Exit Sub
        ElseIf dataf = "" Then
                MsgBox "Digite uma Data Valida", , "Data Final Obrigatória !!!"
                dataf.SetFocus
            Exit Sub
    
        End If
    
    sDtIni = datai.Value
    sDtFim = dataf.Value

    For i = 1 To Tmp
    
        With lstLista
            If .ListItems(i).SubItems(5) < sDtIni Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
           
           ElseIf .ListItems(i).SubItems(5) > sDtFim Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
            ElseIf .ListItems(i).SubItems(5) = sDtFim Then
            
                    Tmp = Tmp ' 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
            End If
                 
        End With

    Next

End Sub

O erro acontece neste código, quando eu insiro uma data no campo "dataf" que é superior a última data registrada.
Por exemplo, se mando pesquisar de uma data inferior qualquer até a data de hoje (último registro) não dá erro, mas se eu insiro a data de amanhã por exemplo dá erro.

Então eu gostaria de saber se dá pra arrumar o código para evitar isso?

2º) Quando estou editando o código e tento executar o formulário eu recebo, as vezes, o erro 91. Mas ao fechar a planilha e abrir novamente o erro some e tudo funciona normal. Alguém tem ideia do que pode ser isso.

3º) Eu uso o formulário de consulta para chamar o formulário de pesquisa, e eu gostaria de ocultar o formulário de consulta durante a pesquisa e reexibí-lo ao final, tem como fazer isso?

Desde já agradeço a ajuda, estou colocando meu "programinha" em anexo para consulta e sugestões.
Obrigado.

 
Postado : 31/03/2015 11:25 am
(@carloshvb)
Posts: 99
Trusted Member
Topic starter
 

Bom dia pessoal,

Eu achei que tinha resolvido o problema mas agora surgiu outro.
Eu inseri um código para forçar a data final a não ultrapassar o último valor inserido, porém, agora, mesmo inserindo uma data final válida, ela é alterada para a última data inserida.

Exemplo: Considerando a data de hoje (08/04/2015) como último registro
Se eu digitar no txtBox "dataf" a data 10/04/2015 ela é alterada para 08/04/2015. Até aqui tudo bem, era isso que eu queria
Mas se eu digitar uma data válida como 04/04/2015 ela também é alterada para 08/04/2015.

Então eu gostaria de saber se tem como acertar isso para que as datas válidas não sejam alteradas.

Segue o código:

'Filtrar somente pelas Datas Inicial e Final
Private Sub cbtSo2Dts_Click()
    Dim Tmp As Long
    Dim i As Long
    Dim sDtIni As Date
    Dim sDtFim As Date
    
    Tmp = smpPesquisa.lstLista.ListItems.Count
    
        If datai = "" Then
                MsgBox "Digite uma Data Valida", , "Data Inicial Obrigatória !!!"
                datai.SetFocus
            Exit Sub
          End If
    
       'TRECHO ONDE ESTÁ OCORRENDO O ERRO
         If dataf.Value = "" Or dataf.Value > Plan2.Range("F100000").End(xlUp) Then
                 dataf = Plan2.Range("F100000").End(xlUp)
           
         End If
     ' FIM DO TRECHO COM ERRO

    sDtIni = datai.Value
    sDtFim = dataf.Value

  For i = 1 To Tmp
    
        With lstLista
            
           If .ListItems(i).SubItems(5) < sDtIni Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                      
              ElseIf .ListItems(i).SubItems(5) > sDtFim Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
              ElseIf .ListItems(i).SubItems(5) = sDtFim Then
            
                    Tmp = Tmp ' 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
           End If
                 
        End With

    Next
    
End Sub
 
Postado : 08/04/2015 5:32 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Carlos, não tenho como baixar seu modelo no momento, então se o problema está com a data digitada for maior que a data atual, eu colocaria a verificação conforme abaixo, não sei se tem algumas instruções no Evento no TextBox "dataf", se não tiver daria para fazer a verificação utilizando um dos eventos : Exit, AfterUpdate, etc

Mas veja se a dica ajuda :

Private Sub CommandButton1_Click()

Dim sDataAtual As Date

sDataAtual = Date


    If dataf.Value = "" Or dataf.Value > sDataAtual Then
        
        MsgBox "Digite uma Data Valida", , "Data Final em Branco ou maior que a data Atual !!!"
        
    End If

End Sub

[]s

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 08/04/2015 7:30 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Carlos, como acessamos os foruns em alguns minutos de descanso, nem sempre da para ler tudo o que escrevem, e agora com um pouco mais de atenção reparei que não quer comparação com a Data atual e sim a maior data registrada na Coluna "F", e como não vi seu modelo estou supondo que o inicio se de em "F2".
Utilizando a Função Maximo, retornamos a maior data na coluna em questão, então teste a rotina abaixo e veja se retorna correto, lembrando que tem de ajustar a coluna e o nome da planilha se por acaso não for "Plan2".

Private Sub CommandButton2_Click()
Dim vMaximo
Dim rgDatas As Range
Dim sDataMaior

'Define o Range com as Datas na coluna F entre F2 e ultima preenchida
Set rgDatas = Worksheets("Plan2").Range("F2", Worksheets("Plan2").Range("F" & Rows.Count).End(xlUp))

'Define a Função
Set WF = Application.WorksheetFunction
    
    'Retorna a maior data
    vMaximo = WF.Max(rgDatas)
    
    'Como o excel enxerga datas como decimal
    'Formatamos para tipo Data
    sDataMaior = Format(vMaximo, "dd/mm/yy")
    
    If dataf.Value = "" Or dataf.Value > sDataMaior Then
        
        MsgBox "Digite uma Data Valida", , "Data Final em Branco ou maior que a data registrada !!!"
        
    End If

End Sub

Qualquer duvida retorne.

[]s

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 08/04/2015 8:10 am
(@carloshvb)
Posts: 99
Trusted Member
Topic starter
 

Mauro,

OBS: Quando postei isso, eu ainda não tinha visto sua última resposta, vou testar e posto o resultado.

Na verdade eu quero que a data final possa ser utilizada em branco, meu único problema é quando a data final é maior que a data do último registro, neste caso acontece o erro. Eu modifique novamente o código para testar e ficou assim:

Select Case dataf.Value
            
            Case Is > Plan2.Range("F100000").End(xlUp): sDtFim = Plan2.Range("F100000").End(xlUp)
            Case Is = "": sDtFim = Plan2.Range("F100000").End(xlUp)
            Case Else: sDtFim = dataf.Value
                        
End Select

Neste código eu percebi o seguinte:
- Se eu não fizer a primeira comparação (Case Is >...) o código funciona quase perfeitamente, se o campo dataf for "" ele considera a data do último registro como dataf e faz a pesquisa e aceita qualquer dataf menor ou igual a do último registro e faz a pesquisa corretamente támbem, mas quando eu ativo o primeiro caso, qualquer valor inserido é considerado como maior que o último registro e este é utilizado, ignorando o valor digitado.

Então meu problema está nesta comparação, como fazer para que ela seja feita da forma correta considerando que dataf e o valor obtido em " Plan2.Range("F100000").End(xlUp)" são datas. Pois acho que o problema é que um dos valores não está sendo interpretado como data, mas não sei como resolver isso.

 
Postado : 08/04/2015 8:52 am
(@carloshvb)
Posts: 99
Trusted Member
Topic starter
 

Mauro Obrigado,

Seu código deu certo, só que eu tive que definir o rgDatas de forma diferente pois estava dando erro.
O código final ficou assim:

'Filtrar somente pelas Datas Inicial e Final
Private Sub cbtSo2Dts_Click()
    Dim Tmp As Long
    Dim i As Long
    Dim sDtIni As Date
    Dim sDtFim As Date
    
    Dim vMaximo
    Dim rgDatas As Range
    Dim sDataMaior

'AQUI EU TIVE QUE MODIFICAR SEU CÓDIGO
Set rgDatas = Plan2.Range("F" & Rows.Count).End(xlUp)

'Define a Função
Set WF = Application.WorksheetFunction
   
'Retorna a maior data
vMaximo = WF.Max(rgDatas)
   
'Como o excel enxerga datas como decimal
'Formatamos para tipo Data
sDataMaior = Format(vMaximo, "dd/mm/yy")
     
Tmp = smpPesquisa.lstLista.ListItems.Count
    
        If datai = "" Then
                MsgBox "Digite uma Data Valida", , "Data Inicial Obrigatória !!!"
                datai.SetFocus
            Exit Sub
        End If
    
        Select Case dataf.Value
            
            Case Is > sDataMaior: sDtFim = sDataMaior
            Case Is = "": sDtFim = sDataMaior
            Case Else: sDtFim = dataf.Value
                        
        End Select
    
    
sDtIni = datai.Value
    
  For i = 1 To Tmp
    
        With lstLista
            
              If .ListItems(i).SubItems(5) < sDtIni Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                            
              ElseIf .ListItems(i).SubItems(5) > sDtFim Then
                smpPesquisa.lstLista.ListItems.Remove i
                    i = i - 1
                    Tmp = Tmp - 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
              ElseIf .ListItems(i).SubItems(5) = sDtFim Then
            
                    Tmp = Tmp ' 1
                        If i = Tmp Then Exit For
                            Tmp = smpPesquisa.lstLista.ListItems.Count
                        
           End If
                 
        End With

    Next
    
End Sub
 
Postado : 08/04/2015 10:28 am
(@carloshvb)
Posts: 99
Trusted Member
Topic starter
 

Pessoal depois de alguns testes, eu descobri alguns erros no código que já foram corrigidos, mas eu gostaria de compartilhar com vocês caso alguém queira utilizar o código em algum projeto.

Eu descobri que um dos problemas era que a data final usada na comparação, caso fosse utilizado o valor da planilha, tinha apenas o dia utilizado na comparação, então se o dia digitado em dataf fosse maior que o último dia registrado independente do mês, a data final da planilha seria utilizada.

Exemplo: valor digitado em dataf: 01/03/2015

valor do último registro: 08/04/2015

Neste caso o filtro funciona corretamente e a data de 01/03/2015 é utilizada, mas no caso abaixo

Exemplo 2: valor digitado em dataf: 20/03/2015

valor do último registro: 08/04/2015

Neste caso o valor em dataf era considerado maior que o último registro, pois o dia era maior.

Para resolver este problema, eu utilizei uma data fictícia fixa (31/12/9999) para comparação.

O que gerou outro problema "Erro 35600 - Out of bounds", esse erro era devido ao código do filtro em si, então este também foi modificado.

O código final ficou assim:

 'Filtrar somente pelas Datas Inicial e Final'
    Private Sub cbtSo2Dts_Click()
        Dim Tmp As Long
        Dim i As Long
      
        
         
            If datai = "" Then
                    MsgBox "Digite uma Data Valida", , "Data Inicial Obrigatória !!!"
                    datai.SetFocus
                Exit Sub
            End If
            

     'Código do Filtro'      
            For i = lstLista.ListItems.Count To 1 Step -1
                If CDate(lstLista.ListItems(i).SubItems(5)) < datai.Value Then
                    lstLista.ListItems.Remove i
                ElseIf CDate(lstLista.ListItems(i).SubItems(5)) > dataf.Value Then
                    lstLista.ListItems.Remove i
                End If
            Next

    End Sub

De qualquer forma, obrigado pela ajuda, e fica o código para quem tiver interesse em fazer algo semelhante.

 
Postado : 10/04/2015 6:38 am