Você está na página 1de 53

Date

End Sub

Sub OutputMessage(Value As Long)


MsgBox Value
End Sub

Sub WriteValueToSheet(Value As Long)


Range("A1").Value = Value
End Sub

Sub WriteCalculation()
Dim mathCalc As Long
mathCalc = 5 * 4 * 3 * 2 * 1

LogMessageToConsole (mathCalc)
OutputMessage (mathCalc)
WriteValueToSheet (mathCalc)
End Sub

Os 3 primeiros códigos não executam nada por si só. Eles são invocados no último
módulo de tal forma a simplificar o código. Posso usar essa lógica se preciso fazer uma
tarefa várias vezes, como dar uma saída, escrever numa célula, etc.
Segredo é definir o parâmetro entre parênteses. Pode ser qualquer nome, mas
atenção na definição do tipo de variável.

Procedure Scope (Public and Private)


Quase todos procedures vistos até agora eram public - Todo mundo podia acessar.
Sub ImplicityPublic()
MsgBox 1 + 1
End Sub

Public Sub ExplicityPublic()


MsgBox 1 + 1
End Sub

Deixa explícito que é público para facilitar identificar futuramente no cenário com
public e private.
Private procedure existem para serem invocados por outros procedures!
Private Sub ExplicityPrivate()
Range("A1").Value = "Private stuff"
End Sub

O user não tem acesso a esse procedure, mas o usuário pode usar esse procedure
nos outros procedures a vontade!

Public Sub ExplicityPublic()


Call ExplicityPrivate
MsgBox 1 + 1
End Sub

Ajuda fornecendo só Procedures úteis ao usuário

Exit Sub
Termina um procedure se uma condição lógica é atingida
Se depende de um valor, e o usuário não fornece, faz sentido matar o processo.
Sub ExitEarly()
Debug.Print 1
Debug.Print 2

Exit Sub

Debug.Print 3
Debug.Print 4
End Sub

Constantes
Modo de associar uma variável para que ela não mude de valor.
Sub FunWithConstants()
Const PI As Double = 3.14159
Const cMonths As Long = 12
Const cTaxRate As Double = 0.0825

End Sub

Usado convenção de colocar um c minúsculo antes de variáveis constantes! Quando


uma variável é declarada fora do Procedure Scope, ela fica acessível para todo módulo!
Se coloco Public antes, ela fica acessível para a geral (outros módulos).
Public Const JobTitle As String = "VBA Developer"
Sub Occupation()
Debug.Print "I am a " & JobTitle
End Sub

Constantes pré definidas


Associa um conceito com um número -- Enumeration
Por exemplo, acessando a Propriedade Worksheet.PageSetup:

Acessando PageSetup e indo em Orientation:

Exemplo claro de enumeração!

Option Explicit

Sub ChangeOrientation()
Dim ps As PageSetup
Set ps = Worksheets("Sheet1").PageSetup
ps.Orientation = xlLandscape

End Sub

Sempre será usado quando a variável e o conteúdo não tiverem muita associação.

1.1 Object Deep Dive

Application Object: Exemplos mais usados:


Sub FunWithApps()
Debug.Print Application.Name
Debug.Print Application.Path
Debug.Print Application.Version
Debug.Print Application.UserName
End Sub

Ainda na janela imediata, posso encerrar via:


Application.Quit

DisplayAlerts Propriedades:
Relacionado com aquelas janelas que aparecem ao usuário. Pode ser interessante
desativar para melhorar a experiência ao usuário.
Sub CloseWorkbook()
Application.DisplayAlerts = False
Workbooks(1).Close
Application.DisplayAlerts = True
End Sub

Lembrando de retornar a função para TRUE porque a mudança é em escala global.

Workbooks.Count e Worksheets.Count
Posso contar o número de Worksheets:
? Worksheets.Count

Ou contar o número de Sheets (Chart Work, ...)


? Sheets.Count

Se quiser contar o número de Workbooks abertos:


?Workbooks.Count
Workbooks.Open Method e Workbooks.Path Property
Primeiro coleto o Path do Workbook aberto, depois executo o seguinte
procedimento para abrir um novo arquivo
Sub OpenSomeFile()
Dim filepath As String
filepath = ActiveWorkbook.Path

Dim wb As Workbook
Set wb = Workbooks.Open(filepath & "\Teste.xlsm")

MsgBox "You've just opened " & wb.Name


MsgBox "And the File Path is " & wb.Path

End Sub

WorkBooks.Close Method
Vai fechar todos os Workbooks!
Sub CloseEverything()
Application.DisplaysAlerts = False
Workbooks.Close
Application.DisplayAlerts = True
End Sub

Workbooks.Add Method
Igual a control + N.
Sub AddWorkbook()
Workbooks.Add
End Sub

Agora, se quero abrir um novo documento, tal que seja cópia idêntica de outro,
posso fazer:
Sub CreateNewWorkbook()
Workbooks.Add ActiveWorkbook.Path & "\teste.xlsm"
End Sub

Sendo mais específico:


Sub CreateNewWorkbook()
Workbooks.Add Template:=ActiveWorkbook.Path &
"\teste.xlsm"
End Sub
Workbooks.SaveAs e Workbook.Save Method
Exemplo de criar duas planilhas do zero e salvá-las no mesmo path:
Sub CreateAndSaveWorkbooks()
Application.DisplayAlerts = False
Application.SheetsInNewWorkbook = 2

Dim w1 As Workbook, w2 As Workbook

Set w1 = Workbooks.Add
Set w2 = Workbooks.Add

w1.SaveAs ThisWorkbook.Path & "\red.xlsm",


xlOpenXMLWorkbookMacroEnabled
w2.SaveAs ThisWorkbook.Path & "\blue.xlsm",
xlOpenXMLWorkbookMacroEnabled

w1.Worksheets(1).Range("C3").Value = "Red!"
w2.Worksheets(2).Range("E5").Value = "Blue!"

w1.Save
w2.Save

w1.Close
w2.Close
Application.DisplayAlerts = True
End Sub

Workbook.Activate Method
Ativa um Workbook - mesmo que clicar nele.
Sub MakingChanges()
Dim red As Workbook, blue As Workbook
Set red = Workbooks.Open(ThisWorkbook.Path &
"\red.xlsm")
Set blue = Workbooks.Open(ThisWorkbook.Path &
"\blue.xlsm")

red.Activate
ActiveWorkbook.ActiveSheet.Range("A1").Value =
"Another RED!"
blue.Activate
ActiveWorkbook.ActiveSheet.Range("A1").Value =
"Another BLUE!"

