Tag Archives: InputBox

VBA – Excluindo linhas em branco no Excel

De vez em quando a Microsoft é mãe. Além de fornecer a ferramenta (guardadas as devidas proporçõe$), fornece vários exemplos de como resolver os problemas com elas. Seria esse o valor agregado?

Enfim, mas uma dúvida frequente em emails de fóruns é pelo VBA conseguir excluir as linhas que estão em branco ou vazias em uma planilhas. Outros códigos já disponibilizados aqui no fórum já promovem a façanha com um pequeno ajuste. Mas, para quem quer um código mais focado, a própria Microsoft disponibiliza a seguinte Macro:

' The following code deletes blank rows from the active worksheet.
 
Dim Counter
Dim i As Integer
 
Sub DelRow()
 
' Input box to determine the total number of rows in the worksheet.
    Counter = InputBox("Enter the total number of rows to process")
    ActiveCell.Select
    ' Loops through the desired number of rows.
    For i = 1 To Counter
        ' Checks to see if the active cell is blank.
        If ActiveCell = "" Then
            Selection.EntireRow.Delete
 
            ' Decrements count each time a row is deleted. This ensures
            ' that the macro will not run past the last row.
            Counter = Counter - 1
        Else
            ' Selects the next cell.
            ActiveCell.Offset(1, 0).Select
        End If
 
    Next i
 
End Sub

A parte bacana é que o código, ao ser executado, ele mostra um InputBox solicitando a quantidade de linhas que serão processadas, ou avaliadas. É uma boa, pois você pode não querer varrer todas as linhas de uma planilha certo?

O link original é:

http://support.microsoft.com/kb/110759/pt-br

Bom proveito!

VBA – Otimizando a entrada de dados com o InputBox

Em várias situações do dia a dia, precisamos coletar informações dos usuários para o correto funcionamento de nossas planilhas.

Isso normalmente é feito através de células evidenciadas através de formatação e outros recursos visuais. É possível até forçar a validação do valores de entrada, mas mesmo assim, não temos a garantia de que as informações foram coletadas. Para estas situações, o VBA disponibiliza uma função simples e muito eficaz, a função InputBox.

Com uma chamada simples, uma caixa de diálogo é mostrada ao usuário, disponibilizando também um caixa de texto para que este digite um valor de entrada.

Para simular o uso da função InputBox, imagine que você possui uma lista produtos cujos valores se baseiam na cotação do dólar do dia. O valor da cotação do dólar precisa ser informado, ou os cálculos não irão refletir os valores corretos dos produtos, podendo causar muitos problemas.

A idéia é tentar forçar com que o usuário insira o valor da cotação do dólar antes de efetuar qualquer operação na planilha. Porque não fazê-lo no momente em que este abre a pasta de trabalho? Para possibilitar isso, abra um novo arquivo do Microsoft Excel. Acione o VBA clicando em Ferramentas->Macros->Editor do Visual Basic ou clicando o atalho Alt+F11. A janela do VBA será mostrada conforme abaixo:

Janela de Projeto VBA

O que faremos é capturar o evento que é disparado quando uma pasta de trabalho é aberta. Para isso, dentro do VBA, na janela de Projeto, procure o item EstaPata_de_trabalho e clique duas vezes sobre ele para abrir a tela de código:

Janela de Projeto VBA

Com a tela de código aberta, logo acima da tela de código, existem duas caixas de seleção. Clique na caixa da esquerda e selecione o item Workbook:

Janela de Projeto VBA - Selecionando o objeto e o evento

Ao fazer isso, o código do evento que é disparado ao abrir a pasta de trabalho de nome Workbook_Open é criado conforme a seguir:

1
2
3
Private Sub Workbook_Open()
 
End Sub

É dentro deste código que trabalharemos com o InputBox. Como tudo o que estiver neleé executado quando o arquivo é aberto, vamos solicitar que o usuário que digite o valor da cotação do dólar no InputBox e colocar este valor em uma determinada célula. Supondo que a célula que contém o valor da cotação seja a célula A1 da Plan1, o código seria o seguinte

1
2
3
4
5
6
7
Private Sub Workbook_Open()
    Dim cotacao As String
 
    cotacao = InputBox("Digite a cotação do dólar do dia: ", "Cotação", "2,00")
 
    ThisWorkbook.Worksheets("Plan1").Range("A1").Value = cotacao
End Sub

O código declara uma variável na linha 2 que armazenará o valor da cotação informado pelo usuário. Ela precisa ser uma String pois é o tipo de retorno do InputBox. Em seguida, o valor da cotação é solicitado através do InputBox na linha 4 e armazenada na variável cotação. O resultado é colocado na célula A1 da planilha Plan1 na linha 6.

Execute o procedimento clicando em F5 ou fechando a planilha e abrindo-a novamente (lembre-se de ativar as macros). Veja o resultado:

InputBox em funcionamento

Clique em OK e veja o valor inserido na célula A1 da planilha Plan1:

A planilha com o valor digitado no InputBox

