Notifications
Clear all

Exit Sub, Goto Fim: End Sub

13 Posts
3 Usuários
0 Reactions
3,841 Visualizações
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

inicialmente eu usava algo como

se não atender então Goto fim
...
fim:
executar operações extras
end sub

depois passei a usar Exit Sub direto
mas me veio a duvida sobre existência sobre diferenças entre eles no termino apropriado de uma macro
fiz uma pesquisa e achei algumas referencias, mas como uso o tradutor fiquei com duvidas
http://www.fmsinc.com/free/newtips/vba/ ... Exits.html
http://www.mrexcel.com/forum/excel-ques ... t-sub.html

parte de uma macro que eu uso
nessa eu faço todas as verificações possíveis logo no inicio
mas tem macros que estou usando Exit Sub depois de varias atribuições e chamadas


Sub FiltraAcertos()    'filtrox)
    If Limit = 1 Then GoTo fim
    Dim Dez_val(), CoL_Or(), CoL_De(), coxin()
    Inicio

    valf = Setor_Ori1.Value: aby = Plan_Ori1.Value
    If aby = "PLanAtiva" Then aby = Limit(1)

    If valf <> "Setor" And valf <> "" Then
        If Setor_Destino.Value = "" Then
            Dest = valf
            Call SetorL(Dest)
            If Not_Setor = 1 Then GoTo fim
        Else
            Dest = Setor_Destino.Value
        End If

        Call SetorL(valf, aby)
    Else
        GoTo fim
    End If
    With Sheets(aby)
...
...
fim:
    Final
End Sub

sera que devo trocar tudo por Goto fim e pular para o End Sub ?

 
Postado : 19/06/2015 5:42 am
(@wagner-morel-vidal-nobre)
Posts: 4063
Famed Member
 

Edcronos,

Bom dia!

Dentro do meu pouco conhecimento, não alcanço muito onde isso pode alterar a execução de uma macro...

Fico aqui também na dependência de esclarecimentos de nossos colegas mais experientes em VBA.

 
Postado : 19/06/2015 6:19 am
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

Wagner
pelo que entendi não é bem a execução da macro que é afetada
como o vba tem coletores que terminam as tarefas e fazem a limpeza da memoria
ao meu ver o Exit sub é tão brusco que não limpa a memoria das atribuições feitas durante a macro

mas não sei se entendi bem,

 
Postado : 19/06/2015 6:52 am
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

estava lembrando de outra situação
viewtopic.php?f=10&t=11171&p=58734#p58734

tentei usar o "End"
mas ele encerra todas as macros e user forms abertos, não apenas os diretamente ligados

sobre o end sub e exit sub,
acho que para se ter uma melhor resposta somente com testes para se ter uma ideia,

para pequenos projetos ou para os que ficam pouco tempo abertos pouco importa,
mas para os que ficam muito tempo em execução , e/ou são de relativa complexidade, acho que vale a pena a verificação desse fator

 
Postado : 19/06/2015 8:22 am
(@wagner-morel-vidal-nobre)
Posts: 4063
Famed Member
 

Sei...

Aguardemos então outras opiniões.

 
Postado : 19/06/2015 8:24 am
(@gtsalikis)
Posts: 2373
Noble Member
 

Primeiramente, "end sub" é uma declaração, ou seja, ele serve para informar "aqui acabou a minha sub" por isso, toda sub tem um "end sub" obrigatório, do mesmo modo que toda function tem um "end function".

O comando "exit" (exit sub) serve exatamente para dizer que a sub deve ser interrompida. Em códigos curtos, ele até poderia ser utilizado sem nenhum problema.

O caso é que, como boas práticas de programação, deve-se evitar o "exit sub", pelo mesmo motivo que deve-se evitar o "goto" - ou seja, para não deixar esses comandos perdidos no meio do código atrapalhando (quando se tem mta programação, issoo se torna um pesadelo ficar interrompendo comandos e pulando de um lado para outro).

Por exemplo, problemas que podem ocorrer quando você usa muito "exit sub" e "goto" (se vc tiver muito código):

1. vc copiou algum código de uma sub pra outra e ficou com um "exit sub" perdido, que te atrapalhou;
2. vc acaba indo e voltando com "goto"s e o código se perde ou dá erro com as variáveis
3. vc interrompo o código (exit sub), sem ter reabilitado algo que desabiitou previamente
entre outros...