End Sub

Workbook.Close Method

Sub ClosingChanges()
Dim red As Workbook, blue As Workbook
Set red = Workbooks.Open(ThisWorkbook.Path &
"\red.xlsm")
Set blue = Workbooks.Open(ThisWorkbook.Path &
"\blue.xlsm")

red.Worksheets(2).Range("A2").Value = "Another
Another RED!"
blue.Worksheets(2).Range("A2").Value = "Another
Another BLUE!"

red.Close SaveChanges:=True
blue.Close SaveChanges:=False
End Sub

Workbooks.Add Method
Gerar uma nova planilha:
Sub GenerateNewWorksheet()
Worksheets.Add Before:=Worksheets("Planilha2")
End Sub

Podendo usar before ou after.

Worksheet.Visible Property
Permite ocultar planilhas!
Sub HideSomeSheets()
Worksheets(2).Visible = True
End Sub

Posso usar o Very Hidden para não possibilitar o user de acessar esses dados!
Sub HideSomeSheets()
Worksheets(1).Visible = xlSheetVisible
Worksheets(2).Visible = xlSheetHidden
Worksheets(3).Visible = xlSheetVeryHidden

End Sub

WorkSheet.Copy
Posso copier para uma nova planilha
Sub CopyWorkSheet()
Worksheets(1).Copy
End Sub

Ou copiar para a mesma planilha


Sub CopyWorkSheet()
Worksheets(1).Copy After:=Worksheets(1)
End Sub

WorkSheet.Delete Method
Deletar uma planilha
Sub DeleteWorkSheet()
Application.DisplayAlerts = False
Worksheets("Planilha1").Delete
Application.DisplayAlerts = True
End Sub

WorkSheet.Move Method
Mover uma planilha de local:
Sub MoveWorksheets()
Worksheets(2).Move After:=Worksheets("Planilha2")
End Sub

1.2 Range References

The Range Select Method


Range object: conjunto de células, uma célula ou até todas!
Notação A1: A para colunas e 1 para linhas
Active Sheet é aquela que está selecionada
Chart Sheet não tem a referência A1
Sub HighlightRange()
Range("B5").Select
Selection.Value = "Hello World!"
End Sub
Selecionando um agrupamento de células:
Sub HighlightRange()
Range("B5:E9").Select
Range("B5", "E9").Select
End Sub

Selecionando todas as colunas:


Sub HighlightRange()
Range("B:C").Select
End Sub

Selecionando todas as linhas:


Sub HighlightRange()
Range("3:3").Select
End Sub

Selecionando células separadas:


Sub HighlightRange()
Range("A1, B2:B3").Select
End Sub

Value and Text Properties


Seja R$ 9,99 - na janela imediata, teremos as seguintes ocasiões:
? Range("A3").Value
9,99

? Range("A3").Text
R$9,99

Seja a data quarta feira, 13 de setembro de 1995 - na janela imediata, teremos as


seguintes ocasiões:
? Range("A4").Value
13/12/1995

? Range("A4").Text
quarta-feira, 13 de dezembro de 1995

Notação R1C1
Melhor para notações não tão fixas - Colunas e linhas encaradas como números
File - Options - Formulas - R1C1 Style (L1C1 no BR)
=L4C1
Células com valor em L5C3. Se estiver em L3C5, posso chamar o valor como:
=L[2]C

Se estiver em L9C3:
=L[-4]C

Se estiver em L5C1:
=LC[2]

Soma de L1C1:L1C2, com resultado em L1C3:


=SOMA(LC[-2];LC[-1])

A fórmula se mantém para todas as linhas!


Posso definir referências absolutas referenciando de forma completa:
=LC[-1]*L1C9
=LC[-2]+LC[-1]

Formula e FormulaR1C1 Properties


Dado exemplo de como coletar um dado em uma célula de diversas maneiras:
Sub WriteFormula()
Range("A3").Formula = "=SUM(A1:A2)"
End Sub

Sub GetCellValues()
Debug.Print Range("A3").Value
Debug.Print Range("A3").Text
Debug.Print Range("A3").Formula
End Sub

Utilizando a Propriedade FormulaR1C1:


Sub CalculateTotals()
Range("A4:C4").FormulaR1C1 = "=SUM(R[-3]C:R[-1]C)"
End Sub
Range Offset Property
Função offset, move-se a partir da célula selecionada, de acordo com as seguintes
possibilidades:
Range("A1").offset(2, 0).Select
Range("A1").offset(0, 5).Select
Range("A1").offset(2, 5).Select

Posso selecionar mais de uma célula!


Range("A1:C3").Offset(10,3).Select

Resize Property
Muda o tamanho de uma Range. Escolho o valor final que será mostrado. Assim,
por exemplo:
Range("C2").Resize(1,1).Select

Retorna apenas a seleção da célula C2.


Mas se tenho algo assim:
Range("C2").Resize(3,1).Select

Ele passa a selecionar 3 linhas abaixo, começando em C2. A célula original é


incluída!
Mudando toda a seleção para o mesmo valor:
Range("C2").Resize(4,5).Value = 25

Parte sempre da célula top left......C2:B17 iria produzir o mesmo resultado!

Cells Property
Se baseia na notação R1C1
Objeto bem alto na hierarquia, assim, posso selecionar todas as células no
worksheet com:
Application.Cells.Select
Cells.Select

Posso usar a referência de Cells mesmo no modo A1!:


Cells(2,5).Value = 25

Só aceita uma id de linha e coluna - Usar resize para alterar para uma seleção maior:
Cells(2,5).Resize(4,5).Select
Cells(2,5).Resize(4,5).Value = "Fill"

Range CurrentRegion Property


Foca nos espaços em branco entre os dados.
Vai buscar os limites que cercam os dados.
Range("B2").CurrentRegion.Select

O VBA vai em todas as direções possíveis, parando nas células em branco,


selecionando uma região. Tanto faz usar B4, C2, etc.
Range("A1:G7").CurrentRegion.Select

Parte de A1 e acha a primeira região possível!


Boa para selecionar células contendo espaços em branco

The Range End Property


Simula pressionar a Tecla end.
End mais direita vai para o final da planilha! End mais qualquer seta vai para um
extremo da planilha!
Comportamento padrão para uma planilha vazia, mas para planilha com dados:
Aqui ela vai até onde existe dados!

As quatro direções possíveis são: xlUp, xlDown, xlToRight, xlToLeft


