Arquivo da tag: Function

VBA – Saindo do controle de fluxo (comando Exit)

O que é?

A instrução Exit sai de um bloco de código Do…Loop, For…Next, Function, Sub ou Property.

Estrutura:

Exit Do

Fornece um meio de sair de uma instrução Do…Loop. Pode ser usada somente dentro de uma instrução Do…Loop. Exit Do transfere o controle para a instrução seguinte à instrução Loop. Quando usada dentro de instruções Do…Loop aninhadas, Exit Do transfere o controle para o loop que está aninhado em um nível acima do loop onde ocorre Exit Do.

Exit For

Fornece um meio de sair de um loop For. Pode ser usada somente em um loop For…Next ou For Each…Next. Exit For transfere o controle para a instrução seguinte à instrução Next. Quando usada dentro de loops For aninhados, Exit For transfere o controle para o loop que está aninhado em um nível acima do loop onde ocorre Exit For.

Exit Function

Sai imediatamente do procedimento Function em que aparece. A execução continua com a instrução seguinte à instrução que chamou Function.

Exit Property

Sai imediatamente do procedimento Property em que aparece. A execução continua com a instrução seguinte à instrução que chamou o procedimento Property.

Exit Sub

Sai imediatamente do procedimento Sub em que aparece. A execução continua com a instrução seguinte à instrução que chamou o procedimento Sub.

Exemplo

Um exemplo útil para o uso das instruções é Exit é no caso de um loop For…Next. Supondo que estivéssemos buscando um determinado valor dentro de uma coleção de itens de 10 posíções. A alternativa mais comum é verificar a lista item a item comparando-os até que encontrar o item que se deseja. Caso o item estivesse na 10º posição, não haveria tanto problemas. Mas se ele estivesse na 2º posição, porque continuar o executando o código até a 10º posição se já achamos o item?

Veja o código abaixo:

Function ProcuraNome(nome As String) As Boolean
    Dim nomes(10) As String
    Dim i As Long
    Dim quantInteracoes As Long
    Dim resultado As Boolean
 
    nomes(0) = "João"
    nomes(1) = "Maria"
    nomes(2) = "Júlio"
    nomes(3) = "Fabio"
    nomes(4) = "Guilherme"
    nomes(5) = "Roberto"
    nomes(6) = "Francisco"
    nomes(7) = "Juliana"
    nomes(8) = "Fabiana"
    nomes(9) = "Alex"
 
    For i = 0 To 9 Step 1
        quantInteracoes = i + 1
        If nome = nomes(i) Then
            resultado = True
        End If
    Next
 
    MsgBox quantInteracoes
 
    ProcuraNome = resultado
End Function

O código declara uma matriz de tamanho 10 com nomes de pessoas e todas as suas posições. Passando um nome por parâmetro, a função retorna VERDADEIRO se o nome existir na lista e FALSO caso contrário. A matriz é preenchida entre as linhas 7 e 16 e a busca é feita em uma laço For…Next nas linhas 18 a 23.

A variável quantInteracoes foi criada para verificar quantas vezes o laço For…Next do código faz interações, quantidade esta que é mostrada numa caixa de mensagem na linha 25.

Para testar a função, em qualquer célula de sua planilha e digite =ProcuraNome(“João”). Veja que a função retona o valor VERDADEIRO, o que significa que o nome consta na lista. Se informar qualquer outro nome, por exemplo “Sérgio”, a função retornará FALSO. Note que independente do nome informado, exista ele ou não na lista, uma caixa de mensagem com a quantidade 10 sempre. Isso significa que, mesmo que o laço encontre o nome na primeira posição, ele continua executando o laço até a última posição. Se a lista contivesse 1000 nomes, o código ficaria muito demorado.

Mas como apenas queremos saber se o nome existe na lista, não há necessidade de continuar executando o laço quanto a condição da linha 20 for atendida. Então, veja a modificação feita na código:

    ...
    For i = 0 To 9 Step 1
        quantInteracoes = i + 1
        If nome = nomes(i) Then
            resultado = True
            Exit For
        End If
    Next
    ...

Adicionando a cláusula Exit For como feito no código acima, ao atender a condição da linha 20, o código sairá do laço For…Next e continuára a exeução na linha 24. Depóis de fazer a modificação, em qualquer célula de sua planilha e digite =ProcuraNome(“João”). Veja que ao invés do valor 10, a caixa de mensagem mostrará 1. Se colocar =ProcuraNome(“Maria”), a caixa de mensagem apresentará 2 e assim por diante.

Além de evitarmos trabalho desnecesário, aumentamos a performance da função para a maior parte dos casos em que ela for utilizada.

Comentários

Não confunda instruções Exit com instruções End. Exit não define o fim de uma estrutura.

Como a instrução Exit desvia a execução do código, é aconselhável usá-la somente se o código da função estiver bem estruturado, principalmente para os casos de Function e Sub.

VBA – Ocultando Funções e Macros para o Usuário

