none
Ciclo FOR...NEXT múltiplo. RRS feed

  • Pergunta

  • Bom dia, amigos.

    Será que é possível obter um ciclo FOR...NEXT múltiplo?

    Clarificando:

    Numa Case podemos utilizar a seguinte sintaxe:

    Case 0 to 4, 10 to 15.

    Isto é possível no ciclo For...Next?

    Se sim, qual a sintaxe?

    Não consigo encontrar nada na NET que me elucide, daí o pedido de ajuda aos mestres na matéria.

    Cumprimentos

    MAL


    M_A_L

    segunda-feira, 24 de novembro de 2014 11:09

Respostas

  • Boa noite M_A_L.

    Penso que no seu caso a resposta seja quase da forma que vc mesmo sugeri. Eu usaria um "Select Case"

    For i = 1 To 20
    
        Select Case i
        
            Case 0 To 4, 10 To 15
                
                '... Seu código
            
            End Select
    Next i

    Vc pode usar quantos "Case" desejar, assim como "Case Else". Também é possível utilizar outros comparadores, como "Like", "is", etc.

    Abraço.


    Filipe Magno

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 01:44
    segunda-feira, 24 de novembro de 2014 23:38
  • Filipe, boa noite e obrigado pela resposta.

    Não percebo muito de VBA, mas penso que as Case, apenas guardam números, certo? Ou também guarda strings?

    Imagine dois grupos de Checkbox, um grupo constituído por ck1, ck2, ck3, ck4, ck5 e ck6 e outro grupo constituído por ck23, ch24, ck25, ck26, ck27 e ck28.

    No caso de qualquer Checkbox do 1º grupo estar selecionada, a comparação de dados será feita na coluna "F", se a seleção recair em qualquer Checkbox do 2º grupo a comparação será feita na coluna "J". Por isso penso que terá mesmo que ser com dois ciclos For...Next, pelo menos na forma como estruturei o código, pois atribuí variáveis às checkbox desta forma:

          For CHECK = 1 To 6
            If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _
              = Range("G" & lngRow) Then
    

    Para o 1º grupo


    For CHECK = 23 To 28 If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _ = Range("G" & lngRow) Then

    Para o 2º grupo.

    Este código vai dividir strings já divididas anteriormente, formando grupos conforme se segue:

    na string:

    .K86-T90-K53-T93-A21-S01-S02

    Os resultados serão num primeiro passo:

    K86-1

    T90-1

    K53-1

    T93-1

    A21-1

    S01-1

    S02-1

    Depois de correr a rotina que pretendia alterar, os resultados deverão ser:

    K-2

    T-2

    A-1

    S-2

    Entretanto, já está a funcionar como pretendo, sem um único erro excepto no caso de uma label ter valor "0", mas nada que "On Error Resume Next" não possa resolver.

    A proposta do Lucas, que agradeço é válida a não ser pelo facto de não existirem objectos com os nºs entre 7 e 22 inclusivé. Isto não iria dar erro?

    Como sei pouco de Vba, vou ficar com os ciclos For que tenho uma vez que já estão a bater certinho.

    De qualquer forma será possível esse ciclo For...Next com dois intervalos?

    Um obrigado aos dois pois de certa forma abriram-me o caminho para encontrar o erro que faltava ultrapassar.

    Abraços 

    M_A_L


    M_A_L

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 01:43
    terça-feira, 25 de novembro de 2014 01:42
  • M_A_L,

    para lhe ser sincero, não compreendi o que precisa fazer exatamente. Mas apenas para apenas complementar, o "Case" pode conter tanto números, como strings e até mesmo expressões. É uma forma bem flexível para trabalhar em alguns casos.

    No código que vc citou não funcionaria algo do tipo abaixo?

    For Check = 1 To 28
    
        Select Case Check
        
            Case 1 To 6, 23 To 28
                If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _
              = Range("G" & lngRow) Then
    
            End Select
    Next i

    Abraço.


    Filipe Magno

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 12:54
    terça-feira, 25 de novembro de 2014 01:56