Sub ChangeCorners()
Range("A1").Value = "Top Left Corner"

Range("A1").End(xlDown).Value = "Bottom left corner"


End Sub

Movendo-se para a bottom right:


Sub ChangeCorners2()
Range("A1").End(xlDown).End(xlToRight).Value = "Bot-
tom left corner"
End Sub

The Range Count and Range CountLarge


CountLarge lida com números maiores. Contam o número de células! Não o seu valor!
? Range("A2:C4").Count
9

? Range("A:A").Count
1048576

? Range("A1:XFD1").Count
16384
? Range("A:XFD").Count =======ERRO=========

? Range("A:XFD").CountLarge
17179869184

Range Row and Range Column Properties


VBA vai para o top left e executa, daí não tem diferença:

? Range("C4").Column
3

? Range("C4:J26").Column
3

Range Rows and Range Columns Properties


Retornam um total de linhas e colunas.
Sub TargetStuff()
Application.Columns.Select
Rows.Select

Debug.Print Rows.Count
Debug.Print Columns.Count
End Sub

1048576
16384

Esolhendo um alvo específico:


Sub TargetStuff()
Rows(2).Select
Rows("2:5").Select
End Sub

Sub TargetStuff()
Columns(2).Select
Columns("B:D").Select
End Sub
Selecionando a segunda coluna de uma seleção (no caso seria a coluna C, até o
elemento C12):
Sub TargetStuff()
Range("B4:D12").Columns(2).Select
End Sub

Option Explicit

Sub TargetStuff()
Range("B4:D12").Columns(2).Select
Range("B4:C12").Rows(4).Value = "!"
End Sub

Range EntireRow and Entire Column


Após selecionar C3: Começa com uma célula e depois selecionar toda a
linha/coluna

? ActiveCell.Address
$C$10

? activeCell.Row
10

? activeCell.Column
3

ActiveCell.EntireRow.Select

ActiveCell.EntireColumn.Select

Last Row of Data


Quero escrever um valor abaixo do último valor possível. Se dados todos
preenchidos, poderia usar a End Property. Alternativa: Buscar iniciar do final para o
inicio!
Sub FindLastRow()
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Debug.Print LastRow
End Sub
1.3 Range Actions

Range Fill down Method


Copia uma fórmula para baixo, ou uma sequência. Com a fórmula já escrita em B1,
basta fazer:
Sub FillCelss()
Range("B1:B5").FillDown
End Sub

Range Replace Method


Criar um procedure para colocar Missing onde não há numeração:
Sub ReplaceBlanks()
Range("A1:A12").Replace What:="", Replacement:= "Mis_
sing"
End Sub

Segredo é usar o Replace e Replacement!


Cuidado que substitui mesmo! Se troco 2 por 20, em 120, vai aparecer 1200.

Range Text to columns Method


Representa a função texto para colunas! Muito comum
Sub SeparateText()
Range("A1:A4").TextToColumns
Destination:=Range("C1"), _
Comma:=True
End Sub

Se o delimitador for um espaço:


Sub SeparateText2()
Range("A5:A7").TextToColumns
Destination:=Range("C5"), _
Space:=True
End Sub

E se o delimitador for /? Que não faz parte das opções padrões?


Sub SeparateText2()
Range("A9:A11").TextToColumns
Destination:=Range("C9"), _
Other:=True, OtherChar:="/"
End Sub

Range Worksheet Property


Outra maneira como conhecer o nome da planilha que trabalho:
Sub DiscoverWorksheet()
MsgBox Range("C5").Worksheet.Name
End Sub

Range Sort Method


Key1 representa o termo a ser considerado para definir quem manda na ordem!
Sub SortColums()
Columns("B:B").Sort key1:=Range("B:B"), _
order1:=xlAscending, Header:=xlYes
End Sub

Atenção que neste código, bagunçou tudo! Perdeu a relação entre os dados em A e
B. O seguinte código corrige o problema!

Sub SortColums()
Columns("A:B").Sort key1:=Range("B:B"), _
order1:=xlAscending, Header:=xlYes
End Sub

Agora usando dois critérios:


Sub SortColums()
Columns("A:B").Sort key1:=Range("A:A"), _
order1:=xlAscending, key2:=Range("B:B"), _
order2:=xlDescending, Header:=xlYes
End Sub

The Range Font Property


Guarda todas as características de estilo da fonte!
Sub ModifyFont()
Dim r As Range
Set r = Range("A1")

r.Font.Bold = True
r.Font.Italic = True
r.Font.Underline = xlUnderlineStyleDouble
r.Font.Size = 36
r.Font.Name = "Comic Sans MS"

r.Font.Color = vbRed
r.Font.Color = RGB(130, 55, 200)
End Sub

The Range Interior Property


Interfere no preenchimento da célula! Segue código para identificar qual cor padrão
está presente no VBA:
Sub Painting()
Dim r As Range
Set r = Cells(4, 3)
Dim i As Long
For i = 1 To 56
Cells(i, 1).Interior.ColorIndex = i
Cells(i, 1).Value = i
Next i
End Sub

Range Column and Row Width/Height Range


Primeiro, uso seguinte Código para selecionar toda a coluna A:
range("A1").EntireColumn.Select

Alterando na janela imediata:


range("A1").EntireColumn.ColumnWidth = 35

Alternado todas as colunas em uma range:


Columns("B:E").ColumnWidth = 35

Cells(8,3).EntireRow.RowHeight = 45

Rows("2:5").RowHeight = 75

Range Auto Fit


Altera tamanho da coluna automaticamente.
Sub ExpandWidht()
Columns("A").AutoFit
End Sub

Se quiser ajustar automaticamente de A até E:


Sub ExpandWidht()
Columns("A:E").AutoFit
End Sub

Range Clear e ClearFormats Method:


Limpando conteúdo e formatações:
Sub ClearStuff()
Range("A1:A3").ClearContents
Range("A1:A3").ClearFormats
End Sub

Ou resumindo:
Sub ClearStuff()
Range("A1:A3").Clear
End Sub

Range Delete Method


Usando na janela imediata:
Rows("4:5").Delete
Columns("B:C").Delete

Excluindo e mudando dados de lado para preencher o vazio:


Range("C5").Delete xlToLeft

Range("C5").Delete xlUp

Range Copy e Cut


Iguala o copia e cola!
Sub CopyAndPaste()
Range("B4:D6").Copy Destination:=Range("B8:D10")
End Sub

Sub CutAndPaste()
Range("B4:D6").Cut Destination:=Range("B8:D10")
End Sub

