none
Problemas com For Next RRS feed

  • Pergunta

  • Bom dia pessoal,

    Estava com uma dúvida de como montar um combo dinâmico com horas. Consegui resolver aqui com ajuda do José Eduardo Castro. Depois tive uma dúvida de como contar de 30 em 30 minutos entre duas datas/horas e consegui resolver com ajuda do Leandro Martins.

    Agora, precisei juntar tudo isso. Preciso verificar o intervalo entre duas datas/horas e ao montar esse combo dinâmico, ele não deve mostrar os horários presentes entre elas.

    Por exemplo: Para um intervalo com Inicio: "14/01/2012 10:00" e Fim: "14/01/2012 11:30", ele não deve mostrar no combo de horas os horários: 10:00, 10:30, 11:00 e 11:30.

    Nesta tentativa de implementação, fiz o seguinte:

    <%
    DataAgendamento = "07/01/2012 15:00"
    
    ' ## Retorna Horários Reservados...
    Set cmdRetornaHorarios = Server.CreateObject("ADODB.Command")
    cmdRetornaHorarios.ActiveConnection = DataAgenda
    cmdRetornaHorarios.CommandText = "Select * from TBAgenda WHERE day(AgendaInicio) = " & day(DataAgendamento) & " and month(AgendaInicio) = " & month(DataAgendamento) & " and year(AgendaInicio) = " & year(DataAgendamento) & " and UsuarioAgendamento = 1" '& request("UsuarioAgendamento")
    cmdRetornaHorarios.CommandType = 1
    Set rsRetornaHorarios = Server.CreateObject("ADODB.Recordset")
    rsRetornaHorarios.Open cmdRetornaHorarios, , 3, 3
    
    x = 1
    dim posicao(47)
     
    do while not rsRetornaHorarios.EOF
    
    	vInicial = hour(rsRetornaHorarios("AgendaInicio")) 'hora inicial
    	vFinal = hour(rsRetornaHorarios("AgendaFim")) 'hora final
    	vInvervalo = 30 'intervalo entre as horas
    	
    	vDate = CDate("0001/01/01 00:00:00") 'data base
    	vDate = DateAdd("h", vInicial, vDate) 'setado hora inicial na data base
    	
    	while hour(vDate) < vFinal 'enquanto hora inicial < hora final
    
    	                posicao(x) = mid(vDate,10,5) & ":00"
    				   	vDate = DateAdd("n", vInvervalo, vDate)
    	                x = x + 1
    
    	wend
    
    rsRetornaHorarios.movenext
    loop
    
    %>
    <select name="Horario" id="Horario">
    	<%
    		horario = "00:00:00"
    	
    		For i = 0 to 47
    		q = 1
    			
    			do while q < x
    			
    				if posicao(q) <> horario then
    			
    			%>
    				<option value="<%=horario%>"><%=horario%></option>
    			<% 
    				end if
    				q = q + 1
    			loop
    				
    		horario = DateAdd("n", 30, horario)
    			
    		Next
    	%>
    </select>
    
    

     

     

    Isso não funcionou, pois ele está repedindo os horários. Não entendi bem o que está acontecendo. Alguém pode me ajudar?

     


    Eder Pardeiro
    sábado, 14 de janeiro de 2012 15:35