Quanto construímos funções e macros personalizadas em nossos programas feitos no VBA em Excel e Word, precisamos expô-las para que sejam acessadas por outros módulos ou mesmo Forms. Para isso, declaramo-as como Public ou simplesmente ocultamos o modificador de acesso que é Public por padrão.

Um inconveniente do VBA é que nossas Functions e Subs ficam disponíveis para o usuário quando este abre a janela de execução de macros (Alt+F8). Isso pode gerar uma série de situações inesperadas, além de erros.

Para que as funções desenvolvidas como Public no VBA não apareçam na caixa de diálogo de execução de macros, basta que na janela de código, seja um Módulo ou UserForm seja colocada a seguinte diretiva no cabeçalho:

Option Private Module

Experimente agora abrir a caixa de diálogo de execução de Macros ou no Excel, acessar a caixa de diálogo Inserir Função selecionar a  opção “Definida pelo usuário” e veja que as Functions e Subs dentro do módulo com a declaração acima.

Note também que a declaração só oculta o código VBA neste escopo. As Functions e Subs continuarão disponíveis para todo o aplicativo VBA, não afetando o aplicativo.

Bom proveito!

Referências:

http://www.allexperts.com/

Tomás

VBA – As diferenças entre Sub e Function

Introdução

O VBA possui dois tipos de estruturas para construção de algoritmos, Sub e Function.

A questão que surge é, quando usar uma ou outra na construção de nossos algoritmos em VBA no Excel? Na prática, Sub e Function trabalham da mesma forma com uma única diferença. A Sub são funções de processamento autônomo enquanto as Functions podem (e devem) retornar valores no final de sua execução.

Veja a estrutura de cada uma:

Sub ExemploSub([parâmetros])
     ' corpo do código
End Sub

onde:

[modificador] são palavras chave que definem o nível de acesso à estrutura de código.

[parâmetros] são variáveis que são passadas na chamada da função e utilizadas dentro. Podem existir vários ou mesmo nenhum parâmetro.

[tipo] é o que informa o tipo de dado a ser retornado pela Function. Pode ser qualquer tipo de dados válido do VBA.

[valor] uma valor que representa o retorno da função. Pode ser uma variável ou um valor constante.

Como saber qual utilizar? Isto depende do contexto da sua aplicação. Quando sua rotina precisar simplesmente executar uma processamento sem emitir qualquer tipo de informação, é aconselhável usar uma Sub. Já quando seu processamento necessitar devolver algum resultado, sem dúvida uma Function é necessária. Supondo uma situação em que você precisa criar funções que executassem operações aritméticas, elas precisariam depois de efetuar os cálculos, devolver o resultado para ser utilizado.

Veja este exemplo:

Public Function SomaSimplesF(x As Long, y As Long) As Long
    SomaSimplesF = x + y
End Function

O código efetua uma operação simples recendo duas variáveis do tipo Long como parâmetro e devolve também um Long (definido na construção da Function) através da chama SomaSimples na linha 2. Para testar as função, basta ir a uma célula da planilha e digitar =SomaSimplesF(1;3). É possível também testar a função através de código VBA, como no código abaixo:

Public Sub TestaSomaSimplesF()
    Dim soma As Long
    'chama a função SomaSimplesF e atribui o resultado à variável soma
    soma = SomaSimplesF(1, 2)
    'mostra o resultado em uma caixa de mensagem
    MsgBox soma
End Sub

Já se este exemplo fosse construído usando uma Sub, não seria possível diretamente retornar o valor como é feito na Function.  A solução então seria mostrá-lo ao usuário, por exemplo em uma caixa de mensagem. Veja este exemplo:

Public Sub SomaSimplesS(x As Long, y As Long)
    MsgBox = x + y
End Sub

Para testar a função, é precisa criar outro bloco de código que faça a chamada a este. Crie a seguinte função para testar o SomaSimplesS:

Public Sub TestaSomaSimplesF()
    'Faz a chamada a Sub SomaSimplesF
    Call SomaSimples(1, 2)
End Sub

Veja que o Sub não tem sequer a opção de mencionar o tipo de dado que pode ser retornado.

No Microsoft Excel, as Functions possuem uma característica especial. Elas podem ser usadas para criação de funções de planilha. A exigência para que isso seja possível, é criá-las com o modificador Public, que é o padrão
caso seja omitido.

Dentro deste entendimento, uma Function sempre poderá assumir o papel de uma Sub, mas não o contrário. Também por isso, o Excel utiliza Functions para criação de funções de planilha personalizadas e Subs para gravação de Macros.

Para superar a limitação do retorno de um único valor ou mesmo conseguir retornar alguns valores em Subs, é necessária a utilização passagem de parâmetros por referência. Este assunto será discutido em outro texto.

Comentários

Alguns podem pensar que por segurança, é melhor sempre criar Functions ao
invés de Subs. Porém, para termos de organização de código e padronização
de suas rotinas em VBA, procure usar a estrutura correta para ter um bom
funcionamento de seu aplicativo.