Range Paste e Paste Special


Aproveita os benefícios da colagem especial:
Sub CopyAndPastRange()
Range("A3").Copy

Range("C3").PasteSpecial xlPasteValues
End Sub

Parent Property
? TypeName(Range("A1").Parent) retorna:
Worksheet
? TypeName(Range("A1").Parent.Parent) retorna:
Workbook

? TypeName(Range("A1").Parent.Parent.Parent) retorna:
Application

Maneira de subir nas propriedades e variar um pouco. Até agora focou em só


descer!

1.4 Conditionals

Boolean Expressions
Valor verdadeiro ou falso. Exemplos de operadores e comparações:
? 3 < 5
Verdadeiro

? 4 < 1
Falso

? 5 <= 25
Verdadeiro

? 20 = 20 ‘Não é “==”!
Verdadeiro

? 10 <> 20 “Is ten not equal to 20?


Verdadeiro

? "hello" <> "hi"


Verdadeiro

? "hello" <> "Hello"


Verdadeiro

? "hello" <> "hello "


Verdadeiro
If Then:
Sintaxe é If........Then e depois no final deve possuir um End If.
Sub MyFirstIf()
If 5 > 3 Then
MsgBox "Yay, it's True"
End If
End Sub

Se for um caso onde há apenas um statement:


Sub MyFirstIf()
If 5 > 3 Then MsgBox "Yay, it's True!"
End Sub

ElseIf and Else


Se a fonte é Calibri alterar para Times New Roman:
Sub ChangeFont()
Dim rng As Range
Set rng = Range("A1")

Dim ft As Font
Set ft = rng.Font

ft.Size = 24

If ft.Name = "Calibri" Then


ft.Name = "Times New Roman"
ElseIf ft.Name = "Times New Roman" Then
ft.Name = "Calibri"
End If
End Sub

Posso usar quantos ElseIf quiser, mas prioirizar colocar os mais prováveis primeiro.
Se tudo acima for falso, posso usar em Else para continuar um código.
Sub ChangeFont()
Dim rng As Range
Set rng = Range("A1")

Dim ft As Font
Set ft = rng.Font
ft.Size = 24

If ft.Name = "Calibri" Then


ft.Name = "Times New Roman"
ElseIf ft.Name = "Times New Roman" Then
ft.Name = "Calibri"
Else
ft.Name = "Comic Sans MS"
End If
End Sub

Select Case
Coletar o que ainda está em D5:
Sub FunWithSelect()
Dim CurrentValue As String
CurrentValue = Range("D5").Value

Select Case CurrentValue


Case "A"
MsgBox "It's A"
Case "B"
MsgBox "It's B"
End Select
End Sub

Mesma resposta para mais de um caso:


Sub FunWithSelect()
Dim CurrentValue As String
CurrentValue = Range("D5").Value

Select Case CurrentValue


Case "A"
MsgBox "It's A"
Case "B", "C", "D"
MsgBox "It's B"
End Select
End Sub

Usando o equivalente do Else:


Sub FunWithSelect()
Dim CurrentValue As String
CurrentValue = Range("D5").Value

Select Case CurrentValue


Case "A"
MsgBox "It's A"
Case "B", "C", "D"
MsgBox "It's B"
Case Else
MsgBox "Wrong!"
End Select
End Sub

Especificando range de números:


Sub TimeOfMonth()
Dim DayOfMonth As Long
DayOfMonth = Day(Now)

Select Case DayOfMonth


Case 1 To 10
MsgBox "Primeiro terço do mês"
Case 11 To 20
MsgBox "Segundo terço do mês"
Case Else
MsgBox "Fim do mês"
End Select
End Sub

Usando símbolos matemáticos:


Sub TimeOfMonth()
Dim DayOfMonth As Long
DayOfMonth = Day(Now)

Select Case DayOfMonth


Case Is < 11
MsgBox "Primeiro terço do mês"
Case Is < 21
MsgBox "Segundo terço do mês"
Case Else
MsgBox "Fim do mês"
End Select
End Sub

And e Or:
Checando várias condições ao mesmo tempo:
Sub BoldHeaders()
If Range("A1").Value = "Name" Then
Range("A1").Resize(1, 2).Font.Bold = True
End If
End Sub

Adicionando mais uma condição:


Sub BoldHeaders()
If Range("A1").Value = "Name" And Range("B1").Value =
"Age" Then
Range("A1").Resize(1, 2).Font.Bold = True
End If
End Sub

Sub BoldHeaders()
If Range("A1").Value = "Name" Or Range("B1").Value =
"Age" Then
Range("A1").Resize(1, 2).Font.Bold = True
End If
End Sub

Not Operator:
? Not True
Falso

Sub BoldSelection()
Range("B4").Resize(1, 3).Font.Bold = True
End Sub

Mas dá problema ao executar pela segunda vez! Usar condições lógicas:


Sub BoldSelection()
Dim f As Font
Set f = Range("B4").Resize(1, 3).Font
If f.Bold Then
f.Bold = False
Else
f.Bold = True
End If
End Sub

Usando o operador NOT;


Sub BoldSelection2()
Range("B4").Resize(1, 3).Font.Bold = Not
Range("B4").Resize(1, 3).Font.Bold
End Sub

1.5 Iteration

For Next Loop


Repete um bloco de programação por mais de uma vez. Iteração é um dos loops.
Sub FirstLoop()
Dim i As Long
For i = 1 To 5
Cells(i, 1) = i
Debug.Print i
Next i
Debug.Print I (6)
End Sub

Sub SumTo25()
Dim Total As Long
Dim i As Long
Total = 0

For i = 1 To 25
Total = Total + i
Next i
MsgBox Total
End Sub

Step keyword
Não precisa de dar passos de 1 em 1:
Sub Step()
Dim i As Long

For i = 1 To 20 Step 2
Debug.Print i
Next i
End Sub

Toda segunda linha amarela:


Set para atribuir em um objeto!

Sub ColorEverySecondRow()
Dim i As Long
Dim r As Range

For i = 2 To 100 Step 2


Set r = Cells(i, 1).EntireRow
r.Interior.Color = vbYellow
Next i
End Sub

Iteration backward
Muito usado para deletar linhas! Quando deleto com loop normal, as linhas sobem
e bagunçam tudo! Por isso, sempre que for deletar linhas, começar debaixo para cima!
Deletando linhas com DELETE: Segredo é usar STEP como -1:
Sub DeleteRows()
Dim FinalRow As Long
FinalRow = Cells(Rows.Count, 1).End(xlUp)