Todas as Respostas

  • E se voce adiantar o for ? Tipo assim,

    Dim sForContador as Integer

    For sForContador = 1 to 15

    if sforcontador > 0 and sforcontador <= 4 then

    bloco de codigo

    end if

    if sforcontador >= 10 and <= 15 then

    bloco de codigo

    end if

    Next

    se aplicaria ?

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 01:44
    • Não Marcado como Resposta M_A_S_L sábado, 29 de novembro de 2014 23:41
    • Marcado como Resposta M_A_S_L sábado, 29 de novembro de 2014 23:41
    • Não Marcado como Resposta M_A_S_L sábado, 29 de novembro de 2014 23:42
    segunda-feira, 24 de novembro de 2014 11:59
  • Bom dia amigo Lucas.

    Logo que possa, vou experimentar, no entanto, parece-me tratar-se da mesma situação que tenho e que queria evitar.

    Tenho as duas condições dentro do ciclo For, cada condição com o seu bloco de código que é igual.

    O que pretendia era poupar linhas de código, pois os números no ciclo referem-se a checkbox's que deverão estar ou não marcadas. Se alguma estiver marcada o código corre, se não não é processado passando ao passo seguinte.

    Obrigado, pela pronta resposta.

    Cumprimentos

    MAL


    M_A_L

    segunda-feira, 24 de novembro de 2014 13:05
  • Boa noite M_A_L.

    Penso que no seu caso a resposta seja quase da forma que vc mesmo sugeri. Eu usaria um "Select Case"

    For i = 1 To 20
    
        Select Case i
        
            Case 0 To 4, 10 To 15
                
                '... Seu código
            
            End Select
    Next i

    Vc pode usar quantos "Case" desejar, assim como "Case Else". Também é possível utilizar outros comparadores, como "Like", "is", etc.

    Abraço.


    Filipe Magno

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 01:44
    segunda-feira, 24 de novembro de 2014 23:38
  • Filipe, boa noite e obrigado pela resposta.

    Não percebo muito de VBA, mas penso que as Case, apenas guardam números, certo? Ou também guarda strings?

    Imagine dois grupos de Checkbox, um grupo constituído por ck1, ck2, ck3, ck4, ck5 e ck6 e outro grupo constituído por ck23, ch24, ck25, ck26, ck27 e ck28.

    No caso de qualquer Checkbox do 1º grupo estar selecionada, a comparação de dados será feita na coluna "F", se a seleção recair em qualquer Checkbox do 2º grupo a comparação será feita na coluna "J". Por isso penso que terá mesmo que ser com dois ciclos For...Next, pelo menos na forma como estruturei o código, pois atribuí variáveis às checkbox desta forma:

          For CHECK = 1 To 6
            If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _
              = Range("G" & lngRow) Then
    

    Para o 1º grupo


    For CHECK = 23 To 28 If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _ = Range("G" & lngRow) Then

    Para o 2º grupo.

    Este código vai dividir strings já divididas anteriormente, formando grupos conforme se segue:

    na string:

    .K86-T90-K53-T93-A21-S01-S02

    Os resultados serão num primeiro passo:

    K86-1

    T90-1

    K53-1

    T93-1

    A21-1

    S01-1

    S02-1

    Depois de correr a rotina que pretendia alterar, os resultados deverão ser:

    K-2

    T-2

    A-1

    S-2

    Entretanto, já está a funcionar como pretendo, sem um único erro excepto no caso de uma label ter valor "0", mas nada que "On Error Resume Next" não possa resolver.

    A proposta do Lucas, que agradeço é válida a não ser pelo facto de não existirem objectos com os nºs entre 7 e 22 inclusivé. Isto não iria dar erro?

    Como sei pouco de Vba, vou ficar com os ciclos For que tenho uma vez que já estão a bater certinho.

    De qualquer forma será possível esse ciclo For...Next com dois intervalos?

    Um obrigado aos dois pois de certa forma abriram-me o caminho para encontrar o erro que faltava ultrapassar.

    Abraços 

    M_A_L


    M_A_L

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 01:43
    terça-feira, 25 de novembro de 2014 01:42
  • M_A_L,

    para lhe ser sincero, não compreendi o que precisa fazer exatamente. Mas apenas para apenas complementar, o "Case" pode conter tanto números, como strings e até mesmo expressões. É uma forma bem flexível para trabalhar em alguns casos.

    No código que vc citou não funcionaria algo do tipo abaixo?

    For Check = 1 To 28
    
        Select Case Check
        
            Case 1 To 6, 23 To 28
                If Me.Controls("CheckBox" & CHECK).Value = True And Me.Controls("CheckBox" & CHECK).Caption _
              = Range("G" & lngRow) Then
    
            End Select
    Next i

    Abraço.


    Filipe Magno

    • Marcado como Resposta M_A_S_L terça-feira, 25 de novembro de 2014 12:54
    terça-feira, 25 de novembro de 2014 01:56
  • Boa tarde Filipe.

    Obrigado pelo interesse demonstrado e pela disponibilidade.

    É complicado explicar. Mexe com estatísticas de doenças e sintomas com base na tabela ICPC-2.

    Pretendia fazer tudo com um bloco de código, mas não é possível pois tem demasiadas condicionantes na forma de leitura e processamentos dos dados.

    Ontem, com dois "if" dentro do ciclo consegui o que pretendia por isso dei o tópico como respondido. Não é fácil no entanto explicar todo o enredo necessário. Dividir uma string em grupos de três caracteres, uma letra e dois nºs e depois separar e contar apenas pela letra, isto para cada tipo de consulta médica.

    Mas aprendi algo novo sobre as "Case" que me vai por certo ser útil, pois desta forma posso evitar "If's" a fazer comparações com as Caption de objectos.

    No ciclo que sugere, penso que ao chegar ao nº 7, vai resultar num erro por falta de objecto, já que a checkbox7 não existe, certo?

    Mais uma vêz obrigado pela disponibilidade.

    Cumprimentos

    M_A_L



    • Editado M_A_S_L terça-feira, 25 de novembro de 2014 13:08
    terça-feira, 25 de novembro de 2014 13:06
  • Talvez eu esteja boiando, mas você poderia fazer algo assim:

    Sub pMain()
      Dim v As Variant
      
      For Each v In Array(0, 1, 2, 5, 8, 10, 100)
        Debug.Print v
      Next v
    End Sub
    

    ou:

    Sub pMain()
      Dim ctl As CheckBox
      
      For Each ctl In Array(checkbox1, checkbox5, checkbox10) 'e assim por diante
        Debug.Print ctl
      Next ctl
    End Sub
    


    Felipe Costa Gualberto - http://www.ambienteoffice.com.br

    terça-feira, 25 de novembro de 2014 20:06
    Moderador
  • Boa noite Felipe.

    Como deve compreender, os meus magros conhecimentos de Vba, impossibilitam-me até de conseguir descortinar a melhor forma de resolver uma questão e se tenho que introduzir um novo bloco de código para fazer face a alguma nova exigência que surge, já fico atrapalhado, mesmo quando já entendo determinado código.

    Agora imagine quão pequeno me sinto quando na tentativa de ajudar, me propõem algo que não consigo mesmo entender. Sinto-me assim como uma variável quando é inicializada para zero.

    Os blocos de códigos que propõe permitem associar as checkbox a colunas diferentes (da 1 à 6, Col "F" e da 23 à 28, Col "J") sem utilizar "If" que alongam o bloco de código?

    Não consigo mesmo chegar lá. Pode explicar-me o código?

    Cumprimentos

    M_A_L

     


    M_A_L



    • Editado M_A_S_L quarta-feira, 26 de novembro de 2014 09:23
    quarta-feira, 26 de novembro de 2014 02:04
  • Eu faria algo assim:

    Private Sub CommandButton1_Click()
      Dim ctl As MSForms.Control
      Dim sCol As String
      
      For Each ctl In Me.Controls
        sCol = ""
        Select Case ctl.Name
          Case "ck1" To "ck6" 'ou "ck1", "ck2", "ck3", "ck4", "ck5", "ck6"
            sCol = "F"
          
          Case "ck23" To "ck28" 'ou "ck23", "ck24", "ck25", "ck26", "ck27", "ck28"
            sCol = "J"
        End Select
        
        If sCol <> "" Then
          MsgBox "Caixa de combinação " & ctl.Name & " no laço." & vbNewLine _
          & "Valor: " & ctl.Value & ". Coluna de atuação: " & sCol & ".", vbInformation
        End If
      Next ctl
    
    End Sub

    Será que é possível entender o código facilmente ou há dúvida em alguma parte?


    Felipe Costa Gualberto - http://www.ambienteoffice.com.br

    quinta-feira, 27 de novembro de 2014 00:34
    Moderador
  • Bom dia Felipe.

    Mestre é mestre e está tudo dito.

    Não, não tenho dúvidas na interpretação deste código e reduziu-me o código em muitas, muitas linhas o que por sua vez ajuda a melhorar o desempenho final.

    É que o código que tinha, deveria ser repetido para 14 objetos, apenas com ligeiras modificações inerentes aos próprios objetos e desta forma, em vez de 14 blocos de código fica reduzido a dois.

    Impecável como sempre.

    Um enorme obrigado para si sem esquecer as duas ajudas anteriores.

    Cumprimentos

    M_A_L

    Manuel António


    M_A_L


    • Editado M_A_S_L quinta-feira, 27 de novembro de 2014 08:40
    quinta-feira, 27 de novembro de 2014 08:37