Usuário com melhor resposta
Problemas com For Next

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
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:- A diferença de segundos entre horario e vInicial deve ser maior do que 0
- 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!- Editado José Eduardo Castro sexta-feira, 20 de janeiro de 2012 19:52
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
-
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!
- Editado José Eduardo Castro sábado, 21 de janeiro de 2012 00:36
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
-
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!
- Editado José Eduardo Castro sábado, 21 de janeiro de 2012 21:41
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
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:- A diferença de segundos entre horario e vInicial deve ser maior do que 0
- 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!- Editado José Eduardo Castro sexta-feira, 20 de janeiro de 2012 19:52
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
-
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- Editado Eder Pardeiro sexta-feira, 20 de janeiro de 2012 23:24
-
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!
- Editado José Eduardo Castro sábado, 21 de janeiro de 2012 00:36
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
-
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 -
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!
- Editado José Eduardo Castro sábado, 21 de janeiro de 2012 18:18
-
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 -
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!
- Editado José Eduardo Castro sábado, 21 de janeiro de 2012 21:41
- Marcado como Resposta Eder Pardeiro domingo, 22 de janeiro de 2012 13:04
-