Dim i As Long

For i = FinalRow To 1 Step -1


If Cells(i, 1).Value = "DELETE" Then
Cells(i, 1).EntireRow.Delete
End If
Next i
End Sub

For Each Next


Navego objetos!
Sub ForEachLoops()
Dim wb As Workbook

For Each wb In Workbooks


Range("A1").Value = "Hi!"
Debug.Print wb.Name
Next wb

Dim ws As Worksheet

For Each ws In Worksheets


Debug.Print ws.Name
ws.Range("A1").Value = ws.Name
Next ws
End Sub

For each loop em um range de células


Tenho os 12 meses escritos na coluna A. Quero escrever eles em maiúsculas:
Sub CapitalizeMonths()
Dim cell As Range

For Each cell In Range("A1:A12")


cell.Offset(0, 1).Value = UCase(cell.Value)
Next cell
End Sub

Cria na coluna da direita!


Sub SampleIteration()
Dim cell As Range

For Each cell In Selection


Debug.Print cell.Address
Next cell
End Sub
With End
Sub ModifyFont()
Selection.Font.Name = "Comic Sans MS"
Selection.Font.Size = 12
Selection.Font.Color = RGB(0, 255, 0)
Selection.Font.Bold = True
Selection.Font.Italic = True
End Sub

Pode ser reescrito como:


Sub ModifyFont()
With Selection.Font
Name = "Comic Sans MS"
Font.Size = 12
Color = RGB(0, 255, 0)
Bold = True
Italic = True
End With
End Sub

Exit For
Busca sair prematuramente:
Sub FindingAugust()
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

Dim i As Long
For i = 1 To LastRow
Cells(i, 1).Font.Name = "Comic Sans MS"
If Cells(i, 1).Value = "Agosto" Then
Cells(i, 1).Select
Exit For
End If
Next i
End Sub

Dobrando um valor de uma célula:


Sub DoubleCell()
Dim cell As Range
For Each cell In Selection
cell.Value = cell.Value * 2
Next cell
End Sub

Se houver espaços em branco: Parar o procedure!


Sub DoubleCell()
Dim cell As Range
For Each cell In Selection
If cell.Value <> "" Then
cell.Value = cell.Value * 2
Else
MsgBox "Tem uma célula em branco!"
Exit Sub
End If
Next cell
End Sub

1.6 Miscellaneous Features

Message Box em detalhes


Clássico:
Sub ShowBox()
MsgBox Prompt:="Hello there!"
End Sub

Mostrando apenas o OK:


Sub ShowBox()
'MsgBox Prompt:="Hello there!"
MsgBox "I have custom buttons", vbOKOnly
End Sub

Como exemplo de segundo argumento: vbOKCancel, vbYesNoCancel,


vbRetryCancel
Mudando o ícone:
Sub ShowBox()
'MsgBox Prompt:="Hello there!"
MsgBox "I have custom buttons", vbQuestion
End Sub

vbQuestion, vbCritical, vbExclamation e vbInformation


Adicionando todas essas funções:
Sub ShowBox()
MsgBox "I have custom buttons", vbQuestion +
vbYesNoCancel
End Sub

Botão Default: Quando aperto enter, já seleciono a opção


Sub ShowBox()
MsgBox "I have custom buttons", vbQuestion +
vbYesNo + vbDefaultButton1
End Sub

Alterar o título:
Sub ShowBox()
MsgBox "I have custom buttons", vbQuestion +
vbYesNo + vbDefaultButton1, "Deletar?"
End Sub

Atribuindo funções aos botões:


Sub CaptureUSerResponse()
Dim response As Long
response = MsgBox("Delete row 1?", vbQuestion +
vbYesNo + vbDefaultButton2)

Debug.Print response
End Sub

Consigo saber que número é resultado de escolher Yes or No!


Sub CaptureUSerResponse()
Dim response As Long
response = MsgBox("Delete row 1?", vbQuestion +
vbYesNo + vbDefaultButton2)

If response = vbYes Then


Rows(1).Delete
End If
End Sub

Status Bar
Aquela parte onde está escrito Ready. Posso dar opção ao user de ver o progresso
da Macro!
Sub StatusBarProcess()
Dim i As Long
For i = 1 To 20000
Cells(i, 1).Value = i * i

If i Mod 100 = 0 Then 'Mod é o resto da divisão!


Executa a cada 100 iterações!
Application.StatusBar = i & " out of 5000"
End If
Next i

Application.StatusBar = False
End Sub

Application Screen Updating


Utilizada para melhorar tempo de desempenho da macro!
Sub TimesTable()
Application.ScreenUpdating = False

Dim I As Long
Dim J As Long

For I = 1 To 100
For J = 1 To 100
Cells(I, J).Value = I * J
Next J
Next I
Application.ScreenUpdating = True
End Sub

Special Cells
Selecionando só algumas células da seleção:
Selecionando só células com constantes:
Sub FindSpecificCells()
Dim r As Range
Set r = Range("A1:A10")

r.SpecialCells(xlCellTypeConstants).Select
End Sub

Células em vazio:
Sub FindSpecificCells()
Dim r As Range
Set r = Range("A1:A10")

r.SpecialCells(xlCellTypeBlanks).Select
End Sub

Fórmulas:
Sub FindSpecificCells()
Dim r As Range
Set r = Range("A1:A10")

r.SpecialCells(xlCellTypeFormulas).Select
End Sub

Input Box Method:


Interação com o usuário: User escolhe nome da Planilha:
Sub AddNewWs()
Dim wsTitle As String
Dim ws As Worksheet