Com isso, temos o valor informado pelo usuário colocado em uma célula desejada. Tudo isso ocorre normalmente, se tudo for feito de forma correta pelo usuário

Porém, no código acima, temos dois problemas. O primeiro é, caso o usuário não informe um valor clicando no botão cancelar, o aplicativo retornará um erro. O segundo é, se a célula não estiver implicitamente configurada para valores numéricos, ela considerará o conteúdo no formato texto, que é o tipo padrão da variável cotacao. Tentaremos resolver os dois problemas de uma vez. Veja o código abaixo:

1
2
3
4
5
6
7
8
9
Private Sub Workbook_Open()
    Dim cotacao As String
 
    While cotacao = ""
        cotacao = InputBox("Digite a cotação do dólar do dia: ", "Cotação", "2,00")
    Wend
 
    ThisWorkbook.Worksheets("Plan1").Range("A1").Value = CDbl(cotacao)
End Sub

As mudanças feitas no código tratam o problema da seguinte maneira:

Na linha 4 a 6, a chamada do InputBox foi colocada dentro de um loop While com a condição de, caso a variável cotacao esta com o valor “”, ou seja, vazia, o que significa que o usuário clicou no botão cancelar, ele voltará a chamar o InputBox e isso acontecerá até que ele insira um valor e clique em OK. Na linha 8, ao invés de atribuir diretamente a variável cotacao à célula, usa-se a função CDbl() que força a conversão da variável passada por parâmetro para o tipo numérico Double.

Isso faz com que o valor seja passado com o formato numérico diretamente para a célula.

Execute o procedimento clicando em F5 ou fechando a planilha e abrindo-a novamente (lembre-se de ativar as macros). Ao aparecer a caixa de diálogo, tente clicar no botão Cancelar e veja o que acontece.

Conclusão

É possível melhorar mais ainda a inclusão de valores, fazendo verificações com funções de validação de tipo como foi o caso da CDbl(), usada neste artigo. Assim, o InputBox torna-se uma alternativa muito elegante para coletar dados do usuário.

VBA – A diferenças entre InputBox e Application.InputBox

Introdução

O VBA disponibiliza além da tradicional função InputBox, um método de nome Application.InputBox. A principal questão é, já que existem duas, qual se deve utilizar?

A principal diferenção entre elas é que, a função InputBox é uma maneira simples de capturar textos introduzidos pelo usuário. Já o método Application.InputBox é capaz de verificar automaticamente o tipo de dados que deve ser inserido na caixa de texto do caixa de diálogo mostrada.

Estrutura do Application.InputBox

Application.InputBox(Prompt, Title, Default, Left, Top, HelpFile, HelpContextId, Type)

Prompt

String necessário. A mensagem a ser exibida na caixa de diálogo. Pode ser uma seqüência de caracteres, um número, uma data ou um valor Boolean (o Microsoft Excel converte o valor automaticamente em um String antes de exibi-lo).

Title

Variant opcional. O título da caixa de entrada. Se esse argumento for omitido, o título padrão será “Entrada”.

Default

Variant opcional. Especifica um valor que aparecerá na caixa de texto quando a caixa de diálogo for inicialmente exibida. Se esse argumento for omitido, a caixa de texto será deixada vazia. Esse valor pode ser um objeto Range.

Left

Variant opcional. Especifica uma posição x para a caixa de diálogo em relação ao canto superior esquerdo da tela, em pontos.

Top

Variant opcional. Especifica uma posição y para a caixa de diálogo em relação ao canto superior esquerdo da tela, em pontos.

Help File

Variant opcional. O nome do arquivo de ajuda para essa caixa de entrada. Se os argumentos HelpFile e HelpContextID estiverem presentes, um botão Ajuda aparecerá na caixa de diálogo.

Help ContextId

Variant opcional. O número de identificação do contexto do tópico da Ajuda em HelpFile.

Type

Variant opcional. Especifica o tipo de dados retornado. Se esse argumento for omitido, a caixa de diálogo retornará texto. Pode ser um dos valores abaixo ou a soma deles.

clip_a04[1]

Exemplo

Note que a única diferença desta para a função InputBox, é a existência do último parâmetro, o Type. É este que permite fazer validações de tipos simples do VBA para retorno da função. Veja o código de exemplo:

1
2
3
4
5
Public Sub TesteAppInputBox()
Dim num As Long
num = Application.InputBox("Digite um valor numérico", "Application.InputBox", "Valor numérico", , , , , 1)
MsgBox "O valor digitado foi: " & num
End Sub

No código, os parâmetros Left, Top, HelpFile e HelpContextId foram omitidos por não serem necessários para este exemplo. O importante neste código é o parâmetro Type que foi informado. Conforme a tabela, o valor 1 significa que o Application.InputBox espera que um valor numérico seja inserido pelo usuário. Execute a função e veja o resultado:

clip_d76[1]

Informe um valor de texto qualquer na caixa de entrada e clique em OK para ver o resultado:

clip_28a[1]