Assim, a prática ideal seria algo assim seguinte:

Sub Executar ()
'On error goto TRATARERRO

Dim PROSEGUE as Boolean

PROSEGUE = True
'use a variável prossegue em cada bloco dentro do código, para executá-lo ou não

'BLOCO 1
If PROSSEGUE then
'Seu código
End if

'BLOCO 2
If PROSSEGUE then
'Seu código
'Para encerrar a execução da sub, é mais seguro o seguinte:
PROSSEGUE = False
End if

'BLOCO 3
If PROSSEGUE then
'Seu código
'Para encerrar a execução da sub (caso esteja dentro de um loop, é mais seguro alterar a variavel prossegue e sair do loop:
For i = 1 to 1000
If cells(i, "A").value = "valor procurado" then
PROSSEGUE = False
Exit For
End if
Next i
End if

'COMANDOS AO FINAL DO CODIGO
'procedimentos para limpar memória, variáveis, etc
'procedimentos para reabilitar o que foi desabilitado para a execução do código, etc
Exit sub

TRATARERRO:
'procedimentos para tratar erros
End Sub

PS: eu li os links que o Ed postou, um deles explica a parte de usar uma variável booleana no lugar do Exit Sub, o outro não fala nada interessante, rs

Abs

 
Postado : 20/06/2015 10:37 pm
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

Então não tem nada a ver com termino adequado da macro ?
se é apenas com a estruturara do codigo é algo inerente ao goto da pessoa

isso de verdadeiro ou falso para sair da sub para mim ficou muito mais Difícil de entender e aplicar

Se a estrutura da macro pede para ser encerrado naquele ponto, se continuar é que vai gerar erros e confusões na logica
se a logica da macro tem uma dependência para sair OU não da macro, acho que um IF Then é mais aplicável,

não vejo pq alguem colocaria um Exit sub no meio do código sem ser necessário .

como se falou, em macros com muitas linhas, pode ser dificil de acompanhar a logica da macro
mas não vejo como isso seria problemático hoje em dia e ainda mais com o vba do excel

as macros podem ser subdividas ,
tem bandeiras de posição no caso do Go to e Go sub
então não ficam monstros de mais de 2000 linhas com goto pulando para numeros de linhas

depois eu faço uns testes com end e exit sub em uma macro cheia de declarações de variaveis

 
Postado : 21/06/2015 1:09 am
(@gtsalikis)
Posts: 2373
Noble Member
 

Ed, não encontrei nada que relacione com o término da macro, pode ser que alguém apareça com alguma informação extra.

Sobre o restante:

Essa parte de verdadeiro ou falso que eu apresentei, não seria para sair da sub, mas para executar ou não executar blocos dentro da sub. Como falei antes, essa é a recomendação do segundo link que vc postou. Quando se trabalha com grandes códigos, se vc segue testando o código, vc vai querer "pular alguns blocos no teu teste". O modo mais rápido que a maioria das pessoas faz é comentar as linhas do código. Quando se tem um bloco com até 10 linhas, ainda vai. Passando disso, fica realmente chato vc comentar/descomentar todas as linhas, 1 por 1. Ai é que entra a ideia de vc colocar todo o bloco dentro do If. Não é complicado, é questão de necessidade - eu também não gostava, mas teve momentos em que eu vi que essa era a melhor forma de pular blocos.

Além disso, se vc tentar usar vários formulários, não tem como controlar eventos usando "application.enableevents", então vc vai ter que usar a dica acima. Faça o teste pra vc ver.

Sobre colocar um exit sem ser necessário - creio que vc não entendeu. Eu não disse que alguém vai fazer isso. Eu disse que alguém vai COPIAR E COLAR. O mais normal em grandes programas é ter que usar os mesmos blocos, ou blocos quase identicos de programação. O que se faz é escrever um bloco, e depois copiar e colar para outras subs, e depois ajustar os detalhes, nesse ponto pode-se deixar um "exit" perdido.

Da mesma forma, imagine um código com milhares de linhas. Você passa meses programando tudo. De repente, dá um erro, ai vc tem que voltar e rever TUDO o que foi programado, e nisso pode ter passado um "exit" despercebido, ou, eventualmente, como todo programador, vc interrompeu o código para testar, e esqueceu de corrigir isso.