wsTitle = InputBox(Prompt:="Enter new woksheet


title", Title:="Worksheet Box", Default:="Magic Sheet")
If wsTitle <> "" Then
Set ws = Worksheets.Add
ws.Name = wsTitle
End If
End Sub

Escolhendo células para receberem cores aleatórias:


Sub PaintColors()
Dim UserRange As Range
Set UserRange = Application.InputBox( _
Prompt:="Select a range!", _
Title:="Range Coloring Time", _
Default:=ActiveCell.Address, _
Type:=8)
Dim r As Long, g As Long, b As Long
Dim cell As Range
For Each cell In UserRange
r = WorksheetFunction.RandBetween(0, 255)
g = WorksheetFunction.RandBetween(0, 255)
b = WorksheetFunction.RandBetween(0, 255)
cell.Interior.Color = VBA.RGB(r, g, b)
Next cell

End Sub

1.7 Arrays

Tipo especial de data!


Como se fosse o vetor! Grava vários valores!
Array formado por elements na posição index.
Arrays começa contando em ZERO!
Seasons(up) - up representa o máximo valor! Se up = 3, o array terá 4 valores
Sub MyFirstArray()
Dim seasons(3) As String

seasons(0) = "Summer"
seasons(1) = "Winter"
seasons(2) = "Fall"
seasons(3) = "Spring"

Debug.Print seasons(2)
End Sub

Alternate Syntax
Ajuda a ver lower e upper bound
Isso:
Sub LuckyNumbers()
Dim nums(5) As Long

nums(0) = 4
nums(1) = 7
nums(2) = 15
nums(3) = 16
nums(4) = 23
nums(5) = 42
End Sub

É idêntico a:
Sub LuckyNumbers()
Dim nums(0 To 5) As Long

nums(0) = 4
nums(1) = 7
nums(2) = 15
nums(3) = 16
nums(4) = 23
nums(5) = 42
End Sub

Posso usar também:


Dim nums(3 To 8) As Long

Option Base 1 Sintax and Write Arrays Values to Cells


Ajustando para começar a contagem em 1:
Option Base 1
Sub Another()
Dim JustTheWeekend(2) As String

JustTheWeekend(1) = "Saturday"
JustTheWeekend(2) = "Sunday"

Debug.Print JustTheWeekend(2)
End Sub

Colocando em uma célula:


Sub Another()
Dim JustTheWeekend(2) As String

JustTheWeekend(1) = "Saturday"
JustTheWeekend(2) = "Sunday"

Debug.Print JustTheWeekend(2)
Range("C1:D1").Value = JustTheWeekend
End Sub

Iniciatilize arrys with loops


Usando para retirar espaços em branco no início da célula: FUNÇÃO TRIM
Só consigo colar na horizontal - Na vertical tem q usar loops
Sub TrimValues()
Dim wordArray(1 To 10)
Dim I As Long

For I = 1 To 10
wordArray(I) = Trim(Cells(I, 1).Value)
Next I

For I = 1 To 10
Cells(I, 2).Value = wordArray(I)
Next I
End Sub

The LBound and UBound Method


Bom para saber quantos elementos tem um vetor!
Identificando os limites do Vetor:
Sub ArrayofSun()
Dim Weekdays(6) As String

Weekdays(0) = "Sunday"
Weekdays(1) = "Monday"
Weekdays(2) = "Tuesday"
Weekdays(3) = "Wednesday"
Weekdays(4) = "Thursday"
Weekdays(5) = "Friday"
Weekdays(6) = "Saturday"

Debug.Print LBound(Weekdays)
Debug.Pring UBound(Weekdays)
End Sub

Ou:
Sub ArrayofSun()
Dim Weekdays(6) As String

Weekdays(0) = "Sunday"
Weekdays(1) = "Monday"
Weekdays(2) = "Tuesday"
Weekdays(3) = "Wednesday"
Weekdays(4) = "Thursday"
Weekdays(5) = "Friday"
Weekdays(6) = "Saturday"

Debug.Print LBound(Weekdays)
Debug.Print UBound(Weekdays)

Dim I As Long

For I = LBound(Weekdays) To UBound(Weekdays)


Cells(I + 1, 1).Value = Weekdays(I) & " is a great
day"
Next I

End Sub

Dynamic Arrays
Pegando o tamanho dos valores da coluna 1! Não importa o dia! Macro tem que
atender condições futuras.
Só não colocar número que o array vira dinâmico.
ReDim - Redimensiona o tamanho do vetor! Deleta todos os valores do Array! Usar
“ReDim Preserve” para conservar o valor.
Sub ArraysofValues()
Dim ColumnValues() As String

Dim FinalRow As Long


FinalRow = Cells(Rows.Count, 1).End(xlUp).Row

ReDim ColumnValues(FinalRow - 1)

Dim I As Long
For I = LBound(ColumnValues) To UBound(ColumnValues)
ColumnValues(I) = Cells(I + 1, 1).Value
Next I

For I = LBound(ColumnValues) To UBound(ColumnValues)


Cells(I + 1, 2).Value = Len(ColumnValues(I))
Next I
End Sub
Range Remove Duplicates:
Remove valores duplicados:
Sub DestroyDuplicates()
Range("A1:A9").RemoveDuplicates Columns:=Array(1), _
Header:=xlYes
End Sub

1.8 Funções
Algumas funções disponíveis-armazenadas no Objeto VBA!
Tudo em minúsculas:
Sub FunWithVBAFunctions()
Debug.Print LCase("Hello")
Debug.Print Trim(" Hi! ")
End Sub

Debug.Print VBA.L - Informa todas as funções

In string: Checando se há um caractere em uma string


Sub FunWithVBAFunctions()
Debug.Print InStr(1, "My Number is 555-555-555", "-")
End Sub
17

Signfica que o - é encontrado primeiramente na posição 17! Se no lugar de 1, coloco


18 - Começa a procurar a partir da posição 18 e encontra o valor de 21!
Sub MoreFunctions()
Debug.Print Left("555-555-5555", 3)
Debug.Print Right("Rua Lira, 44", 2)
Debug.Print Mid("Mr. Excel", 5, 3)
Debug.Print StrReverse("straw")
Debug.Print Replace("555 555 5555", " ", "-")
End Sub

555
44
Exc
warts
555-555-5555
Split Function

Separando os dados 100/50/26 em três colunas diferentes:


Sub SplitFunc()
Dim Results() As String
Results = VBA.Split(Range("A1").Value, "/")
Range("B1").Value = Results(0)
Range("C1").Value = Results(1)
Range("D1").Value = Results(2)
End Sub

Is Family
? isnumeric(5)
Verdadeiro

? IsNumeric(False)
Verdadeiro

? isdate("13/11/1992")
Verdadeiro

? isempty(Range("A1"))
Falso

Value Numeric Date Empty Error

3.14

Santa
Claus

TRUE

#DIV/0!

04/12/1991

Aplicando a subrotina:
Sub FigureOutCellType()
Dim I As Long
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Dim val As Variant
Dim Calculations(3) As Boolean

For I = 2 To LastRow
val = Cells(I, 1).Value
Calculations(0) = IsNumeric(val)
Calculations(1) = IsDate(val)
Calculations(2) = IsEmpty(val)
Calculations(3) = IsError(val)
Cells(I, 2).Resize(1, 4).Value = Calculations
Next I
End Sub

Value Numeric Date Empty Error


5 VERDADEIRO FALSO FALSO FALSO
3.14 VERDADEIRO VERDADEIRO FALSO FALSO
Santa Claus FALSO FALSO FALSO FALSO
TRUE FALSO FALSO FALSO FALSO
#DIV/0! FALSO FALSO FALSO VERDADEIRO
04/12/1991 FALSO VERDADEIRO FALSO FALSO

Date and Time Functions


Pegando as informações de tempo no PC:
Sub FunWithDates()
Debug.Print VBA.Date
Debug.Print VBA.Time
Debug.Print VBA.Now
End Sub

23/07/2019
06:46:21
23/07/2019 06:46:21

Inserindo uma data e alterando o tipo da célula para datas:


Sub CreateDate()
Dim birthday As Date
birthday = DateSerial(1991, 4, 12)
Range("A1").Value = birthday
End Sub

Outras funções:
Sub CreateDates()
Debug.Print Year(Now)
Debug.Print Month(Now)
Debug.Print Day(Now)
Debug.Print Hour(Now)
Debug.Print Minute(Now)
Debug.Print Weekday(Now)
Debug.Print WeekdayName(Weekday(Now))
Debug.Print MonthName(Month(Now))
End Sub

2019
7
23
6
53
3
terça-feira
julho

Worksheet Functions
Vlook - Encontrando um salário da pessoa na célula selecionada, em uma tabela:
Sub VLookExample()
Dim cv As Variant

cv =
Application.WorksheetFunction.VLookup(ActiveCell.Value,
Range("A1:C5"), 3, False)
ActiveCell.Offset(0, 1).Value = cv
End Sub
Custom Functions
A função é adicionada a interface do Excel!
Function FtoC(temperature As Double) As Double
FtoC = (temperature - 32) * (5 / 9)
End Function

Function HeightInCm(Feet As Long, Inches As Long) As


Double
Dim TotalInches As Long
TotalInches = (Feet * 12) + Inches
HeightInCm = TotalInches * 2.54
End Function

Sub Action()
Dim result As Long
result = FtoC(32)
Range("A1").Value = result
End Sub

1.9 Lidando com erros:

Depurar - Compilar VBA Project para checar todos os Procedures por erros!

OnError e GoTo
Lembrar de usar Exit Sub!

Sub FunWithSum()

On Error GoTo InvalidEntry


MsgBox Range("A1").Value + 5
Exit Sub

InvalidEntry:
MsgBox "Invalid cell value!"
End Sub

OnError Resume Next:


Quando tento deletar um worksheet que não existe.
Dividindo uma coluna por outra, lidando com erro de dividir por zero:
Sub FunWithDivision()
Dim I As Long

On Error Resume Next


For I = 1 To 10
Cells(I, 3).Value = Cells(I, 1).Value / Cells(I,
2).Value
Next I
End Sub

Error Object
0 significa que não erros - em Debug.Print Err.Number. Erro se mantém nas
iterações! Usar Err.Clear para não reter o valor.
Sub FunWithDivision()
Dim I As Long

On Error Resume Next


For I = 1 To 10
Cells(I, 3).Value = Cells(I, 1).Value / Cells(I,
2).Value

If (Err) Then
Debug.Print Err.Number
Err.Clear
End If
Next I
End Sub

Pegando os detalhes do erro:


Sub FunWithDivision()
Dim I As Long
On Error Resume Next
For I = 1 To 10
Cells(I, 3).Value = Cells(I, 1).Value / Cells(I,
2).Value

If (Err) Then
Debug.Print Err.Number
Debug.Print Error(Err.Number)
Err.Clear
End If
Next I
End Sub

Mostrando todos erros de 01 a 100:


Sub ShowErros()
Dim I As Long

For I = 1 To 100
Cells(I, 1).Value = Error(I)
Next I
End Sub

Executando o código step by step


Utiliza F8 para acionar esse método! Posso usar Verificação imediata e ir checando
os valores!
Posso voltar no código arrastando a seta na direita!
Funções dentro do menu Debug!

Breakpoints
Pausa a execução do código.
Basta clicar na barra esquerda do código - Linha fica na cor Bordô.
F9 coloca o Breakpoint e Shift+F9 retira o breakpoint.

1.10 Eventos

Responsáveis por dar trigger em uma macro, por exemplo. Quando adicionar um
valor na célula, execute uma macro.
Códigos não escritos mais nos Modules - Mas em Microsoft Excel Objetos -
Podendo limitar em uma planilha ou global!
Abrindo EstaPastaDeTrabalho - Escolhendo Objeto como Worksheet:
Private Sub Worksheet_SelectionChange(ByVal Target As
Range)

Este é o evento padrão - Mas tem vários na janela acima


Tudo será executado automaticamente!
The Worksheet_SelectionChange Event
Nome definidos pelo VBA - não personalizáveis
ByVal - user não pode sobrescrever o valor da constante!
Private Sub Worksheet_SelectionChange(ByVal Target As
Range)
Debug.Print Target.Address
Cells.ClearFormats
Target.Interior.Color = vbRed
End Sub

Review of Application.EnableEvents
Desativar um evento no começo e ativar depois! Evita Loops Infinitos
Private Sub Worksheet_SelectionChange(ByVal Target As
Range)
Application.EnableEvents = False
Cells.ClearFormats
Target.Interior.Color = vbBlue
Application.EnableEvents = True
End Sub

The Worksheet_Change Event


Código de Conversão! De pounds para kg automaticamente:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Column = 1 And Target.Row >= 2 Then
If Target.Value = "" Then
Target.Offset(0, 1).Clear
Else
Target.Offset(0, 1).Value = Target.Value *
0.453592
End If
End If
Application.EnableEvents = True
End Sub

The Worksheet_Activate Event


Private Sub Worksheet_Activate()
MsgBox "welcome to " & ActiveSheet.Name
MsgBox "Be careful when changing values!"

End Sub
Workbook Events and The Sh Argument
Sh é o nome padrão do Worksheet!
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal
Target As Range)
Application.EnableEvents = False