Respostas

  • Eder,
     
    Não sei se já conseguiu resolver esta questão.
    Veja se a solução atende:
     
    <%
    	'Simulando entrada com datas vindas do banco de dados
    	vInicial = "2012-01-20 10:00:00"
    	vFinal = "2012-01-20 11:30:00"
    
    	'Obtendo hora e minuto
    	vInicial = Hour(vInicial) & ":" & Minute(vInicial)
    	vFinal = Hour(vFinal) & ":" & Minute(vFinal)
    	
    	response.write "vInicial : " & vInicial & "<br>"
    	response.write "vFinal : " & vFinal & "<br><br>"
    %>


    Na primeira parte, eu simulo a entrada de datas provindas de uma tabela do banco de dados e obtenho a hora e minuto de cada uma, que são os valores que precisaremos para interagir com a lista de horários.
     
    <select name="cboHorario">
    <%
    	horario = "00:00:00"
    	
    	For i = 0 to 47
    		if DateDiff("s", horario, vInicial) > 0 or DateDiff("s", vFinal, horario) > 0 then
    			%><option value="<%=horario%>"><%=horario%></option><%
    		end if
    		
    		horario = DateAdd("n", 30, horario)
    	Next
    %>
    </select> 


    Na segunda parte, eu utilizo a função DateDiff para verificar a diferença entre as datas em segundos. Para adicionar uma nova opção no combo de horários é preciso que uma das duas condições seja verdadeira:
     
    1. A diferença de segundos entre horario e vInicial deve ser maior do que 0
    2. A diferença de segundos entre vFinal e horario deve ser maior que 0
     
    Dessa forma é possível filtrar o intervalo desejado, tendo baixo custo de implementação.
     
     
    Nessa minha solução eu estou prevendo que você queira filtrar somente os horários de um dia específico.
     
    Você está planejando ter mais de um intervalo de horário por dia? Por exemplo: 10:00 às 11:30 e das 15:00 às 17:00 não exibir as opções no combo. Se precisar disso, será necessário adicionar algumas funcionalidades para este código. Entretanto, se deseja filtrar somente um intervalo de horas por dia, creio que a solução acima atenderá.
     
     
    Abraços!

    sexta-feira, 20 de janeiro de 2012 19:32
  • Eder,

    Eu havia comentado sobre a possibilidade de ter mais de um intervalo de horário a ser restringido.

    Inicialmente você deve criar uma array com duas dimensões (x,y), onde:

    • x: número de intervalos de horários (nesse caso, você pode considerar o número de registros retornados no select que você realiza no banco de dados para obter essas informações)
    • y: número de valores para cada intervalo de horário. neste caso, nós teremos dois. a data inicial e a data final.

    Vou postar um exemplo simulando a entrada de dados.

    Dim restricoesHorario(2, 1)
    restricoesHorario(0,0) = "10:00"
    restricoesHorario(0,1) = "11:30"
    restricoesHorario(1,0) = "13:30"
    restricoesHorario(1,1) = "14:30"
    restricoesHorario(2,0) = "18:00"
    restricoesHorario(2,1) = "23:30"
    
    

    Primeiramente declarei o meu array, informando que ele terá três valores na primeira dimensão e dois na segunda.

    Preenchi os valores, que representam os intervalos mencionados no seu exemplo.

    Feito isso, você pode criar uma função para validar o horário do combobox. Essa função receberá esse vetor com todos os horários de restrição e o valor do horário atual, que estará sendo preenchido pelo combobox.

    Estrutura da função:

    function ValidarRestricaoHorario(restricoesHorario, horario)
    	dim tamanhoRestricoesHorario, vInicialHorario, vFinalHorario
    	
    	tamanhoRestricoesHorario = uBound(restricoesHorario)
    	for j = 0 to tamanhoRestricoesHorario 
    				
    		vInicialHorario = restricoesHorario(j,0)
    		vFinalHorario = restricoesHorario(j,1)
    		
    		if DateDiff("s", horario, vInicialHorario) <= 0 and DateDiff("s", vFinalHorario, horario) <= 0 then
    			ValidarRestricaoHorario = false
    			Exit Function
    		end if
    	next
    	
    	ValidarRestricaoHorario = true
    end function
    
    

    Inicialmente eu utilizo a função uBound para obter o tamanho do meu vetor, que neste caso é 2. Eu percorro todo o vetor e realizo a validação que comentei anteriormente para todos os horários de restrição que tenho no meu vetor.

    Eu inverti a lógica de validação. Agora, se uma das condições retornar " <=0 ", eu considero que o horário não deve ser exibido. Retorno false na função e utilizando o comando "Exit Function" para encerrar esta rotina.

    Por fim, é necessário realizar a chamada para esta função criada no momento da criação dos horários no combox. Ficaria desta forma:

    <select name="cboHorario">
    <%
    	horario = "00:00:00"
    	
    	For i = 0 to 47
    	
    		if ValidarRestricaoHorario(restricoesHorario, horario)  then
    			%><option value="<%=horario%>"><%=horario%></option><%
    		end if
    		
    		horario = DateAdd("n", 30, horario)
    	Next
    %>
    

    Apenas será inserida a opção do horário se a "ValidarRestricaoHorario" retornar o valor verdadeiro.

    Resultado:

    Abraços!


    sábado, 21 de janeiro de 2012 00:29
  • Eder,

    Ah sim, agora entendi. Quanto bati o olho e vi o recordcount, pensei que este seria o problema.

    Realizando alguns testes, encontrei como alternativa o uso do redim para criar um array com tamanho dinâmico, lendo uma variável.

    Fiz um teste, conforme exemplo abaixo, e funcionou corretamnete.

    dim qtdRegistros
    qtdRegistros = 2
    redim restricoesHorario(qtdRegistros, 1)
    

    Abraços!

    sábado, 21 de janeiro de 2012 21:41