Veja que não necessário nenhuma verificação via código VBA. O Applcation.InputBox somente precisa da informação sobre o tipo de dado que deve ser esperado pelo usuário. Informe um valor numérico qualquer e clique novamente em OK:

clip_0e6[1]

Você pode usar a soma dos valores permitidos para Type. Por exemplo, para uma caixa de entrada que possa aceitar tanto texto como números, defina o parâmtro Type como 1 + 2.

Comentários

Use InputBox para exibir uma caixa de diálogo simples para que você possa inserir informações a serem usadas em uma macro. A caixa de diálogo tem um botão OK e um botão Cancelar. Quando você escolhe o botão OK, InputBox retorna o valor inserido na caixa de diálogo. Quando você clica no botão Cancelar, InputBox retorna False.

Quando Type é 0, InputBox retorna a fórmula na forma de texto — por exemplo, “=2*PI()/360”. Se houver quaisquer referências na fórmula, elas serão retornadas como referências de estilo A1. (Use ConvertFormula para fazer a conversão entre estilos de referências).

Quando Type é 8, InputBox retorna um objeto Range. Você precisa usar a instrução Set para atribuir o resultado a um objeto Range, como mostrado no exemplo seguinte.

1
Set meuRange = Application.InputBox(prompt := "Exemplo", type := 8)

Se você não usar a instrução Set, a variável será definida com o valor no intervalo em vez do próprio objeto Range.

Se você usar o método InputBox para pedir uma fórmula ao usuário, você terá que usar a propriedade FormulaLocal para atribuir a fórmula a um objeto Range. A fórmula de entrada deverá estar no idioma do usuário.

O método InputBox difere da função InputBox porque permite validação seletiva da entrada do usuário e aceita objetos, valores de erro e fórmulas do Microsoft Excel. Observe que Application.InputBox chama o método InputBox e InputBox sem qualificador de objeto chama a função InputBox.

VBA – Utilizando InputBox com Máscara (senha)

InputBox com Senha
InputBox com Senha

Tirado o blog do Luiz Cláudio que tirou do excelfiles.com. Aí vai mais uma referência.

O InputBox é função extremamente prática para coletar dados de maneira rápida ao usuário. Porém, seria muito bacana se fosse possível estender algumas de suas possbilidades. Uma delas seria se, por exemplo, fosse possível adicionar uma máscara de forma que o usuário pudesse digitar uma senha no InputBox.

Pois bem. A macro abaixo faz exatamente isso:

'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'http://www.danielklann.com/
'March 2003
 
'// Kindly permitted to be amended
'// Amended by Ivan F Moala
'// http://www.xcelfiles.com
'// April 2003
'// Works for Xl2000+ due the AddressOf Operator
'////////////////////////////////////////////////////////////////////
 
'API functions to be used
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
                                                      ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
 
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _
                                         ByVal lpModuleName As String) As Long
 
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
                                          ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) _
                                          As Long
 
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
 
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" ( _
                                            ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, _
                                            ByVal lParam As Long) As Long
 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, _
                                                                          ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
 
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
 
'Constants to be used in our API functions
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5
Private Const HC_ACTION = 0
 
Private hHook As Long
 
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
    Dim RetVal
    Dim strClassName As String, lngBuffer As Long
 
    If lngCode < HC_ACTION Then
        NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
        Exit Function
    End If
 
    strClassName = String$(256, " ")
    lngBuffer = 255
 
    If lngCode = HCBT_ACTIVATE Then    'A window has been activated
        RetVal = GetClassName(wParam, strClassName, lngBuffer)
        If Left$(strClassName, RetVal) = "#32770" Then    'Class name of the Inputbox
            'This changes the edit control so that it display the password character *.
            'You can change the Asc("*") as you please.
            SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0
        End If
    End If
 
    'This line will ensure that any other hooks that may be in place are
    'called correctly.
    CallNextHookEx hHook, lngCode, wParam, lParam
 
End Function
 
'// Make it public = avail to ALL Modules
'// Lets simulate the VBA Input Function
Public Function InputBoxDK(Prompt As String, Optional Title As String, Optional Default As String, _
                           Optional Xpos As Long, Optional Ypos As Long, Optional Helpfile As String, _
                           Optional Context As Long) As String
 
    Dim lngModHwnd As Long, lngThreadID As Long
 
    '// Lets handle any Errors JIC! due to HookProc> App hang!
    On Error GoTo ExitProperly
    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)
 
    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
    If Xpos Then
        InputBoxDK = InputBox(Prompt, Title, Default, Xpos, Ypos, Helpfile, Context)
    Else
        InputBoxDK = InputBox(Prompt, Title, Default, , , Helpfile, Context)
    End If
 
ExitProperly:
    UnhookWindowsHookEx hHook
 
End Function

Para fazê-la funcionar, adicione o código acima a um módulo e use a seguinte chamanda:

1
2
3
Sub Teste()
    MsgBox InputBoxDK("Digite sua senha", "Atenção", "123456")
End Sub

Funciona muito bem. Agradecimentos ao autor da macro, o MVP inglês Daniel Klann.