Dim ws As Worksheet
Set ws = Worksheets("Changes")

Dim LastRow As Long


LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row

ws.Cells(LastRow + 1, 1).Value = Sh.Name


ws.Cells(LastRow + 1, 2).Value = Target.Address
ws.Cells(LastRow + 1, 3).Value = Target.Value

Application.EnableEvents = True
End Sub

The Workbook_Open Event


Private Sub Workbook_Open()
MsgBox "Welcome to my Workbook: " &
ActiveWorkbook.Name
End Sub

Procedures with Boolean Arguments + The Workbook_BeforePrint Event


Cancelando um procedure:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If 5 > 3 Then
MsgBox "Hey! Print is not allowed!"
Cancel = True
End If
End Sub

1.11 User Forms


Formularios - Um exemplo é a caixa de Insert Function
Constituido por Form Controls (Objetos do VBA)
INSERIR - USER FORM - Cria a pasta Formulários!
Mudar o título em CAPTION
The Label and TextBox Controls

Usar o padrão de definir três letras iniciais como código para identificação:
Fmr é Form
Lbl é label

Naming Conventions
Sempre inicio com o prefixo que indica o tipo de código! Inicia com o tipo de
controle, pois há diferentes métodos e objetos! Quando escrevo Procedures que vão
interagir com os User Forms - Necessário adotar um esquema de 3 letras para ajudar
futuramente.
Ajuda a associar objetos que estarão conectados!