Todas as Respostas

  • Eder,
     
    Não sei se já conseguiu resolver esta questão.
    Veja se a solução atende:
     
    <%
    	'Simulando entrada com datas vindas do banco de dados
    	vInicial = "2012-01-20 10:00:00"
    	vFinal = "2012-01-20 11:30:00"
    
    	'Obtendo hora e minuto
    	vInicial = Hour(vInicial) & ":" & Minute(vInicial)
    	vFinal = Hour(vFinal) & ":" & Minute(vFinal)
    	
    	response.write "vInicial : " & vInicial & "<br>"
    	response.write "vFinal : " & vFinal & "<br><br>"
    %>


    Na primeira parte, eu simulo a entrada de datas provindas de uma tabela do banco de dados e obtenho a hora e minuto de cada uma, que são os valores que precisaremos para interagir com a lista de horários.
     
    <select name="cboHorario">
    <%
    	horario = "00:00:00"
    	
    	For i = 0 to 47
    		if DateDiff("s", horario, vInicial) > 0 or DateDiff("s", vFinal, horario) > 0 then
    			%><option value="<%=horario%>"><%=horario%></option><%
    		end if
    		
    		horario = DateAdd("n", 30, horario)
    	Next
    %>
    </select> 


    Na segunda parte, eu utilizo a função DateDiff para verificar a diferença entre as datas em segundos. Para adicionar uma nova opção no combo de horários é preciso que uma das duas condições seja verdadeira:
     
    1. A diferença de segundos entre horario e vInicial deve ser maior do que 0
    2. A diferença de segundos entre vFinal e horario deve ser maior que 0
     
    Dessa forma é possível filtrar o intervalo desejado, tendo baixo custo de implementação.
     
     
    Nessa minha solução eu estou prevendo que você queira filtrar somente os horários de um dia específico.
     
    Você está planejando ter mais de um intervalo de horário por dia? Por exemplo: 10:00 às 11:30 e das 15:00 às 17:00 não exibir as opções no combo. Se precisar disso, será necessário adicionar algumas funcionalidades para este código. Entretanto, se deseja filtrar somente um intervalo de horas por dia, creio que a solução acima atenderá.
     
     
    Abraços!

    sexta-feira, 20 de janeiro de 2012 19:32
  • Primeiramente, obrigado por responder José Eduardo.

    Ótima sua solução, muito simples, mas ainda tenho um problema. Podem existir diversos agendamentos para o mesmo dia... por exemplo:

    Registro1: "2012-01-20 10:00:00" à "2012-01-20 11:30:00"
    Registro2: "2012-01-20 13:30:00" à "2012-01-20 14:30:00"
    Registro3: "2012-01-20 18:00:00" à "2012-01-20 23:30:00"

    Sendo assim, no exemplo acima, temos três agendamentos para o mesmo dia.... É justamente neste ponto que estou tendo problemas...

    Como devo implementar?




    Eder Pardeiro
    sexta-feira, 20 de janeiro de 2012 23:23
  • Eder,

    Eu havia comentado sobre a possibilidade de ter mais de um intervalo de horário a ser restringido.

    Inicialmente você deve criar uma array com duas dimensões (x,y), onde:

    • x: número de intervalos de horários (nesse caso, você pode considerar o número de registros retornados no select que você realiza no banco de dados para obter essas informações)
    • y: número de valores para cada intervalo de horário. neste caso, nós teremos dois. a data inicial e a data final.

    Vou postar um exemplo simulando a entrada de dados.

    Dim restricoesHorario(2, 1)
    restricoesHorario(0,0) = "10:00"
    restricoesHorario(0,1) = "11:30"
    restricoesHorario(1,0) = "13:30"
    restricoesHorario(1,1) = "14:30"
    restricoesHorario(2,0) = "18:00"
    restricoesHorario(2,1) = "23:30"
    
    

    Primeiramente declarei o meu array, informando que ele terá três valores na primeira dimensão e dois na segunda.

    Preenchi os valores, que representam os intervalos mencionados no seu exemplo.

    Feito isso, você pode criar uma função para validar o horário do combobox. Essa função receberá esse vetor com todos os horários de restrição e o valor do horário atual, que estará sendo preenchido pelo combobox.

    Estrutura da função:

    function ValidarRestricaoHorario(restricoesHorario, horario)
    	dim tamanhoRestricoesHorario, vInicialHorario, vFinalHorario
    	
    	tamanhoRestricoesHorario = uBound(restricoesHorario)
    	for j = 0 to tamanhoRestricoesHorario 
    				
    		vInicialHorario = restricoesHorario(j,0)
    		vFinalHorario = restricoesHorario(j,1)
    		
    		if DateDiff("s", horario, vInicialHorario) <= 0 and DateDiff("s", vFinalHorario, horario) <= 0 then
    			ValidarRestricaoHorario = false
    			Exit Function
    		end if
    	next
    	
    	ValidarRestricaoHorario = true
    end function
    
    

    Inicialmente eu utilizo a função uBound para obter o tamanho do meu vetor, que neste caso é 2. Eu percorro todo o vetor e realizo a validação que comentei anteriormente para todos os horários de restrição que tenho no meu vetor.

    Eu inverti a lógica de validação. Agora, se uma das condições retornar " <=0 ", eu considero que o horário não deve ser exibido. Retorno false na função e utilizando o comando "Exit Function" para encerrar esta rotina.

    Por fim, é necessário realizar a chamada para esta função criada no momento da criação dos horários no combox. Ficaria desta forma:

    <select name="cboHorario">
    <%
    	horario = "00:00:00"
    	
    	For i = 0 to 47
    	
    		if ValidarRestricaoHorario(restricoesHorario, horario)  then
    			%><option value="<%=horario%>"><%=horario%></option><%
    		end if
    		
    		horario = DateAdd("n", 30, horario)
    	Next
    %>
    

    Apenas será inserida a opção do horário se a "ValidarRestricaoHorario" retornar o valor verdadeiro.

    Resultado:

    Abraços!


    sábado, 21 de janeiro de 2012 00:29
  • Bom dia José Eduardo,

    Perfeito, é disso mesmo que preciso. Só estou tendo um problema. Consigo criar a variável restricoesHorario(x, 1) apenas com valores fixos.

    Quando tento trazer isso do banco acontece o seguinte:

    Erro de compilação do Microsoft VBScript erro '800a0402'

    Constante inteira esperada

    /homecare/retorna_horarios.asp, line 29

    Dim restricoesHorario(rsRetornaHorarios.recordcount, 1)
    ----------------------^

     

    Já tentei colocar restricoesHorario(cInt(rsRetornaHorarios.recordcount), 1) mas mesmo assim retorna esse erro...

    tem idéia do que está acontecendo?


    Eder Pardeiro
    sábado, 21 de janeiro de 2012 11:57
  • Eder,

    Este é um problema que muitos programadores ASP já passaram.

    Como a mensagem de erro informa, o RecordCount não está retornando um valor inteiro.

    Recomendo a leitura dos artigos abaixo, os quais apresentam alternativas para você contornar este problema, além de explicá-lo.

    http://blog.djmib.net/arquivos/66/asp-recordcount-1/

    http://www.adopenstatic.com/faq/recordcounterror.asp

    http://www.w3schools.com/ado/prop_rs_recordcount.asp

    Abraços!

    sábado, 21 de janeiro de 2012 18:17
  • Boa noite José Eduardo,

    Na verdade o problema não está no recordcount. Se eu colocar uma variável qualquer com um valor no lugar também dá erro. Não está aceitando variável somente o valor mesmo e o recordcount está retornando a quantidade, coloquei um response.write e ele imprimiu...


    Eder Pardeiro
    sábado, 21 de janeiro de 2012 21:33
  • Eder,

    Ah sim, agora entendi. Quanto bati o olho e vi o recordcount, pensei que este seria o problema.

    Realizando alguns testes, encontrei como alternativa o uso do redim para criar um array com tamanho dinâmico, lendo uma variável.

    Fiz um teste, conforme exemplo abaixo, e funcionou corretamnete.

    dim qtdRegistros
    qtdRegistros = 2
    redim restricoesHorario(qtdRegistros, 1)
    

    Abraços!

    sábado, 21 de janeiro de 2012 21:41
  • Show José Eduardo.. .valeu kra...

    Não conhecia o redim.... nunca precisei usar...

     

    Muito obrigado!!!


    Eder Pardeiro
    domingo, 22 de janeiro de 2012 13:04