Da mesma forma, é problemático sim, acompanhar códigos, ainda mais hoje em dia. Em grandes programas, xistem vários programadores trabalhando ao mesmo tempo. Depois de tempo, chega-e à fase final, que basicamente se resume em corrigir erros. Se cada um ficar colocando interrupções e saltos (goto's), todo mundo vai enlouquecer. Ou seja, é preciso estabelecer um padrão.

Veja: mesmo em códigos pequenos, vc diz que é confuso seguir essas orientações. Eu, por outro lado, digo que é confuso encher de goto's e exit's. Se nós 2 tentássemos trabalhar juntos, não iria funcionar. Isso, como eu disse, em códigos pequenos. Agora imagine em códigos grandes. A solução seria uma só: mandar 1 de nós 2 embora e contratar outro, para que todos trabalhem da mesma forma.

Se, porém, vc quiser trabalhar sozinho e encher os teus códigos de goto's e exit's, fique à vontade.

Ah, outra coisa: sobre dividir macros. A estrutura de uma sub envolve blocos, como já disse. Essa é a subdivisão da sub. Se vc colocar um monte de gosub ou call macro, é a mesma coisa que colocar um monte de goto's. Eu entendo que dividir macros não é o caminho, mas sim, ter macros específicas. Quero dizer: não acho certo dividir uma macro só porque vc quer economizar linhas de programação. Para isso, crie um bloco e copie-cole onde precisar. Agora, para funções mais genéricas, vc deve ter uma macro em separado - por exemplo, uma macro para tratamento de erros ao final da sub, ou uma macro para limpar memória, uma para bloquear a planilha, e por ai vai.

PS: apenas a título de curiosidade: programar não se resume a dar instruções para se chegar a um resultado, mas a ter controle de tudo o que está acontecendo. Eu já li vários relatos de hackers que invadiram sistemas de segurança simplesmente porque atacaram uma variável.

Abraço

 
Postado : 21/06/2015 9:50 am
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

gtsalikis bem explicativo a sua explicação para a sua resposta :P

não quero entrar em outra guerra de conceitos
Sim, em trabalho em conjunto tem que se seguir as regras da maioria
igual quando eu falei para o fernando que quando ele me contratasse eu ia ter que seguir as regras impostas

mas em se trabalhando sozinho vai pelo gosto como tinha falado,

eu mesmo me sinto confortável em escrever e analisar códigos quebrados com goto, gosub e nomes de variaveis pequenos (mó bagunça)
bem, minhas macros são mais genéricas e a maioria é mais de pesquisa e comparação como algumas que postei aqui

vc falou em 10 linhas,
agora imagina 100 linhas com algo como isso ?...

...
    For L = UBound(CoL_Or, 1) To 2 Step -1  
        For C = 4 To Cf1 
            v = CoL_Or(L, C)
            If v <> "" Then
                For cg = 1 To cfg  
                    If Dez_val(cg) = v Then  
                        If Ant_Actv = 1 Then 
                            For C2 = 4 To Cf1
                                v2 = CoL_Or(L - 1, C2)
                                If v2 <> "" Then
                                    For cg2 = 1 To cfg2
                                        If Dez_ant(cg2) = v2 Then GoTo cgf1
                                    Next   
                                End If  
                            Next   
                            GoTo cgf2
                        End If    'Ant_Actv
cgf1:
...

não sei oq é esse evento application.enableevents
meus formulários são simples

sobre dividir codigos acho que depende muito da organização que se faz, fica igual a classes

sobre invasões de sistemas, desconheço as demandas da área em relação a estrutura e proteção,
nem sei como ficam as variáveis em um sistema assim
mas se dependente de segurança, o sistema tem que passar por diversas baterias de ataque teste e ou trabalhar em camadas diferentes da rede ou mascarada para evitar ataques externos
internet<-->firewall<-->Rede interna<-->sistema de permissões <--// mascara de rede//--> servidor<-->banco de dados "ou algo assim (apenas um chute) "

Ps. não fui eu que escrevi nem defini as variáveis desse sistema invadido :D

se falou qeu as regras facilita as correções, mas talvez tbm facilite as invasões, isso por se ter um padrão pré definido de escrita e estrutura e que todo mundo conhece

PS4: não estou tentando fazer um jogo em primeira pessoa, nem fazer um sistema operacional igual ao win ou linux,
apenas estou tentando descobrir o "próximo" resultado da megasena :D ( o chato é que nem coragem de jogar eu tenho :|)
se bem que seria algo que ninguem fez até hoje
tá bom, é apenas um sistema de cruzamento de dados e eu estou usando esse troço pq é mais facil e os dados são simples ,
mas não custa sonhar né ...

 
Postado : 21/06/2015 12:08 pm
(@gtsalikis)
Posts: 2373
Noble Member
 

Cara, se tu ganhar na megasena, lembra dos amigos, kkkkk.

De resto, como falei, se vc trabalha sozinho e faz algo para você mesmo, use o sistema que vc achar melhor, mas tenha em mente que a grande maioria das pessoas segue alguns padrões.

No meu caso, a maioria dos padrões eu criei por "quebrar a cara", ou por "perder muito tempo".

Mas dá uma pesquisada no application.enableevents - se vc usa eventos, não pode deixar de conhecer.

 
Postado : 21/06/2015 2:04 pm
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

memoria é uma droga
eu não uso eventos mas já fiz algumas macros que usam e e tem o application.enableevents para o pessoal do forum

como o clonar range
download/file.php?id=13350

acho que mesmo da maneira maluca de escrever as macros eu consegui fazer algumas coisas legais
no forum eu coloquei pouca coisa mas na minha planilha tem um monte :P

tem esse conta repetidos que eu usei pela primeira vez o gosub para intercalar 2 loops , hoje nem uso mais assim, uso da maneira que postei la em cima

download/file.php?id=13349
essa função eu fiz para um cara aqui do forum para bingos,
mas se mostrou muito eficaz para comparar tabelas, e eu já fiz um monte de filtros com a ideia

nessa eu uso o Goto para fazer um Do Loop
ela retona o concurso em que todas as dezenas de 1 até 60 foi sorteado a partir de um concurso inicial,
fiz essa função para uma pessoa de outro forum,
até hoje não sei a utilidade pratica disso, só sei que que na planilha dele falta o 54 para fechar o ciclo, o 60 que estava atascado junto do 54 saiu no sabado

Function CicloTo(concursoNum As Long)

    Dim valt(1 To 60) As Long, linSort()
    With ThisWorkbook.Worksheets("Mega-Sena")

        lf = .Cells(Rows.Count, 1).End(xlUp).Row + 1
        L = concursoNum + 1
ijSini:

        linSort = .Range("C" & L, "H" & L).Value2
        For v = 1 To 6
            valt(linSort(1, v)) = 1
        Next
        If L < lf Then
            For v = 1 To 60
                If valt(v) = 0 Then L = L + 1: GoTo ijSini:
            Next
        End If
    End With
    CicloTo = L - 1

End Function

talvez com certa adaptação sirva para retornar espaço vago ou itens faltantes em tabelas :P "eu já coloquei ela para usar array e ser mais eficiente, alem de retornar quantas vezes cada item saiu no ciclo"

como pode ver eu gosto e uso bastante, e se vc está falando que fica dificil analisar, pelo menos o pessoal para roubar a ideia vai ter que esquentar os neurônios
(mas na boa, acho que o funcionamento da macro ficou muito na cara para vc não entende)

 
Postado : 21/06/2015 3:06 pm
(@gtsalikis)
Posts: 2373
Noble Member
 

Os comandos são bem simples, não é difícil entender. Mas eu sou perfeccionista, isso faz doer a cabeça, do mesmo jeito que essas imagens tb fazem:
http://www.smosh.com/smosh-pit/photos/2 ... ists-crazy

 
Postado : 21/06/2015 4:57 pm
(@edcronos)
Posts: 1006
Noble Member
Topic starter
 

essas imagens no máximo me irritam "algumas"
aprendi a levar em conta as irregularidades do mundo,

o pior é que tem coisas por aí que o pessoal chama de obra de arte que parece quebra cabeça montado por um chipanzé ou um quadro pintado por ..."vai saber"
o pessoal dá valor só pq fulano tem e ciclano falou bem,
acaba virando uma bola de neve de mau gosto " e super valorizado",
e todos vestindo a roupa invisível só para não ser o único burro... tá bom... gosto não se discute.

em relação as macros, no caso dessa ultima função, é bem simples, mas como ficaria sem esse goto ?
se bem que já saiu do teor inicial da pergunta

 
Postado : 21/06/2015 7:59 pm