Design Aesthetics
Todas opções em Formatar!
Como alinhar, etc.
Quando selectionado - O objeto que estiver com o envoltório com quadrados
brancos será o líder para que o alinhamento seja baseado!
The CommandButton Control
Dá um trigger em um procedure se quiser!
Código é CMD

Cada botão é um procedure por exemplo!


Add Event Procedure to Control
Botão direito no Formulário e exibir código - Depois escolhe a parte do desenho
que quero associar clicando duas vezes.
Coletando todas mudanças:
Private Sub TextBox1_Change()
Debug.Print TextBox1.Value
End Sub

Unload and Hide a UserForm


Fechando o UserForm - Cancel perde todos os dados - Hide só esconde!
Private Sub cmdCancel_Click()
Unload Me
End Sub

Private Sub cmdHide_Click()


Me.Hide
Application.ScreenUpdating = True
End Sub

Submit the UserForm


Private Sub cmdSubmit_Click()
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Cells(LastRow + 1, 1).Value = Me.TextBox1.Value
Unload Me
End Sub

Mas agora quero melhorar o Formulario para: não fechar automaticamente (tirar
UNLOAD ME) - e indicar ultimo valor inserido
Private Sub cmdSubmit_Click()
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

Dim LastValue As String


LastValue = Me.TextBox1.Value

Cells(LastRow + 1, 1).Value = LastValue


Me.TextBox1.Value = ""

Me.lblLastValue = "The lasta value added was " &


LastValue
End Sub

Activate a UserForm from Procedure


Iniciar o procedure meio que automaticamente! Via Procedure!
Atirbuir a seguinte macro para uma figura:
Sub ShowForm()
fmrFormulario.Show
End Sub

The initialize Event


Permite uma troca dinâmica de valores! Muda o dia da semana, a hora por exemplo
- Seta um estado inicial!
Private Sub UserForm_Initialize()
Dim WeekdayNumber As Long
WeekdayNumber = VBA.weekday(VBA.Now)
Dim weekday As String
weekday = VBA.WeekdayName(WeekdayNumber)
Me.lblWeekday.Caption = "Happy " & weekday
End Sub
The ListBox Control I - Wire up the Form
Lista pré-definida de valores para o usuário para diminuir erros deles!
Private Sub cmdCancel_Click()
Unload Me
End Sub

Private Sub UserForm_Initialize()


lbxWorksheets.RowSource = ""
Dim ws As Worksheet

For Each ws In Worksheets


lbxWorksheets.AddItem ws.Name
Next ws
End Sub

The ListBox Control II - React to User Selection


Coletando qual a célula para deletar:
Private Sub cmdCancel_Click()
Unload Me
End Sub

Private Sub cmdDelete_Click()


Dim SheetToDelete As String
SheetToDelete = lbxWorksheets.Value

If SheetToDelete <> "" Then


Application.DisplayAlerts = False
Worksheets(SheetToDelete).Delete
lbxWorksheets.RemoveItem lbxWorksheets.ListIndex
Application.DisplayAlerts = True
End If
End Sub

Private Sub UserForm_Initialize()


lbxWorksheets.RowSource = ""
Dim ws As Worksheet

For Each ws In Worksheets


lbxWorksheets.AddItem ws.Name
Next ws
End Sub

The ListBox Control III - Select Multiple Items


Selecionando várias planilhas ao mesmo tempo:
Mudar no Label - MultiSelect para 1-fmMultiSelectMulti - Proporciona selecionar
mais de um item da lista de uma vez!
Basta alterar a lógica por trás do Delete Procedure:
Private Sub cmdDelete_Click()
Application.DisplayAlerts = False
Dim I As Long

For I = lbxWorksheets.ListCount - 1 To 0 Step -1


Debug.Print I
Next I
Application.DisplayAlerts = True
End Sub

2
1
0

Lógica Final:
Private Sub cmdDelete_Click()
Application.DisplayAlerts = False
Dim I As Long

For I = lbxWorksheets.ListCount - 1 To 0 Step -1


If lbxWorksheets.Selected(I) Then
Worksheets(I + 1).Delete
lbxWorksheets.RemoveItem I
End If
Next I
Application.DisplayAlerts = True
End Sub

The ComboBox Control


Style - Informa se é possível inserir mais valores na Combo Box
Style 2 - Não permite que o User selecione outras informações além (Fonte)
Style 0 - Posso usar qq valor (Tamanho da Fonte)
RowSource - Indicativo que iremos usar nossa própria lista, e não algo nas ranges
Código Inicial:
Option Explicit
Private Sub cmdChangeFonts_Click()
Dim ws As Worksheet

For Each ws In Worksheets


ws.Cells.Font.Name = Me.cbxFont.Value
ws.Cells.Font.Size = Me.cbxFontSize.Value
Next ws
End Sub

Private Sub cmdExit_Click()


Unload Me
End Sub

Private Sub UserForm_Initialize()


With Me.cbxFont
.RowSource = ""
.AddItem "Arial"
.AddItem "Comic Sans MS"
.AddItem "Calibri"
End With
With Me.cbxFontSize
.RowSource = ""
.AddItem 12
.AddItem 24
.AddItem 36
End With
End Sub

Check Box:
On-Off
Retorna booleano - V ou F

Private Sub cmdActions_Click()


If Me.chkClear.Value Then
Cells.Clear
End If

If Me.chkSave.Value Then
ActiveWorkbook.Save
End If
End Sub

Private Sub cmdCancel_Click()


Unload Me
End Sub

Você também pode gostar