Excel VBA Bundle 2 Books Excel VBA and Macros and 51 Awesome Macros
Excel VBA Bundle 2 Books Excel VBA and Macros and 51 Awesome Macros
Excel VBA Bundle 2 Books Excel VBA and Macros and 51 Awesome Macros
READING ORDER
1 VISUAL BASIC INTRODUCTION
5 ERROR HANDLING
5.1 LOGICAL ERRORS
5.2 COMPILE ERRORS
5.3 RUN TIME ERRORS
6 ACTIVEX CONTROL
7.1 INTRODUCTION
7.2 DIFFERENCE BETWEEN BYREF AND BYVAL
7.3 BYREF (REFERENCE)
7.4 BYVAL (VALUE)
7.5 EXAMPLE
10 PROGRAMMING EXAMPLES
10.1 LEARNING BY EXAMPLES
10.2 1º PROJECT - CHANGE ALL WORKSHEETS NAME
10.3 2º PROJECT – SAVE EACH SHEET AS A NEW FILE
10.4 3º PROJECT – SAVE EACH SHEET AS PDF FILE
10.5 4º PROJECT – REFRESH ALL LINKS
10.6 5º PORJECT – SIMPLE LOGIN SYSTEM TO ACCESS THE SPREADSHEET
10.7 7º PROJECT – REGISTRATION FORM
11 INTRODUCTION
SPREADSHEET CONTROL
15. TRACK USERS WHO OPENED THE WORKBOOK
16. HIGHLIGHT ALL EDITED CELLS
17. PROTECT ALL WORKSHEETS
18. UNPROTECT ALL WORKSHEETS
19. PROTECT A SINGLE WORKSHEET WITH PASSWORD
20. PREVENT USER’S SAVE THE FILE
21. SIMPLE LOGIN SYSTEM TO ACCESS THE SPREADSHEET
ERROR MANAGEMENT
12 OTHERS
Mail Contact:
[email protected]
WHO SHOULD READ THIS BOOK?
If you want a book that uses a systematic and easy approach, complete with
numerous examples and full projects, then this book is for you. The goal of
this book is help you how to automate your tasks and create custom
applications using VBA programming language without thousands of
boring pages. This book is a fast lecture, which allows you to start coding
since the first chapter. No prior programming knowledge is required.
DEDICATION
This book is dedicated to my darling Flavia Bange, who always supported
me in every single moment of my life.
VBA (Visual Basic for Applications) is a programming language developed
by Microsoft. It is an awesome resource of Excel and other Office
programs. With VBA you can automate tasks and reports in Excel by
writing so-called macros, it is also possible develop tools, User Forms,
sophisticated applications and a wide variety of professional solutions.
The book starts exploring the necessary aspects to master Excel resources
with simple codes. These simple commands cover: make selections, do
copy and paste, apply number formatting, insert formulas and many other
aspects, which has a direct relation between commands and excel interface.
With these basic instructions section you are able to automate reports just
creating simple routines.
In the second part of this lecture, the approach is about VBA programming
logic, where is possible to understand the variables, logical statements,
repeating cycles, User Forms, and all sorts of advanced resources. In order
to facilitate the learning process, the book counts with wide variety of
examples to explain each concept including full projects at the end.
READING ORDER
The learning of VBA can be completely different for each user profile; this
book was created to meet all readers’ expectations from early beginners
who never had any contact with any programming language to most
advanced users who already master other languages.
The chapter structure is for absolute beginners. The first one do a short
introduction of VBA concepts and the second chapter, approach instructions
to control Excel resources, teaching the reader how to automate simple
tasks like copy and paste, open and close files, number formatting, filter and
any other straight interaction with Excel. Those commands lines don’t
constitute a programming logic; they are just simple instructions that
explain the concept of object, propriety and methods.
The third chapter start the approach about programing, introducing many
concepts around the most powerful techniques like loops, “if statements”,
correct variable declaration and others programming logic approach.
Experienced readers, after read the first introducing chapter can skip
temporally the second one for learning the programming session before
start the learning about objects (2º chapter), this order is just recommended
for those who already know programming logic and then can easily absorb
the VBA syntax. For absolute beginners is highly recommended follow the
chapter order to understand how the VBA interact with Excel before learn
programming concepts.
1 VISUAL BASIC
INTRODUCTION
The two basic structures in VBA are Sub (Sub-routines) and Function, the
difference is because the function return a value in the end. The function is
useful to provide a calculation and return a value for a Sub.
1.1 BASIC STRUCTURE
The sub structure:
Sub macro_name ( )
Algorithm
End Sub
The approach is especially about subs, functions are just for some cases. By
default, most examples in this book will have the following sub name:
Sub Learning ( )
Algorithm
End Sub
1.2 DEVELOPER TAB
The developer tab is the toolbar that contains the buttons to open the VBA
editor and create Form/ActiveX, this tab is hide by default, but you can add
it to the ribbon by following these steps:
Click in File menu
Select Options from the drop down menu
Click on the Customize Ribbon
Click on the Developer checkbox under the list of Main Tabs on the
right
Note: The + operator, when used with values works as sum, when used with
string work's as concatenation. For values concatenation, is necessary use
the operator &.
1.4 MODULES
When you want to run the VBA code, it's necessary store this code in a
module, which basically works like a Word document where you write your
routines. It's highly recommended store the collection of similar routines
grouped usually in terms of their functionality in the correct module. There
are Private and Public modules, in the first one, Functions and Sub-routines
are available only within that module. When it's public, they can be
accessed from anywhere. It is common practice to store utility functions in
separated modules.
1) New Module
There are individual module objects. Most codes in this book will be added
in a new module, the other objects will be used just for specific purpose,
like a trigger for open the workbook, or worksheets changes, those sort of
codes must be added in workbook or the current worksheet.
2) ThisWorkbook
ThisWorkbook is a private module of the Workbook Object. If you create
code which triggers following a workbook event, for example:
Workbook_Open(), Workbook_Close(), the code must be placed on the
workbook code module. There is only one module of this type per
workbook.
For change the module name, press F4 key to access the propriety and
change the default text.
When you add the module, the code window will automatically open; this is
the text area where code is allocated.
1.6 HELLO WORLD
The famous first learned code for any programming language, it allows the
student understand the most basic structure that communicate with users
using an interface. In VBA this code is:
Sub Learning ( )
Msgbox (“Hello World”)
End Sub
To run the code, there are three ways, the first is by clicking in the play
button right above the code window, the second is clicking in the tab Run >
Run Sub, and the last way is using the shortcut F5.
Breakpoint
Add a breakpoint basically set that the macro will stop to run in a specific
line. To still processing you can press play again or continues using the
debug by pressing F8. To insert breakpoints are three ways:
Debug toolbar > Toggle Breakpoint
Set the mouse cursor in the line and pressing F9
Click on the left grey are next to the code line
Note: At any time you can let your mouse linger over a variable or
property to show its value.
1.8 IMMEDIATE WINDOW
Immediate Window is an awesome tool that allows user to get immediate
answers and quickly execute code. It is built into the Visual Basic Editor,
and has many different uses that can be very helpful when writing macros
debugging code or displaying the results of your code.
There are two ways to get to the Immediate Window is to:
ToolBar > Show > Immediate Window
Pressing Ctrl+G
Note: The answer will be displayed on the next line, directly under the
code.
Note: Range object is one of the most important and most frequently used
objects.
Or
Note: Use methods with instructions Cells() will be completely useful when
applied with looping’s in some chapters ahead. Cells() is also limited for
individual elements, while Range() can get more than one object.
Or
Range(Cells(1,1),Cells(2,2)).Select
The method is also used with sheets, where is just necessary refer the name
inside quotation marks as the following example:
Worksheets(“Plan1”).select
Or
Sheets(“Plan1”).select
Note: The first one is used just for worksheets and don’t work for chart
tab’s.
Another way to select sheets is using the index of position instead the name.
The index consider the position from left to the right. For example, select
the first sheet refer to index number 1.
Worksheets(1).select
Or
Sheets(1).select
For select more than one sheet, it’s necessary use the command Array, as
the following example:
Sheets(Array(1,2,3)).select
Or
Sheets(Array(“Plan1”, “Plan2”, “Plan3”)).select
2.2.2 Activate
This method works similar with Select. Difference between select is that
you can get several objects at once while Activate just simply makes a
single one be active.
In the following example, five cells are selected, but only the first one is
activated.
For workbooks:
Workbooks(“NomeDoArquivo”).Activate
Or
Workbooks(1).Activate
For sheets:
Sheets (“NomeDoArquivo”).Activate
Or
Sheets (1).Activate
For cells:
Range("A1").Activate
Or
Cells(1,1).Activate
Note: Both methods are good for beginners understand how a code works.
But both have one thing in common, they are rarely ever needed and they
generally slow your code down. You can work directly on an object
without selecting or activating it and it is a good practice not to use these
unless needed.
2.2.3 End
This method is equivalent to pressing the key’s End + up arrow, End +
down arrow, End + left arrow, or End + right arrow as the following
examples:
Range(“A1”). End(xlDown).Select
Those codes are essential for automate excel navigation just using command lines. The methods also
works inside a range. For example:
Range(Selection, Selection.End(xlDown)).select
With this combination, selection works from the current selected cell, until the last one in a sequence.
There are a huge number of combinations to do selections, another exemple
using combinations:
Range(Selection, Selection.End(xltoRight)).select
Range(Selection, Selection.End(xlDown)).select
This code will select the last avaliable cell from left to the right and from
top to bottom.
2.2.4 Offset
The Offset method returns a reference to a range that is offset a number of
rows and columns from another range or cell.
Example:
ActiveCell.Offset(X,Y).Select
Ou
Range(“A1”).Offset(X,Y).Select
For example:
Range(“A1”).Offset(2,1).Select
The code is giving two combined methods, first the Offset(2,1), that change
the reference from the object (Range(“A1”)) for 2 rows and 1 column away,
than the method Select is used, and the referenced cell is selected.
In the next example bellow, the current position is used for back to original
position, than the method offset is informing the new reference is -2 rows
and -1 column away.
Note: Is important say that positive values are always to right and down
directions, negative values do the opposite, to the left and up.
The offset method can also be written inside a Range, which allows the user
create hundreds of combinations of the previous methods.
For example:
Range(ActiveCell.Offset(0,1), ActiveCell.Offset(2,2)).select
Or
Range(Range(“A1”).Offset(0,1), Range(“A1”).Offset(2,2)).select
The following example shows a simple and easiest routine of copy and
paste a selection:
Range(“B1”,”B3”).Copy
Range(“C1”).Select
ActiveSheet.Paste
The most efficient method for a simple copy and paste in VBA:
Range(“B1”,”B3”).Copy Destination:=Range("C3")
Note: The first method is good for beginners understand how a code
works. However, generally slow your code down. You can work straight
on an object without selecting or activating like in the second case, where
the object is pasted in the destination.
It is important to note that the method Copy can be used with worksheet
declared. Then it is possible copy and pastes a selection without change the
worksheet selection, like in the following example:
Sheets(“Sheet2”).Range(“B1”,”B3”).Copy Destination:=
Sheets(“Sheet1”).Range("C3")
With rows or columns the process is the same, in the following example the
reference for both are through index.
Copy from first to the second row:
Rows(1).Copy Destination:= Rows(2)
The previously example was about simple paste actions, but there are
options of specific methods to do a paste special:
The last option to add is the transpose in Paste Special, to do that just adds
this code:
Transpose:=True
The following example shows the application of transpose in paste special:
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlMultiply, Transpose:=True
2.2.6 Insert
Below is the code to insert range. Here inserting the column D from a copy
of column B.
Columns(2).Copy
Columns(4).Select
Selection.Insert
Fileld:=2 is the command that applied the criteria in the second position of
range. In the example it happens in the column B. Criteria1 is the first (and
in this example unique) argument used, to add new arguments it is
necessary add new criteria’s as in the following example.
Range("A1","B1").AutoFilter Field:=2, Criteria1:=">=0", Criteria2:="<40"
To remove autofilter through VBA code, just use the following code:
ActiveSheet.ShowAllData
2.2.9 SORT
In the following example, the sort method is applied in Range(“A1”,”B6”).
Range("A1:B6").Sort key1:=Range("B1:B6"), order1:=xlAscending, Header:=xlYes
2.3.3 Save As
This method do the Save As with VBA, the following examples shows the
different ways to do Save As, considering different FileFormat.
ActiveWorkbook.SaveAs Filename:=" C:\Aula.xlsx
",FileFormat:=xlOpenXMLWorkbookMacroEnabled
ActiveWorkbook.SaveAs Filename:=" C:\Aula.xlsx", FileFormat:=xlOpenXMLWorkbook
ActiveWorkbook.SaveAs Filename:=" C:\Aula.xlsb", FileFormat:= xlExcel12
ActiveWorkbook.SaveAs Filename:=" C:\Aula.xls", FileFormat:= xlExcel8
2.3.4 CLOSE
The following code just close the file.
Workbooks("Aula").Close savechanges:=False
The value of savechanges as false or true, just decide if the file will be
saved or not before close.
2.4 LINKS METHODS
Links basically defines the interactions between external files.
2.4.1 Update links
When a spreadsheet has a huge amount of information is linked with an
external sources, links won’t refresh automatically, than is necessary update
link’s. To execute this process with VBA, just use the following methods.
ActiveWorkbook.UpdateLink Name:= "C: \LinkedFile.xlsx ", Type:=xlExcelLinks
Example:
Sub Learning()
Range("B2:E8").Borders(xlEdgeLeft).LineStyle = xlContinuous
Range("B2:E8").Borders(xlEdgeLeft).Color = vbRed
Range("B2:E8").Borders(xlEdgeLeft).Weight = xlMedium
Range("B2:E8").Borders(xlEdgeRight).LineStyle = xlContinuous
Range("B2:E8").Borders(xlEdgeRight).Color = vbRed
Range("B2:E8").Borders(xlEdgeRight).Weight = xlMedium
Range("B2:E8").Borders(xlEdgeTop).LineStyle = xlContinuous
Range("B2:E8").Borders(xlEdgeTop).Color = vbRed
Range("B2:E8").Borders(xlEdgeTop).Weight = xlMedium
Range("B2:E8").Borders(xlEdgeBottom).LineStyle = xlContinuous
Range("B2:E8").Borders(xlEdgeBottom).Color = vbRed
Range("B2:E8").Borders(xlEdgeBottom).Weight = xlMedium
End Sub
2.5.5 Color of Sheet Tabs
Following Examples will show you how to change the Color of Sheet tabs
using Excel VBA. In the following example the Sheet2 tabs change color to
Red:
Sheets("Sheet2").Tab.ColorIndex = 3
3 EXCEL VBA PROGRAMMING
This chapter will approach the programming logic for creating algorithms
inside the sub-routines and functions. As mentioned in previous chapters,
methods and properties are good for beginners understand the interaction
between codes and Excel, but those simple commands doesn’t represent
“real programming”, in this section, the logic will be explored with focus in
productivity.
3.1 VARIABLE TYPES
This section explains this important topic and shows you how to use
variables in your VBA procedures. The first step to learn any programming
language is understand the variable declaration; the following table resume
the VBA variables:
By default, VBA doesn't require that you declare your variables and this
flexibility can easily lead to poor coding practices. The correct memory
allocation is important for code optimization. For example, you can store an
integer number as double, but it is a waste of memory.
The variables have some restrictions like special characters or start with
numbers.
Examples of wrong variable names:
Dim Var? As Integer
Dim 1Var As Integer
Dim Var-1 As Integer
It’s also possible declare a sequence of variables in the same line, as in the
following example:
Dim Value1, Value2, Value3, Value4, Value5, Value6 As Integer
Or
Dim Value1 As Integer, Name As String, RealValue As Double, RealDate
As Date
3.2 CREATING OBJECT VARIABLES
The object data type can store any kind of object. You just need do the
following two steps:
Declare the object variable.
Assign the object variable to an object.
Example 1:
Range (Selection)
Workbook (Spreadsheet)
Worksheet (Sheet)
Example of object declaration
Dim Selection_1 As Range
Dim Wsheet_1 As Workbook
Dim Wbook_1 As Workbook
Example 2:
Sub Learning()
Dim Selection _1 As Range
Selection _1 = Range(“A1”)
Selection _1 = 10
End sub
When run the code, the variable result get the sum and than the
Range(“A4”) receive this value.
3.4 ARRAY VARIABLES
In VBA a normal variable can store only one value at a time. Another way
to declare variables is through a list, which is called Array, like the
following example:
One Dimensional Array:
Dim Value1 (5) As Integer
The first one can allocate five variables in one dimension and the second
example can allocate 15 values in two dimensions.
The numbers just represent the index for each array position.
Explanation:
Variable Name is declared as Array String with three positions.
Variable Name index 0 retrieve the value Clara
Variable Name index 1 retrieve the value Clara
Variable Name index 2 retrieve the value Clara
Msgbox with storage names, Chr(13) is the code used to break lines.
Example 2:
Sub Learning ()
Dim MatrixArray(2, 2) As String
MatrixArray(0, 0) = "A "
MatrixArray(0, 1) = "B "
MatrixArray(1, 0) = "C "
MatrixArray(1, 1) = "D "
MsgBox "Letters:" & Chr(13) & MatrixArray(0, 0) & MatrixArray(0, 1) & Chr(13) &
MatrixArray(1, 0) & MatrixArray(1, 1)
End Sub
Explicação:
Variable MatrixArray declared as array with 2,2 positions
Variable MatrixArray with index 0,0 retrieve the letter A
Variable MatrixArray with index 0,1 retrieve the letter B
Variable MatrixArray with index 1,0 retrieve the letter C
Variable MatrixArray with index 1,1 retrieve the letter D
Msgbox with storage letters
3.5 INPUTBOX AND MSGBOX
The both are functions that displays message for the user and wait for a
return. The inputbox return a string and msgbox return a integer.
3.5.1 MsgBox
The MsgBox is a function that displays a message box on the screen and
waits for the user to click a button and then an action is performed based on
the button clicked by the user.
Syntax
MsgBox(prompt[, buttons] [, title] [, helpfile, context])
3.5.1.1 Prompt
Only prompt is a required parameter, which is used for display a message
for the user. The others parameters will change the box structure, changing
the buttons, the icon or title.
The following example shows the most basic message box, just using the
prompt.
MsgBox ("Message for the user")
Note: If the message extends to more than a line, then you can break lines
using a carriage return character (Chr(13)) or a linefeed character
(Chr(10)) between each line.
3.5.1.2 Button
The button code determines the structure of message box, the code is
divided in 4 groups, which can be combine to create a different structure.
The combination is the sum of values of different groups of tables bellow.
The code bellow determines the number and type of buttons displayed in
the dialog box
Note: You only can sum one code for each group
When the user click a button the VBA returns an integer indicating which
was clicked. The table below resumes the return codes.
The following example shows how get the user answer.
Example:
Sub Learning()
Dim Answer As Integer
Answer = MsgBox("The value is too high, wish continue ?", 36)
If Answer = 6 Then
MsgBox ("User Answered Yes")
End If
If Answer = 7 Then
MsgBox ("User Answered No")
End If
End Sub
3.5.2 InputBox
The InputBox is a function that displays a message box on the screen and
waits for the users to enter values in a text box. After entering the values, if
the user clicks the OK button, the function will return the text as a string.
Syntax
InputBox(prompt[, title] [, default] [, xpos] [, ypos] [, helpfile, context])
3.5.2.1 Prompt
Only prompt is a required parameter, which is used for display a message
for the user.
The following example shows the most basic input box, just using the
prompt.
Example 1:
InputVar = InputBox ("Enter a Number")
Example 2:
Sub RectangleCalc()
Dim Area As Double
Dim Perimeter As Double
Dim Length As Double
Dim Width As Double
Length = InputBox("Enter Length ", "Enter a Number")
Width = InputBox("Enter Width", "Enter a Number")
Area = Length * Width
Perimeter = 2 * (Length + Width)
MsgBox "Result: " & Chr(13) & "Area: " & Area & Chr(13) & "Perimeter: " & Perimeter
End Sub
3.6 FUNCTIONS WITH VBA
The WorksheetFunction is a object that access the accessible functions
inside Excel and use them as VBA methods. It's a good way for you don't
have to keep reinventing the wheel, with this resource you save time and
incress your productivity.
The following example shows how to use of a function inside the VBA
code.
Example 1:
Sub Learning()
Dim total as integer
Total = WorksheetFunction.CountA(Range("A:A"))
MsgBox (Total)
End Sub
The variable Total retrieve the value of function CountA, than the
“MsgBox” return the value 6, that is the number of filled cells.
You can apply any function you want; it’s just necessary use the correct
syntax and choose the correct arguments inside the function.
Example 2:
Sub Learning()
Dim Total As Integer
Total = Application.WorksheetFunction.SumIf(Range("A:A"), ">5", Range("A:A"))
MsgBox Total
End Sub
In this example, the variable Total retrieve the value of function SumIf, with
criteria “>5”, the result appears in the msgbox.
3.7 RECORD MACROS
When you record a macro, the Recorder captures almost every move you
make automatically creating a code with VBA. For example, can include
typing text or numbers, formatting cells, rows or columns, or even
importing data from an external source. Unfortunately, there are many
things, which you cannot perform with Macro Recorder, and this process
uses much more code than is actually required, which can slow your
process down.
4. In the Store macro in, select the object where you want to store the
macro.
5. The Description text box is optional and it’s brief description of what
the macro does.
7. When you finish, click Stop Recording in the same place where you
clicked Start.
4 PROGRAMMING CONTROL
STRUCTURES
Control Structures are powerful feature for any programming language.
These control structures are useful to save time to write a huge amount of
lines of code. It works to facilitate user to work with logic decisions and
calculations. The following list shows the most commonly functions used
on VBA with a brief description.
4.1 IF – THEN - ELSE
This structure basically does something if a condition is true; otherwise, do
something else (Else is optional). It's similar with VBA function If().
Syntax:
If [Condition] Then
[Code if condition is true]
Else
[Code if condition is false]
End If
The “Else” part of the code is optional, the structure can work just with the
“If” statement. The following example shows the code just using “If”.
If [Condition] Then
[Code if condition is true]
End If
You can also use “ElseIf” to include another condition inside the statement,
like the following structure:
If [Condition] Then
[Code if condition is true]
Elseif [Condition2]
[Code if condition2 is true]
Elseif (Condition3)
[Code if condition3 is true]
Else
[Code if any condition before was true]
End If
This second example provides the same functionality, but now using the
“ElseIf”, the result is the same, but the code is written more efficiently with
good practices.
Example 2:
Sub Learning()
Dim GradeResult As Integer
GradeResult = InputBox("Type your grade, 1 to 10")
If GradeResult = 10 Then
MsgBox ("Congratulations, your grade is perfect")
ElseIf GradeResult > 7 And GradeResult < 10 Then
MsgBox ("Your grade is good")
ElseIf GradeResult >= 6 And GradeResult <= 7 Then
MsgBox ("Your grade is average")
Else
MsgBox ("Your grade is low")
End If
End Sub
This third example shows how the code can be integrated with sheets,
analyzing the cell information and then inputting an answer (“OK” or “F”)
in the B column.
Sub Learning()
Dim ReferenceData As Date
ReferenceData = "05/04/2018"
Syntax:
For [Start Counter] To [End Counter] Step [Step value]
[Instructions]
Next
The following Example Demonstrate how For Next works.
Example 1:
Sub learning ()
For i = 1 To 10 Step 1
Range("A" & i) = i
Next i
End Sub
In this example, "i" is the counter, "1 to 50" is the range, and "1" is the step.
When the statement is initialized, the counter is set to the first number in the
range (i = 1) and then executes any code between the “for” and “next”
statements. Upon reaching the next statement, the program returns to the
statement and increases the value of the counter (i) by the value of the step.
In the next example, a double for is used to insert data’s in two directions,
rows and columns.
Example 2:
Sub learning()
For i = 1 To 10
For j = 1 To 3
Cells(i, j) = i + j
Next j
Next i
End Sub
Syntax:
Do While [Condition]
[Instructions]
Loop
Do Until [Condition]
[Instructions]
Loop
The statement can also be written with the condition in the end, as the
following syntax:
Do
[Instructions]
Loop While [Condition]
Do
[Instructions]
Loop Until [Condition]
This first example, show the basic concept of “Do while”, while condition i
< 5 is true, the code still doing the interactions.
Example 1:
Sub Learning()
Dim n As Integer
n=0
Do While i < 5
i=i+1
Range("A" & i).Value = "Company " & i
Loop
End Sub
Note 1: This same example could be created using For Next statement.
The second example shows how "Do While" can interact with Sheets, using
the condition to verify if the cell is not empty.
Example 2:
Sub Learning()
Range("C2").Select
Do While ActiveCell <> ""
If (ActiveCell > 25000000) Then
ActiveCell.Offset(0, 1) = "Good"
ActiveCell.Offset(0, 1).Interior.Color = vbGreen
Else
ActiveCell.Offset(0, 1) = "Bad"
ActiveCell.Offset(0, 1).Interior.Color = vbRed
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Note 1: You must take care with conditions in “Do While”, if your
condition never becomes true, VBA will be stuck in an infinite looping,
and the Excel can crash. In the previous example, the “ActiveCell.Offset(1,
0).Select” guarantee the code will not enter in an infinite loop.
4.4 FOR – EACH – NEXT
This is another statement for interactions; in this case, the function does
loop when you want to repeat a set of codes for each Excel element of a
collection or array.
Syntax:
For Each [Variable] in [Collection]
[Instructions]
Next
Example 1:
Sub Learning()
Dim Wkt As Worksheet
For Each Wkt In ActiveWorkbook.Worksheets
Wkt.Select
Wkt.Name = InputBox("Type the new name")
Next
End Sub
Note 1: The statement “For Each Next” uses a looping of the variable Wkt
in the collection of Worksheets (“ActiveWorkbook.Worksheets”) to repeat
the instructions that rename a selected worksheet.
Note 2: The variable Wkt is declared as Worksheet, it’s a good practice
that makes the code easier to write and read.
Example 2:
Sub Learning()
Dim Rng As Range
Dim Area As Range
Note: This example is used just to illustrate how the “For Each” works,
but you could apply the properties directly on the range.
4.5 SELECT CASE STATEMENT
The “Select Case”, is an alternative to “Else if”. The statement runs one
several group of codes, depending on value of an expression.
Syntax:
Select Case [Test Expression]
Case [Condition 1]
[Instructions]
Case [Condition 2]
[Instructions]
.
.
.
Case [Condition n]
[Instructions]
Case Else
[Instructions]
End Select [Condition]
The following example is the same that was made before in “If Then Else”
statement, the same code could have been written with “Select Case”. The
code is now simpler to read and read.
Example:
Sub Learning()
Dim GradeResult As Integer
GradeResult = InputBox("Type your grade, 1 to 10")
The following example illustrate how the code works in VBA, in the
example bellow the code is combined with “If Statement”:
Example:
Sub Learning()
Dim Var1 As Integer
Dim Var2 As Integer
Var1 = 3
Var2 = 4
4.7 VBA ERROR STATEMENT
There are three types of Error Statement, which hold one characteristic in
common, what instructs VBA Compiler what to do in case of runtime error.
4.7.1 On Error Goto 0
This statement basically disables any error trapping that could be present in
the procedure. This is the default mode in VBA, when a run time error
occurs VBA display its standard run time error message box.
Example:
Sub Learning()
Dim Var1 As Integer
Dim Var2 As Integer
Dim Var3 As Integer
Var1 = 3
Var2 = 0
On Error GoTo Label:
Var3 = Var1 / Var2
MsgBox ("Result: " & Var3)
Exit Sub
Label:
MsgBox (“Error found in the runtime")
End Sub
4.8 WITH STATEMENT
This statement sets a series of properties for a single object.
Syntax:
WithObject
.Propertie
End With
The following example helps to illustrate the difference between apply the
“With Statement” or not in the object Range(“C5”,”I24”).
Example 1:
Sub Learning()
Range("C5", "I24").Interior.Color = vbWhite
Range("C5", "I24").Font.Bold = True
Range("C5", "I24").Font.Name = "Arial"
Range("C5", "I24").Font.ColorIndex = 5
End Sub
Example 2:
Sub Learning()
With Range("C5", "I24")
.Interior.Color = vbWhite
.Font.Bold = True
.Font.Name = "Arial"
.Font.ColorIndex = 5
End With
End Sub
Note: The statement improves the code reading, usability and speed.
5 ERROR HANDLING
During the programming process, is common face a series of Errors, with
various characteristics and of the various causes. Some errors are easy to
identify and fix, but others are tough to discovery.
There are three main errors on Excel:
a) Logical Errors
b) Compile Errors
c) Run time Errors
5.1 LOGICAL ERRORS
This is the most difficult error to find, logical errors are also known as
‘bugs’, in this error the execution of VBA code will finish normally,
however, the result is unexpected return or a wrong calculation. In this
error’s the compiler will not identify any problem, because in terms of
syntax and run time, the code is perfect.
The only way to fix the code is by slowly reading each line to find a logical
mistake. As shown in the first chapter, the VBA editor provides a
debugging tool to assist you in finding those kind of errors. With the
debugging tool, you can run the code step-by-step to discovery where the
unexpected return is.
5.2 COMPILE ERRORS
Those are the simplest errors to identify, once the VBA editor recognized as
being a wrong syntax, or a variable that is not defined, or for any other
reason. In the moment you type a wrong expression and you press enter the
editor automatically highlight the error in red and shows a pop up.
5.3 RUN TIME ERRORS
Those errors allows the code to start, but during the execution, a runtime
error occurs and pop up a message in the screen. The pop up will inform
you details of the nature of the error, and shown the location where the code
has stopped.
As Compile Errors, this kind is not difficult to fix, once the editor also
shown the location where the code stop running. The following table shows
the runtime error codes.
In the following example the runtime error occurs when the code need to
divide a number by zero.
Example:
Sub Learning()
Dim a, b, c As Integer
a=3
b=0
c=a/b
End Sub
When an error occurs, the compile offer three available options, End,
Debug and Help. The first one end the macro execution, the second open
the debug tool, and the last open an office help webpage.
The Debug option is the most common to use in those cases to diagnose the
code when a crash is founded. When choose this option, the VBA editor
will open, and highlight the line where the code crashed. It is important to
note that although the editor highlight the line where the problem where
found, it does not imply necessarily this is the cause of the problem.
The following example how it clear how the highlight line is not often the
cause of the problem, note the found error is division by zero, what occurs
in the line where the variables are doing the division a/b, but the real causes
is on the line where the b variable receive the value zero. It’s a simple
example that errors can might have a wide range of origins.
6 ACTIVEX CONTROL
ActiveX Controls are the one of most important resources for automating
tasks with VBA, although these controls are very similar with Form
Controls, there are important differences between them. Forms controls
doesn’t need any kind of VBA programming, those structures do a direct
interaction with the spreadsheet, and they are used to perform some
restricted functions. Otherwise, the ActiveX Controls need a VBA code to
work properly, and they give you much more in terms of possibilities and
functions.
6.1 OBJECTS INTRODUCTION
The following objects are the most important for worksheets interaction:
Each element will have a special approach in the following sections of this
book with demonstration of use through examples. It’s important to note
that this chapter will approach the main five ActiveX Controls for
spreadsheets, but there are other important controls but they are not very
useful for sheets, they work better in forms, then the others elements will be
explored in the Forms Chapter.
To insert a Control in Excel spreadsheet:
Developer > Insert > ActiveX Controls
Once you have placed the object on the worksheet, it can be manipulated
activating the button Design Mode that is located beside the Insert button.
With design mode activated, you can resize the object and change the
positions. Other important feature of design mode is access the VBA code
easily, to do that, with the mode activated, just double click the object and
then the VBA editor will open and the declaration is already on the screen,
like the following example:
Note: The VBA automatically insert the Click declaration (the most used)
and automatically creates the Sub inside the current worksheet. It’s
important to always use the sub inside the same sheet where the object is
located.
With design mode activated, you can access their properties by selecting the
object and then clicking in the button besides ‘Design Mode’ button. The
image bellow show the properties of a CheckBox, it is important to note
that each Object has a difference set of properties. The properties can also
be accessed and modified through VBA instructions.
The object properties cover many aspects, as previously mentioned, each
object has their own set of properties, and the following sections will
explore the main properties of each object. The properties dialog have two
tabs to sort the items alphabetic or categorized.
Those properties cover categories like:
Appearance
Behavior
Data
Font
Misc
Font
Position
Good practices
There are some good practices to create new objects with ActiveX in VBA;
the most common is renaming the object with a prefix of the control and
their function. As the following example:
BT_Hide
CB_Option1; CB_Option2; CB_Option3
LB_Apple; LB_Grape; LB_Banana
CH_CheckAnswer_A; CH_CheckAnswer_B
OB_FirstOption; OB_SecondOption
6.2 BUTTON
Button is the simplest object; it basically works as a trigger that run a code.
The most common declaration is ‘Click’ than the code runs by clicking in
the button as the following example:
Main properties:
Example 1:
Private Sub CommandButton1_Click()
MsgBox ("Button pressed")
End Sub
Note: It’s important to say that the name and captions are two things
completely different, the name is the label inside the button and the name
is macro reference, in this example is the default CommandButton1.
Example 2:
This simple second example, demonstrate the interaction between Control
object with Excel interface. Then the button is used to hide or show a
worksheet.
Note: It is important to deactivate the Design Mode button; else, you are
not able to click the button.
Main properties:
Main methods:
There are two ways to add items in a ComboBox list, through Design
Properties interface, or using VBA codes. The first one is the most easy,
you just need to choose a range of cells inside the propertie ListFillRange,
as the following example:
Despite ListFillRange be the easily way to add items to a combobox, you
can also add items inside VBA code, to do that you just need to use the
AddItem method with combobox object like the following example:
Worksheet_SelectionChange(ByVal Target As Range)
Private Sub
CB_LIST.Clear
CB_LIST.AddItem "4"
CB_LIST.AddItem "2"
CB_LIST.AddItem "3"
CB_LIST.AddItem "4"
End Sub
Note 1: The method ‘Clear’ is used in the beginner to guarantee the items
won’t be added multiple times.
Note 2: In the example the default name of ComboBox1 was changed to
CB_List, the code is inside the current Worksheet object in VBA editor,
and are using the declaration SelectionChange.
6.4 CHECK BOX
This control is used to require from users a binary choice that is turn on or
off a value. The special characteristic of CheckBox provides to users the
possibility to select more than one object at time on the worksheet.
Main properties:
The following example shows how the CheckBox works with Excel
interaction, select the box automatically hides the corresponding worksheet,
and each object works independently.
Main properties:
The following example shows how the Option Button works. There are two
options to resize a generic rectangle as Portrait or Landscape.
OB_LandScape_Click()
Private Sub
ActiveSheet.Shapes("Rectangle 1").Width = 160
ActiveSheet.Shapes("Rectangle 1").Height = 90
End Sub
OB_Portrait_Click()
Private Sub
ActiveSheet.Shapes("Rectangle 1").Width = 90
ActiveSheet.Shapes("Rectangle 1").Height = 160
End Sub
6.6 LISTBOX
The ListBox display items in a list and the users can select one or multiple
items. With VBA you basically can code some functionality for items
selection. It’s common to use two ListBox’s to add or remove items. The
object can also works with the same purpose of ComboBox, but in this case
it’s not a dropdown list.
Main properties:
Main methods:
The following example is the most common for ListBox’s, you basically
create two List’s and two Buttons, and then you can add or remove items
between them. To create this little system you need to follow four main
steps. The first one is design your objects.
There are the following objects and their VBA names:
The next step is code the objects. The first goal in this step is add de items
in the first list. In this example items are added when the workbook is open.
The following code is added in the “ThisWorkbok” VBA object.
Private Sub Workbook_Open()
Sheets("Sheet1").LB_LIST1.Clear
Sheets("Sheet1").LB_LIST2.Clear
Sheets("Sheet1").LB_LIST1.AddItem "Apple"
Sheets("Sheet1").LB_LIST1.AddItem "Orange"
Sheets("Sheet1").LB_LIST1.AddItem "Banana"
Sheets("Sheet1").LB_LIST1.AddItem "Blueberry"
End Sub
Then, when you open the file again, the first list will be populated with the
added items. But the buttons doesn’t works yet.
Note 1: The Clear method is used in both lists to guarantee that the lists
are clear for any modification. The AddItem basically add new items at
the end of the list.
Note 2: How this sub is created inside the “ThisWorkbook”, it’s necessary
declare what is the Sheet that contains the object.
The following two subs are added in the Sheet Object, for declaration of
Button Click:
Private Sub BT_ADD_Click()
Dim SelectedItem1 As String
SelectedItem1 = LB_LIST1
LB_LIST1.RemoveItem (LB_LIST1.ListIndex)
LB_LIST2.AddItem (SelectedItem1)
End Sub
With these 3 Sub’s the project already works. But if you try to click the
button without any selected item then you’ll get a Runtime Error.
To solve this problem, it’s necessary create an alternative for those cases.
The following example modify the code, adding the “On Error Goto”
statement preventing cases where selection is empty, then the code jump to
label “NoSelection” which display the MsgBox informing the user to select
the item. On the other hand, if there is no error, the macro continues until
the statement “Exit Sub”, which finish the code before the MsgBox.
There are two separated structures, a Sub and a Function. The function has
two arguments (of type Long), basically the function is processing these
arguments to calculate a final value. Now, using a Sub, you can call this
function simply using the name of the function and informing the values of
each arguments that will be processed.
The sub is basically displaying a MsgBox that calls the function through the
name Area(3,5), where 3 and 5 are the arguments, then the function process
the calculation and return the value to the Sub, the sub finish the procedure
and display the message, which is the value of the area.
When you handle with functions, there are two-ways process, the sub is
calling the function and then the function return the value to the sub. You
can also order a sub to call another sub, but it will not return to the first sub,
then your exit need to be in your second structure, as the following
example:
In this case, there is a sub calling another sub, which is one single way. The
second sub will end the process instead return the value to the first one as
the function does.
7.2 DIFFERENCE BETWEEN BYREF AND BYVAL
In VBA you can pass an argument to a procedure with two different ways,
By Reference (ByRef) and By Value (ByVal), all the previous examples
was using the by reference, because this is the VBA default when you don’t
declare what you are using.
7.3 BYREF (REFERENCE)
You declare a variable ByRef when the procedure has a need to change the
underlying element in the calling code. Then the variable is a reference
from the original, when you change the reference you also changes the
original, as the following example:
Sub Learning ()
Dim x As Integer
x = 10
Call Calc (x)
MsgBox x
End Sub
7.4 BYVAL (VALUE)
You declare a variable ByVal when the calling code element underlying the
argument is a no modifiable element. Then the variable behavior as a copy
from the original, when you change the copy you do not affect the original,
as the following example:
Sub Learning ()
Dim x As Integer
x = 10
Call Calc (x)
MsgBox x
End Sub
As the example uses ByVal, the X value remain original, even the function
modifying the value multiplying by 3, when the procedure return to the
Sub, the X still with the original value.
7.5 EXAMPLE
Quadract Equation with Function
The following example is a function that was created to calculate a
Quadratic Equation. The parameters are informed inside Excel Worksheet,
the button has the default name of (CommandButton1), which is a sub that
just collect the values from the worksheet assign than to corresponding
variables and then call the Function.
Note: As the function just need to process the information without change
any value, the ByVal argument is used.
In the dialog below, activate the libraries of the programs that you want.
8.2 INTRODUCTION
The first step to automate others office applications is declare the new
application as objects. The logic works in the same way as Excel, but now
you are doing a reference for an external software.
We can take a word interaction as example; the first step is set a variable as
a word application object. In VBA you can use the function CreateObject to
return a reference. Once you set the object, you can manipulate the
application through this variable.
Sub Learning()
Dim wrdapp as object
Set wrdapp = CreateObject(“Word.Application”)
wrdapp.Documents.Add
wrdapp.Visible = True
Wrdapp.Quit
End Sub
These four lines do the basic procedures of open, show and then close the
document. The same procedure is used for create, display and finish a
PowerPoint presentation, there is just one obviously difference, instead the
method Documents.Add, now you use Presentations.Add, as the following
example:
Sub Learning()
Dim PptApp as object
Set PptApp = CreateObject("PowerPoint.Application")
PptApp.Visible = True
PptApp.Presentations.Add
PptApp.Quit
End Sub
As any other object, each application will have specific properties and
methods, some of them are similar and others are exclusive for the
application that you are doing the reference. The following section, will
explore the main applications that interacts with VBA, showing the main
methods and properties through practical examples.
8.3 INTERACT WITH OUTLOOK
As previously shown, the first step is create an object variable that will get
the object. With Outlook interaction, you can also create another object that
represent the mail item. The following example shows how to send a simple
e-mail, using VBA from Excel.
Main properties and methods:
Example:
Sub Send_Mail()
Dim OutApp As Object
Dim OutMail As Object
Dim bMessage As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
bMessage = "Type the content line 1" & vbNewLine & _
"Type the content line 2" & vbNewLine & _
"Type the content line 3"
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = bMessage
.Attachments.Add ("C:\examplefile.txt")
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Note that the first step was create two objects, the first one to represent
the Outlook Application (“OutApp”), and the second to represent the
Mail Item (“OutMail”). There is another variable to represent the
message (bMessage as string, Just to organize the code).
In the next step, basically the properties and methods interacts with
OutMail variable to create and send the email.
Note. The .Send command sends the email automatically, if uses .Display
instead, it create the e-mail but do not sends automatically.
8.4 INTERACT WITH POWERPOINT
There are a huge diversity of methods and properties of VBA with
PowerPoint, but the focus of this book is about Excel, then the following
explanation is enough to do some basic interactions between Excel and
PowerPoint.
Main properties and methods:
The following example shows a scenario that you export each cell for a new
Word Document:
Example:
Sub Learning()
Dim objWord As Object
Dim objDoc As Object
Dim strValue As String
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.documents.Add
Dim i As Integer
For i = 1 To 10
objDoc.Activate
strValue = Cells(i, 1)
objWord.Selection.TypeText Text:=strValue
objWord.Selection.TypeParagraph
Next i
End Sub
As any other application interaction, the first step is create a new object
variable that will receive the Workd Application. The objWord get the
WordApplication and the variable objDoc get the new document, the “For
To” creates the looping that will import cells values. The strValue get the cell
content, and the object objWord using the method .Selection.TypeText Text:=strValue
basically write this content inside the document. In the end, the TypeParagraph
is necessary to move to the next line.
9 USERFORMS
The UseForm is an awesome and useful tool, what provides an easy way for
your applications interact and get information from the user. The forms
also uses the same objects from Chapter 5 - ActiveX, but forms also uses
other elements that was not previously shown, because these others
elements are useful for Forms.
For create a UseForm, you just need to access your VBA editor (Alt + F11)
and then navigate to Inser > Userform.
When you add a form, automatically your useform window appears at the
right, than you can customize the form by adding the objects with the
ToolBox. If your Toolbox isn't visible, be sure to click the UserForm. It's
visible when the UserForm is selected. You can also activate the ToolBox
by clicking View > ToolBox.
Note: Select the object UseForm1 and press F4 to display the form
properties. The most important properties are:
Name – Change the VBA object name
Caption – The caption name at the top of the window
There are differences between this UserForm module and others objects
(Worksheets and Workbooks, Button, ListBox and so on), it is because in
these others, you just need to code their instructions. With Forms, you code
and design the object, then you can interact in two ways, the first is
displayed since you created the object and an empty window was displayed
at the right, and then you can access the code mode for your Form. To
display the code behind the form you just need to right click on the form
object at the VBAProject and then click on View Code, and you can back to
Design mode by clicking on View Object, as the following print screen:
Note: When you are creating Forms, you will always alternate between
these two modes, View Code and View Object.
9.1 VIEW OBJECT MODE
This is basically the design mode, where you create the structure of your
form, here you resize your window, put the objects, change their properties
and do everything else related with the visual part of your form. In this part,
you don’t code anything; you just organize your application.
ToolBox
The ToolBox works like ActiveX elements, you’ll recognize most of them,
because they are the same, and works in the same way. The following
picture show all the tools available at the toolbox.
1. Select Objects
2. Label
3. TextBox
4. ComboBox
5. ListBox
6. CheckBox
7. OptionButton
8. ToggleButton
9. Frame
10. CommandButton
11. TabStrip
12. MultiPage
13. ScrollBar
14. SpinButton
15. Image
16. RefEdit
These are not all the available controls, there are many others; you can see
the complete list by right clicking on any Control and selecting "Additional
Controls". However the list above provide than enough flexibility.
The objects: ComboBox, ListBox, CheckBox, OptionButton,
CommandButton were all cover in previous Chapter 5 ActiveX, they work
in the exactly same way, the only difference is because you put them inside
the form instead the worksheet. The other tools works as the description
bellow:
Select Objects
This is the only tool that actually is not an object; it is just a selection
tool. You can select, resize and move other objects.
Label
This is a text label that you can insert in your form, and the user can’t
change the value.
TextBox
This object holds a text box that the user can either enter or change.
ToogleButton
This object basically works as a light switch; you can set On or Off.
Frame
This object works to create a group for controls. You can group your
controls by draw a frame first, and then draw other controls inside this
frame.
TabStrip
This object creates multiple pages for the same area of window.
MultiPage
This one works in a similar way with TabStrip, but the difference is
because MultiPage allows different controls on each page.
ScrollBar
Once you start coding, the process is the same of any other object. It is just
important to note, that you can access your form in any other Sub, just by
calling the Form VBA name and using the method “Show”, as the
following Example:
There is just a form with label with caption “Test”, without any code. Then
the Sub Learning which is inside Sheet1 object, will call the form, just by
using the UserForm1 object with method Show.
Note: This is not the Code Mode of UserForm, it is just a Sub inside the
Sheet1 object which is calling the form.
When you run the Sub inside the Sheet1, it display the form:
9.3 USERFORM EXAMPLES
The best way to understand how Form’s works is through examples. This
first one basically creates a Form that select the Next or Previous
worksheet. The first Step is create the user interface, which contains the
Window with two Buttons (Previews and Next).
Object Mode:
Code Mode:
Private Sub BT_Next_Click()
If ActiveSheet.Index = Worksheets.Count Then
Sheets(1).Select
Else
ActiveSheet.Next.Select
End If
End Sub
Note: In this scenario, the “if statement” is working to avoid any error. If
you have the last worksheet selected and you try to use the method
Next.Select, you’ll get an error. The “if statement” is basically verifying if
you have the last worksheet already selected and then select the first one
when you click the button Next. The same logic is applied at the first
worksheet, the “if statement” is verifying if have the first one selected,
and then select the last one when you press the button previous.
10 PROGRAMMING EXAMPLES
10.1 LEARNING BY EXAMPLES
Despite the earlier chapters did a complete approach about VBA resources,
one of the best ways to learn and improve the Excel VBA skill is by
exploring examples. The purpose of this section is introduce a simple
scenario where you need to create a solution, and then provides you a full
example code of how solve the problem.
The main aspects of the following examples is combine many conceptions
previously approached. Some examples are part of a book “51 Awesome
Macros” and others were created just for this section.
It is really important that you try to practice your own codes before you see
the answer. This process helps you to understand the concepts of VBA.
Then you can create your own routines and think with VBA programming
logic.
10.2 1º PROJECT - CHANGE ALL WORKSHEETS
NAME
In this scenario, you need to create a macro that uses a looping structure
that select each worksheet, one by one, and then show a InputBox where
you can type a new name for the sheet.
SOLUTION:
Sub ChangeSheetName()
Dim NewName as String
For Each Sheet In Worksheets
Shortcut1:
Sheet.Select
NewName = InputBox("What is the new name for this sheet?")
If NewName = "" Then
Exit Sub
End If
On Error GoTo Shortcut1:
ActiveSheet.Name = NewName
Next
End Sub
EXPLANATION:
FIRST STEP
The first step is define the variable “NewName” as string and use the
looping structure. In this example we use the “For Each” (You could also
use “For To” combined with WorkSheets.Count), with object Sheet, inside
the group Worksheets, this help us to cover each worksheet easily.
For Each Sheet In Worksheets
‘[Instructions]
Next
Second Step:
Inside the looping, we apply the InputBox that provides an interface for
uses type the new name, it’s also important to verify if the variable is not
empty (to prevent error’s) and them the object ActiveSheet with property
name receives the value of NewName.
Note: In case of invalid characters or any other error, this statement: “On
Error GoTo Shortcut1:”, basically return the code to the InputBox.
10.3 2º PROJECT – SAVE EACH SHEET AS A NEW
FILE
You need to create a macro that automatically saves each worksheet as a
different file in the same path.
SOLUTION:
Sub SaveSheets()
Dim wkb, iFileNames, PathFolder As String
wkb = ActiveWorkbook.Name
PathFolder = "C:\DestinyFolder"
For i = 1 To Worksheets.Count
Worksheets(i).Select
iFileNames = ActiveSheet.Name
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:= PathFolder + "\" + iFileNames + "." & "xlsx"
ActiveWorkbook.Close
Workbooks(wkb).Activate
Next
MsgBox "File Saved with Success"
End Sub
EXPLANATION:
FIRST STEP
Define your variables, in this solution we are using Wkb, PathFolder and
iFileNames as Strings.
SECOND STEP
Define the Wkb as ActiveWorkbook.Name, it help us to go back to main
file whenever we want using the method Activate.
THIRD STEP
USE A LOOPING STRUCTURE, IN THIS EXAMPLE WE ARE USING THE “FOR TO”,
(YOU COULD ALSO USES THE “FOR EACH”), FROM 1 (FIRST SHEET) TO
WORKSHEETS.COUNT (THE LAST SHEET).
FOURTH STEP
Insert the instructions inside the looping, the sequence basically is: Assign
the variable with the WorkSheet Name, Select the Worksheet, do a Copy,
Save as in the path using the Sheet Name and extension as .xlsx, close the
file and Activate our main File. Then the looping still processing the code
until the last sheet.
10.4 3º PROJECT – SAVE EACH SHEET AS PDF FILE
This project is very similar with the second, you need to create a macro that
saves each worksheet as a PDF file.
SOLUTION:
Sub SaveWorkshetAsPDF()
Dim ws As Worksheet
Dim PathFolder As Integer
PathFolder = "C:\DestinyFolder"
For Each ws In Worksheets
On Error Resume Next
ws.ExportAsFixedFormat xlTypePDF, PathFolder & "\" & ws.Name & ".pdf"
Next ws
End Sub
EXPLANATION:
FIRST STEP
The first step is define a variable for the worksheet object and a string that
receives the directory path. We assign the variable PathFolder with the path
of destiny folder in the system.
SECOND STEP
Then we choose the looping method, in this example we are using the For
Each.
For Each ws In Worksheets
‘[Instructions]
Next ws
THIRD STEP
Now it is just necessary define the instructions inside the looping, which is
the method ExportAsFixedFormat xlTypePDF. Then we also assign the
path, the name and the format (which obviously is .pdf).
10.5 4º PROJECT – REFRESH ALL LINKS
This is a useful macro, you need to create a simple looping routine that
automatically refresh all Excel Links with external sources.
SOLUTION:
Sub LinksUpdate()
Dim linksarray As Variant
linksarray =
ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
For i = 1 To UBound(linksarray)
ActiveWorkbook.UpdateLink Name:=linksarray(i),
Type:=xlLinkTypeExcelLinks
Next i
End Sub
EXPLANATION:
FIRST STEP
Declare the variable that receives the link sources. In this example the
variable is linksArray declared as Variant (The variable will receive an
array)
SECOND STEP
Assign the object ActiveWorkbook with LinkSources method to the
variable LinksArray.
THIRD STEP
Create a looping, in this example we are usign the “For To” from 1 to the
total amount of links “UBound(linkarray)”.
FORTH STEP
Define the instructions inside the looping, what basically is apply the
method: UpdateLink to the object ActiveWorkBook. The LinksArray
variant provides each link that’s updating.
Note: The VBA UBound function returns the highest subscript for a
dimension of a supplied array, in this example returns the number of
available links.
10.6 5º PORJECT – SIMPLE LOGIN SYSTEM TO
ACCESS THE SPREADSHEET
There are many ways to create a login system, the best way to do this is
creating a custom form where you create all the system you wanted.
However, for this example, the goal is create a login system just using the
code to register users and “InputBoxs” to require the login and the
password.
The following diagram help to understand how this simple system will
work:
SOLUTION:
Sub Auto_Open()
Dim iUser(1 To 999) As String
Dim iPassWord(1 To 999) As String
Dim UserOK As Boolean
Dim PassOK As Boolean
'User Register
'-------------------
iUser(1) = "Daiana"
iUser(2) = "Clark"
iUser(3) = "Bruce"
'-------------------
iPassWord(1) = "1345"
iPassWord(2) = "1234"
iPassWord(3) = "5367"
'-------------------
UserOK = False
PassOK = False
Shortcut2:
InputUser = InputBox("Type your user name: ")
For i = 1 To 999
If iUser(i) = InputUser And iUser(i) <> "" Then
UserOK = True
GoTo Shortcut1:
End If
Next
Shortcut1:
If UserOK = True Then
InputPassword = InputBox("Welcome: " & InputUser & ", type your
password:")
If iPassWord(i) = InputPassword Then
Exit Sub
Else
question = MsgBox("Wrong password, do want to try again ?", vbYesNo)
If question = 6 Then
GoTo Shortcut1:
Else
MsgBox "This file will close"
ActiveWorkbook.Close
End If
End If
Else
question = MsgBox("Wrong user name, do want to try again ?",
vbYesNo)
If question = 6 Then
GoTo Shortcut2:
Else
MsgBox "This file will close"
ActiveWorkbook.Close
End If
End If
End Sub
EXPLANATION:
FIRST STEP
The first step is obviously declare the variables, but in this example it’s
necessary declare users and passwords as array, then each index can receive
a different register. The Booleans is for verify if User and Password are OK.
Then we created the following variables:
Dim iUser(1 To 999) As String
Dim iPassWord(1 To 999) As String
Dim UserOK As Boolean
Dim PassOK As Boolean
SECOND STEP
How it is a simple login system, the User Names and Passwords are
registered inside the own code. Each index of User and Password variables
correspond a different register. Then the iUser(1) has the iPassWord(1), and
so on. It is also important to assign the Booleans with false; they only
become true when the user answer the login and password correctly.
THIRD STEP
Now it is necessary require the Login Name with an InputBox. This
example was created with an array from 1 to 999, what allows 999
registers; then we use the “For To” to create a looping between all available
registers. If the InputBox receives a valid username, the code skip to label
“ShortCut1” and then the Boolean becomes true, else the Boolean still false.
FORTH STEP
This step, basically verifies if Boolean “UserOK” is true (What means the
username is correct), a InputBox ask for the password, if the Password is
correct, the code run the “Exit Sub” end finish the macro. In another hand,
if the Password or Username are wrong, the macro ask for another try, else
the file will close.
10.7 7º PROJECT – REGISTRATION FORM
The goal of this project is create a registration form, to insert and store
data’s as name, address and phone. There are thousands of ways to create
this form, on this project, will need to create a form that interacts with
Excel worksheet. The form will read, insert and delete data’s from
worksheet.
The following picture shows the form model of this project.
Public NAME, LNAME, GENDER, COUNTRY, STATE, CITY, ADDRESS, PHONE, PHONE2 As
String
Public nRow, pos As Long
Public ChangesOK As Boolean
After define the project variables, is necessary create the sub instructions.
There are nine Sub’s in the Registration form, each one is fundamental for
the application functionality.
The Main Form:
1. UserForm_Initialize()
2. BT_REGISTER_Click()
3. BT_SAVE_Click()
4. BT_DELETE_Click()
5. BT_SEARCH_Click()
6. BT_CLEAR_Click()
7. LB_REGISTERS_Change()
8. Insert()
9. UpdateText()
2. BT_REGISTER_Click()
First Step
Set the variable nRow to get the total of used rows, using the method
Application.WorksheetFunction.CountA.
Second Step
Call the “UpdateText” Sub, which associate the variables with Text Boxes
values, then the” if Statement”, verifies if three important variables are
empty or not.
Third Step
Call the “Insert” Sub, which fill the cells with variable values.
3. BT_SAVE_Click()
First Step
Set the Boolean ChangesOK as False, it is necessary to avoid the sub
LB_REGISTERS_Change() in this case.
Second Step
Set the variable “pos” as LB_REGISTERS.ListIndex + 2, this variable
represent the row position in the worksheet, it is necessary sum 2 because
the ListBox count from zero while the worksheet row start with 1 and the
worksheet also has a head.
Third Step
The last Step of this Sub is set the Cells values to get the Forms
information. There are a “if statement” to check if ComboBox is with male
of female value.
4. BT_DELETE_Click()
First Step
Set the variable pos as LB_REGISTERS.ListIndex + 2, this variable
represent the row position in the worksheet, it is necessary sum 2 because
the ListBox count from zero while the worksheet row start with 1 and the
worksheet also has a head.
Second Step
The second step is just for delete the row with Rows(pos).Delete
Third Step
The last step of this sub select the previous ListBox item. The “On Error
Resume Next” is applied to prevent error if the user delete the first row.
On Error Resume Next
LB_REGISTERS.Selected(pos - 1) = True
5. BT_SEARCH_Click()
This sub is just to show the Search Form.
FORM_SEARCH.Show
6. BT_CLEAR_Click()
This sub is just to clear all fields and select the default Option Button as
Male. The procedure to clear fields is simple, just set the value as empty
using “”.
TXT_NAME.Value = ""
TXT_LNAME.Value = ""
OB_MALE.Value = True
CB_COUNTRY.Value = ""
TXT_STATE.Value = ""
TXT_CITY.Value = ""
TXT_ADDRESS.Value = ""
TXT_PHONE.Value = ""
TXT_PHONE2.Value = ""
7. LB_REGISTERS_Change()
This sub is activated for any selection change inside the list. It provides the
update of the forms fields with ListBox selection.
First Step
As previously mentioned the ChangesOK Boolean works as a trick to run
the update just when necessary. When the Boolean is false, the code exit the
Sub.
Second Step
Each Text Box and the Option Button (Male and Female) are updated
according to the ListBox selection. The following code do this procedure.
For the option box, the “If Statement” provides the correct selection
according to the ListBox information (Male or Female).
TXT_NAME.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 0)
TXT_LNAME.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 1)
If LB_REGISTERS.List(LB_REGISTERS.ListIndex, 2) = "Male" Then
OB_MALE.Value = True
OB_FEMALE.Value = False
Else
OB_MALE.Value = False
OB_FEMALE.Value = True
End If
CB_COUNTRY.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 3)
TXT_STATE.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 4)
TXT_CITY.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 5)
TXT_ADDRESS.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 6)
TXT_PHONE.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 7)
TXT_PHONE2.Value = LB_REGISTERS.List(LB_REGISTERS.ListIndex, 8)
8. Insert()
As previously mentioned, this sub will just update the worksheet
information according to the Variables values.
9. UpdateText()
As previously mentioned, this sub will just update the variables according
with Text Box and Option Button information. The Option Button, uses a
“if Statement” to associate the gender.
NAME = TXT_NAME.Value
LNAME = TXT_LNAME.Value
If OB_MALE.Value = True Then
GENDER = "Male"
Else
GENDER = "Female"
End If
COUNTRY = CB_COUNTRY.Value
STATE = TXT_STATE.Value
CITY = TXT_CITY.Value
ADDRESS = TXT_ADDRESS.Value
PHONE = TXT_PHONE.Value
PHONE2 = TXT_PHONE2.Value
First Step
The first step is the variable declarations, there are three variables declared
as Strings that will receive the column position (“COL”), the row position
(“ROW”) and the text to find (“TXTSEARCH”).
Dim COL As String
Dim ROW As String
Dim TXTSEARCH As String
Second Step
The second step verifies the selected Option Box to define the column. The
variable TXTSEARCH get the textbox value.
If OB_SNAME.Value = True Then
COL = "A"
ElseIf OB_SLNAME.Value = True Then
COL = "B"
ElseIf OB_SPHONE.Value = True Then
COL = "H"
End If
TXTSEARCH = TXT_SEARCH
Third Step
The “On Error GoTo sError” works moving the code reading to the end
with sError label. Then an MsgBox display the message: "Registration not
found".
Fourth Step
The last step verifies if the TXTSEARCH is a number or not, then the
“Application.WorkSheetFunction.Match”, return the row, the method
Selected with True Value activates the searched line in the listbox. The
ROW is subtracting 2 for the difference between the worksheet and the
listbox, the sheet start counting from 1 and it has a header, while the listbox
starts from zero.
If IsNumeric(TXTSEARCH) Then
ROW = Application.WorksheetFunction.Match(CLng(TXTSEARCH),
Range(COL & ":" & COL), 0)
Else
ROW = Application.WorksheetFunction.Match(CStr(TXTSEARCH),
Range(COL & ":" & COL), 0)
End If
FORM_REGISTER.LB_REGISTERS.Selected(ROW - 2) = True
Exit Sub
2. TXT_SEARCH_KeyDown()
This sub works just to recognize the Enter Button that will call the
“BT_SEARCH_Click”, the “if statement” is verifying if the user pressed
the Enter Key, that KeyCode is 13.
2. Select the object to allocate the macro, in most cases, the user can
insert the code in a new module; by right click in the Microsoft Excel
Objects folder, Insert, Module.
3. Insert the macro in the text box and run the code clicking in “Play”
button, or pressing the shortcut F5. The user can also run the macro
“Step by Step”, to verify each line of code, with the shortcut F8 to
debug the code.
Note 1. For some macros, it is necessary allocate the code in specific
objects (Sheet’s or ThisWorkbook object), for those cases, there are a note
specifying how to proceed.
Note 2. Once the macro is ready in VBA editor, just close the Visual Basic
window. To access the macro again, can do it easily and quickly in the
Developer superior tab and button Macros.
Note 3: If the tab “Developer” is not available, just follow the steps bellow:
1) File
2) Options
3) Customize the Ribbon
4) In the selection, just check the option Developer
OPEN SAVE AND CLOSE
Sub Openandmax()
Dim FileName As String, FolderPath As String, Extension As String
FolderPath = "C:\Users\usertest\Documents"
FileName = "Workbook1"
Extension = "xlsx"
Dim wkb As Workbook
On Error Resume Next
Set wkb = application.Workbooks(FileName)
If Err <> 0 Then
Set wkb = application.Workbooks.Open(FolderPath + "\" + FileName + "."
& Extension, UpdateLinks:=0)
End If
On Error GoTo 0
Workbooks(FileName).Activate
End Sub
Sub CopiarSaida()
Dim iPath, iFileName, iSheet As String
iSheet = "Plan3"
iPath = "C:\Users\UserTest\Documents\"
iFileName = "Planilha.xls"
Worksheets("Sheet1").Copy
Cells.Copy
Cells.PasteSpecial Paste:=xlPasteValues
ActiveWorkbook.SaveAs Filename:= iPath & iFileName, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled
End Sub
Sub SaveBackup()
ThisWorkbook.SaveCopyAs Filename:=ThisWorkbook.Path & _
"\" & Format(Date, "mm-dd-yy") & " " & _
ThisWorkbook.Name
End Sub
Sub SaveSheets()
Dim wkb, iFileNames As String
wkb = ActiveWorkbook.Name
PathFolder = "C:\DestinyFolder"
For i = 1 To Worksheets.Count
Worksheets(i).Select
iFileNames = ActiveSheet.Name
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:= PathFolder + "\" + iFileNames + "."
& "xlsx"
ActiveWorkbook.Close
Workbooks(wkb).Activate
Next
MsgBox "File Saved with Success"
End Sub
Sub SaveWorkshetAsPDF()
Dim ws As Worksheet
PathFolder = "C:\DestinyFolder"
For Each ws In Worksheets
On Error Resume Next
ws.ExportAsFixedFormat xlTypePDF, PathFolder & "\" & ws.Name &
".pdf"
Next ws
End Sub
Note 1. Change the name of file, extension and folder path, highlighted in
bold.
Note 2. For change, erase or include new path’s, just need to modify the
example. For inclusion, just add FolderPath(4), FolderPath(5) and so on.
Sub SaveFile()
Dim NomeArquivo, Extensao As String
Dim iFolder(1 To 999) As String
iFileName = "File Name"
iExtension = "xls"
iFolder(1) = "C:\DestinyFolder"
iFolder(2) = "C:\DestinyFolder"
iFolder(3) = "C:\DestinyFolder"
For i = 1 To 999
If iFolder(i) = "" Then
GoTo ExitShortcut:
End If
Perg = MsgBox("Save file as: " & iFileName & " in the folder: " &
iFolder(i), vbYesNo)
If Perg = vbYes Then
ActiveWorkbook.SaveAs Filename:=iFolder(i) + "\" + iFileName + "."
& iExtension
End If
Next i
ExitShortcut:
MsgBox "File Saved with Success"
End Sub
Option Explicit
Dim StartTime As Date
Dim EndTime As Date
Dim Elapsed As Double
Dim iMinutes As Long
Dim dblSeconds As Double
Private Sub WorkBook_Open()
StartTime = Now
End Sub
Private Sub WorkBook_BeforeClose(Cancel As Boolean)
EndTime = Now
Elapsed = 86400 * (EndTime - StartTime)
If Elapsed < 60 Then
MsgBox "This file has been used for: " & Format(Elapsed, "#0.0") & "
Seconds", vbInformation + vbOKOnly
Exit Sub
Else
On Error GoTo ShortcutA:
iMinutes = Elapsed / 60
On Error GoTo ShortcutA:
dblSeconds = Elapsed - (60 * iMinutes)
MsgBox " This file has been used for: " & Format(iMinutes, "#") & ":" &
Format(dblSeconds, "00") & " Minutes", vbInformation + vbOKOnly
Exit Sub
End If
ShortcutA:
MsgBox "When you open the file again, the time will be recorded"
End Sub
INTERACTION WITH CHARTS
Note. The code will adjust all charts in the active worksheet
Before:
After:
Sub AjustGraphic()
For i = 1 To ActiveSheet.ChartObjects.Count
ActiveSheet.ChartObjects(i).Select
Dim MaxScale, MinScale, MyPoint, DefaultPosition, AdjustedPosition As
Long
Dim MySeries As Series
Dim PointsArray As Variant
With ActiveChart
MaxScale = .Axes(xlValue).MaximumScale
MinScale = .Axes(xlValue).MinimumScale
For Each MySeries In .SeriesCollection
If MySeries.ChartType <> xlColumnClustered And _
MySeries.ChartType <> xlLine And _
MySeries.ChartType <> xlLineMarkers Then
GoTo NEXTSERIES
End If
PointsArray = MySeries.Values
For MyPoint = LBound(PointsArray) To UBound(PointsArray)
If MySeries.Points(MyPoint).HasDataLabel = False Then
GoTo NEXTDOT
End If
If MySeries.ChartType = xlColumnClustered Then
MySeries.Points(MyPoint).DataLabel.Position =
xlLabelPositionOutsideEnd
If PointsArray(MyPoint) > MaxScale * 0.9 Then
MySeries.Points(MyPoint).DataLabel.Position =
xlLabelPositionInsideEnd
End If
End If
If MySeries.ChartType = xlLine Or MySeries.ChartType =
xlLineMarkers Then
MySeries.Points(MyPoint).DataLabel.Position = xlBelow
If MyPoint > 1 Then
If PointsArray(MyPoint) > PointsArray(MyPoint - 1) Then
MySeries.Points(MyPoint).DataLabel.Position = xlAbove
Else
MySeries.Points(MyPoint).DataLabel.Position = xlBelow
End If
End If
If PointsArray(MyPoint) > MaxScale * 0.9 Or _
PointsArray(MyPoint) < MinScale * 1.5 Then
MySeries.Points(MyPoint).DataLabel.Position = xlRight
End If
End If
NEXTDOT:
Next MyPoint
NEXTSERIES:
Next MySeries
End With
Next
End Sub
Sub RedmCharts ()
Dim i As Integer
For i = 1 To ActiveSheet.ChartObjects.Count
With ActiveSheet.ChartObjects(i)
.Width = 300
.Height = 200
End With
Next i
End Sub
EXCEL LINKS MANAGEMENT
Sub LinksUpdate()
Dim linksarray As Variant
linksarray =
ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
For i = 1 To UBound(linksarray)
ActiveWorkbook.UpdateLink Name:=linksarray(i),
Type:=xlLinkTypeExcelLinks
Next i
End Sub
Sub BreakLinks()
Dim alinksarray As Variant
alinksarray =
ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
Do Until IsEmpty(alinksarray)
ActiveWorkbook.BreakLink Name:=alinksarray(1),
Type:=xlLinkTypeExcelLinks
alinksarray =
ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
Loop
End Sub
Note. Change the values of path, what is highlighted with bold. File1 is the
current link and File2 is the new link wanted.
Sub ChangeLinks()
Dim File1, File2 As String
Dim wkb, wkb2 As String
wkb = ActiveWorkbook.Name
File1 = " C:\Users\usertest\Documents\ Planilha1.xls"
File2 = " C:\Users\ usertest \Documents\ Planilha2.xls"
Application.DisplayAlerts = False
Workbooks.Open Filename:=Arquivo2, UpdateLinks:=0
wkb2 = ActiveWorkbook.Name
Workbooks(wkb).Activate
ActiveWorkbook.ChangeLink Name:= File1, NewName:= File2,
Type:=xlLinkTypeExcelLinks
Workbooks(wkb2).Activate
ActiveWorkbook.Close
Application.DisplayAlerts = False
Workbooks(wkb).Activate
End Sub
SPREADSHEET CONTROL
Sub Auto_Open()
Dim iLine As Integer
Dim iDate, iTime As Date
iDate = Date
iTime = Time
iLine = Application.WorksheetFunction.CountA(Worksheets("Access
Control").Range("A1", "A1048576")) + 1
Worksheets("Access Control ").Range("A" & iLine) =
Application.UserName
Worksheets("Access Control ").Range("B" & iLine) = iDate
Worksheets("Access Control ").Range("C" & iLine) = iTime
Columns(1).AutoFit
Columns(2).AutoFit
Columns(3).AutoFit
End Sub
Option Explicit
Private SelectA As Object
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Variant
For Each cell In Target
If SelectA.Exists(cell.Address) Then
If SelectA.Item(cell.Address) <> cell.FormulaR1C1 Then
cell.Interior.ColorIndex = 35
End If
End If
Next
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim cell As Variant
Set SelectA = Nothing
Set SelectA = CreateObject("Scripting.Dictionary")
For Each cell In Target.Cells
SelectA.Add cell.Address, cell.FormulaR1C1
Next
End Sub
Sub ProtectSheets()
Dim wksht As Worksheet
For Each wksht In ActiveWorkbook.Worksheets
wksht.Protect Password:="password"
Next wsheet
End Sub
Sub unprotectsheets()
Dim wsheet As Worksheet
For Each wsheet In ActiveWorkbook.Worksheets
wsheet.Unprotect Password:="password"
Next wsheet
End Sub
Sub Auto_Open()
Dim iUser(1 To 999) As String
Dim iPassWord(1 To 999) As String
Dim UserOK As Boolean
Dim PassOK As Boolean
'User Register
'-------------------
iUser(1) = "Daiana"
iUser(2) = "Clark"
iUser(3) = "Bruce"
'-------------------
iPassWord(1) = "1345"
iPassWord(2) = "1234"
iPassWord(3) = "5367"
'-------------------
UserOK = False
PassOK = False
Shortcut2:
InputUser = InputBox("Type your user name: ")
For i = 1 To 999
If iUser(i) = InputUser And iUser(i) <> "" Then
UserOK = True
GoTo Shortcut1:
End If
Next
Shortcut1:
If UserOK = True Then
InputPassword = InputBox("Welcome: " & InputUser & ", type your
password:")
If iPassWord(i) = InputPassword Then
Exit Sub
Else
question = MsgBox("Wrong password, do want to try again ?", vbYesNo)
If question = 6 Then
GoTo Shortcut2:
Else
MsgBox "This file will close"
ActiveWorkbook.Close
End If
End If
Else
question = MsgBox("Wrong user name, do want to try again ?",
vbYesNo)
If question = 6 Then
GoTo Shortcut2:
Else
MsgBox "This file will close"
ActiveWorkbook.Close
End If
End If
End Sub
ERROR MANAGEMENT
Sub CheckError()
Dim ws As Worksheet
Dim ra As Range
For Each ws In Worksheets
For Each ra In ws.UsedRange
ra.Select
On Error Resume Next
If IsError(ra.Value) Then
MsgBox "Aba: " & ra.Parent.Name & Chr(13) & "Célula: " &
ra.Address
End If
Next
Next
End Sub
Sub CheckErrorSelection()
Dim ra As Range
For Each ra In Selection
ra.Select
If IsError(ra.Value) Then
MsgBox "Sheet: " & ra.Parent.Name & Chr(13) & "Cell: " &
ra.Address
End If
Next
End Sub
Sub CheckErrorAllSheets()
Dim ws As Worksheet
Dim ra As Range
Dim iCounter As Long
iCounter = 0
For Each ws In Worksheets
For Each ra In ws.UsedRange
If IsError(ra.Value) Then
iCounter = iCounter + 1
End If
Next
Next
MsgBox (iCounter & " Errors Founded")
End Sub
HIDE AND SHOW INFORMATION
Sub UnhideAll()
Dim Ws As Worksheet
For Each Ws In Application.Worksheets
Ws.Select
Cells.Select
Selection.EntireRow.Hidden = False
Selection.EntireColumn.Hidden = False
Next
End Sub
Note. The macro starts from worksheet number 2, as the number in bold
bellow. To start hide from another sheet, just change this number.
Sub HideAndShow()
For i = 2 To Worksheets.Count
If Worksheets(i).Visible = True Then
Worksheets(i).Visible = False
Else
Worksheets(i).Visible = True
End If
Next
End Sub
12 OTHERS
Sub AlternateColors()
Dim SelecArea As Range
Dim LineVar As Range
Set SelecArea = Selection
For Each LineVar In SelecArea.Rows
If LineVar.Row Mod 2 = 1 Then
LineVar.Interior.ColorIndex = 15
End If
Next LineVar
End Sub
Note 1. The code consolidates all data’s starting from A1 cell, what is
changeable.
Note 2. The first worksheet in the workbook will receive all data.
Sub Consolidate()
Dim total As Long
For i = 2 To Worksheets.Count
Worksheets(i).Select
Range("A1").Select
If ActiveCell.Offset(0, 1) <> "" Then
Range(Selection, Selection.End(xlToRight)).Select
End If
If ActiveCell.Offset(1, 0) <> "" Then
Range(Selection, Selection.End(xlDown)).Select
End If
Selection.Copy
Worksheets(1).Select
total =
Application.WorksheetFunction.CountA(Worksheets(1).Range("A1:A1048
576"))
Range("A" & total + 1).Select
ActiveSheet.Paste
Next
End Sub
Sub Runtime()
‘Start Timer
ti = Time
‘Inser the code here
‘End timer
tf = Time
‘Calculate the difference between start and end
tDif = tf - ti
MsgBox "Processing time: " & WorksheetFunction.text(tDif,
"HH:MM:SS")
End Sub
Sub Copy_Paste_Values()
iquestion = MsgBox("This macro will convert the content off all cells to
values, continue?", vbYesNo)
If iquestion = vbYes Then
For i = 1 To Worksheets.Count
Worksheets(i).Select
If Worksheets(i).Visible = False Then
Worksheets(i).Visible = True
End If
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
Range("A1").Select
Next
End If
End Sub
Sub Remove_Empty()
Dim Celula As Range
For Each Celula In Selection
If Not IsEmpty(Celula) Then
Celula = Trim(Celula)
End If
Next Celula
End Sub
Sub Refresh_PivotTables()
Dim pivotTable As PivotTable
For Each pivotTable In ActiveSheet.PivotTables
pivotTable.RefreshTable
Next
End Sub
Note. The macro remove’s duplicate in the same column in all worksheets,
from row 1 to 99999
Sub Remove_Duplicate()
coluna = InputBox("Choose the column to remove duplicates in each
worksheet ?")
For i = 1 To Worksheets.Count
Worksheets(i).Select
ActiveSheet.Range("$" & coluna & "$1:$" & coluna &
"$99999").RemoveDuplicates Columns:=1, Header:=xlNo
Next
End Sub
Sub ConsolidateNewFile()
Dim wkbDestino As String
Dim WorkbookName(1 To 99) As String
Dim ws As Worksheet
Dim i As Integer
i=1
For Each Workbook In Workbooks
i=1+1
WorkbookName(i) = Workbook.Name
Next Workbook
Total = i
Workbooks.Add
wkbDestiny = ActiveWorkbook.Name
For i = 1 To Total
Workbooks(i).Activate
For Each ws In Workbooks(i).Worksheets
ws.Copy
after:=Workbooks(wkbDestiny).Sheets(Workbooks(wkbDestiny).Sheets.Co
unt)
Next ws
Next i
Application.DisplayAlerts = False
For i = 1 To 3
Sheets(1).Delete
Next i
Application.DisplayAlerts = True
End Sub
Sub DeleteEmptySheet()
Dim Ws As Worksheet
On Error Resume Next
Application.DisplayAlerts = False
For Each Ws In Application.Worksheets
If Application.WorksheetFunction.CountA(Ws.UsedRange) = 0 Then
Ws.Delete
End If
Next
Application.DisplayAlerts = True
End Sub
36. SORT WORKSHEETS ALPHABETICALLY
This macro sorts worksheets in alphabetically ascending order. To change to
descending order, just change the signal (“>”), highlighted in bold, for the
(“<”).
Sub OrderSheets()
Dim i As Integer
Dim j As Integer
Dim Resposta As VbMsgBoxResult
Resposta = MsgBox("Do you want order ascending ?", vbYesNo +
vbQuestion + vbDefaultButton1, "Order Alphabetically")
For i = 1 To Sheets.Count
For j = 1 To Sheets.Count - 1
If Resposta = vbYes Then
If UCase$(Sheets(j).Name) > UCase$(Sheets(j + 1).Name) Then
Sheets(j).Move After:=Sheets(j + 1)
End If
End If
Next j
Next i
End Sub
Sub ChangeSheetName()
For Each Sheet In Worksheets
Shortcut1:
Sheet.Select
NewName = InputBox("What is the new name for this sheet?")
If NewName = "" Then
Exit Sub
End If
On Error GoTo Shortcut1:
ActiveSheet.Name = NewName
Next
End Sub
Sub PdfConvert()
Dim iNumArq As Integer
Dim iCounter As Integer
Dim sMyFiles() As String
Dim OriginFolder As String
Dim DestinyFolder As String
OriginFolder = "C:\OriginFolder"
DestinyFolder = "C:\DestinyFolder"
FileFound = FindFiles(OriginFolder, sMyFiles, iNumArq, "*", True)
If FileFound Then
For iCounter = 1 To iNumArq
Filename = sMyFiles(2, iCounter)
ExtCount = Len(Filename) - Application.WorksheetFunction.Search(".",
Filename, 1) + 1
Workbooks.Open (OriginFolder & "\" & Filename)
Workbooks(Filename).Activate
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
DestinyFolder & "\" & Mid(Filename, 1, Len(Filename) - ExtCount)
& ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True,
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Workbooks(Filename).Close
Next iCounter
End If
End Sub
Function FindFiles(ByVal sPath As String, ByRef sFoundFiles() As String,
_
ByRef iFndFiles As Integer, _
Optional ByVal sFileSpec As String = "*.*", _
Optional ByVal blIncludeSubFolders As Boolean = False) As Boolean
Dim iCounter As Integer
Dim sFileName As String
Dim oFileSystem As Object, oParentFolder As Object, oFolder As
Object
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set oParentFolder = oFileSystem.GetFolder(sPath)
If oParentFolder Is Nothing Then
FindFiles = False
On Error GoTo 0
Set oParentFolder = Nothing
Set oFileSystem = Nothing
Exit Function
End If
sPath = IIf(Right(sPath, 1) = "\", sPath, sPath & "\")
sFileName = Dir(sPath & sFileSpec, vbNormal)
Do While sFileName <> ""
iCounter = UBound(sFoundFiles, 2)
iCounter = iCounter + 1
ReDim Preserve sFoundFiles(1 To 2, 1 To iCounter)
sFoundFiles(1, iCounter) = sPath
sFoundFiles(2, iCounter) = sFileName
sFileName = Dir()
Loop
If blIncludeSubFolders Then
For Each oFolder In oParentFolder.SubFolders
FindFiles oFolder.Path, sFoundFiles, iFndFiles, sFileSpec,
blIncludeSubFolders
Next
End If
FindFiles = UBound(sFoundFiles, 2) > 0
iFndFiles = UBound(sFoundFiles, 2)
On Error GoTo 0
Set oFolder = Nothing
Set oParentFolder = Nothing
Set oFileSystem = Nothing
End Function
Sub ListFiles()
Dim iNumArq As Integer
Dim iCounter As Integer
Dim sMyFiles() As String
Dim OriginFolder As String
Dim DestinyFolder As String
OriginFolder = "C:\OriginFolder"
Foundfile = FindFiles(OriginFolder, sMyFiles, iNumArq, "*", True)
If Foundfile Then
For iCounter = 1 To iNumArq
Filename = sMyFiles(2, iCounter)
ActiveSheet.Range("A" & iCounter) = Filename
Next iCounter
End If
Columns(1).AutoFit
End Sub
Function FindFiles(ByVal sPath As String, ByRef sFoundFiles() As String,
_
ByRef iFndFiles As Integer, _
Optional ByVal sFileSpec As String = "*.*", _
Optional ByVal blIncludeSubFolders As Boolean = False) As Boolean
Dim iCounter As Integer
Dim sFileName As String
Dim oFileSystem As Object, oParentFolder As Object, oFolder As
Object
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set oParentFolder = oFileSystem.GetFolder(sPath)
If oParentFolder Is Nothing Then
FindFiles = False
On Error GoTo 0
Set oParentFolder = Nothing
Set oFileSystem = Nothing
Exit Function
End If
sPath = IIf(Right(sPath, 1) = "\", sPath, sPath & "\")
sFileName = Dir(sPath & sFileSpec, vbNormal)
Do While sFileName <> ""
iCounter = UBound(sFoundFiles, 2)
iCounter = iCounter + 1
ReDim Preserve sFoundFiles(1 To 2, 1 To iCounter)
sFoundFiles(1, iCounter) = sPath
sFoundFiles(2, iCounter) = sFileName
sFileName = Dir()
Loop
If blIncludeSubFolders Then
For Each oFolder In oParentFolder.SubFolders
FindFiles oFolder.Path, sFoundFiles, iFndFiles, sFileSpec,
blIncludeSubFolders
Next
End If
FindFiles = UBound(sFoundFiles, 2) > 0
iFndFiles = UBound(sFoundFiles, 2)
On Error GoTo 0
Set oFolder = Nothing
Set oParentFolder = Nothing
Set oFileSystem = Nothing
End Function
Note 2. The code can be improved with each user’s necessities, by verifying
the name of the file, or verifying part of the name with codes like MID(),
LEFT() and other’s codes that manipulates texts.
Sub Copyfiles()
Dim iNumArq As Integer
Dim iCounter As Integer
Dim sMyFiles() As String
Dim OriginFolder As String
Dim DestinyFolder As String
OriginFolder = "C:\OriginFolder"
DestinyFolder = "C:\DestinyFolder"
FileFound = FindFiles(OriginFolder, sMyFiles, iNumArq, "*", True)
If FileFound Then
For iCounter = 1 To iNumArq
FileCopy OriginFolder & "\" & sMyFiles(2, iCounter), DestinyFolder &
"\" & sMyFiles(2, iCounter)
Next iCounter
End If
End Sub
Function FindFiles(ByVal sPath As String, ByRef sFoundFiles() As String,
_
ByRef iFndFiles As Integer, _
Optional ByVal sFileSpec As String = "*.*", _
Optional ByVal blIncludeSubFolders As Boolean = False) As Boolean
Dim iCounter As Integer
Dim sFileName As String
Dim oFileSystem As Object, oParentFolder As Object, oFolder As
Object
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set oParentFolder = oFileSystem.GetFolder(sPath)
If oParentFolder Is Nothing Then
FindFiles = False
On Error GoTo 0
Set oParentFolder = Nothing
Set oFileSystem = Nothing
Exit Function
End If
sPath = IIf(Right(sPath, 1) = "\", sPath, sPath & "\")
sFileName = Dir(sPath & sFileSpec, vbNormal)
Do While sFileName <> ""
iCounter = UBound(sFoundFiles, 2)
iCounter = iCounter + 1
ReDim Preserve sFoundFiles(1 To 2, 1 To iCounter)
sFoundFiles(1, iCounter) = sPath
sFoundFiles(2, iCounter) = sFileName
sFileName = Dir()
Loop
If blIncludeSubFolders Then
For Each oFolder In oParentFolder.SubFolders
FindFiles oFolder.Path, sFoundFiles, iFndFiles, sFileSpec,
blIncludeSubFolders
Next
End If
FindFiles = UBound(sFoundFiles, 2) > 0
iFndFiles = UBound(sFoundFiles, 2)
On Error GoTo 0
Set oFolder = Nothing
Set oParentFolder = Nothing
Set oFileSystem = Nothing
End Function
INTERACTION WITH OUTLOOK
Note 1. Change the subject and e-mail content message highlighted in bold
Note 2. .CC and .BCC are optional; just use those lines for copies and blind
copies if you need, else just erase them.
Note 3. The .Send command sends the email automatically, if uses .Display
instead, it create the e-mail but do not sends automatically.
Sub Send_Mail()
Dim OutApp As Object
Dim OutMail As Object
Dim bMessage As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
bMessage = "Type the content line 1" & vbNewLine & _
"Type the content line 2" & vbNewLine & _
"Type the content line 3"
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = "This is the email text"
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
44. SEND E-MAIL WITH WORKBOOK AS
ATTACHMENT
This macro sends the last saved version of the active workbook in an
outlook e-mail message.
Sub SendWorkbookEmail()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = "This is the email text"
.Attachments.Add ActiveWorkbook.FullName
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
45. SEND E-MAIL WITH ACTIVE WORKSHEET
AS ATTACHMENT
This macro sends an e-mail using outlook with the active worksheet as
attachment.
Note 2. .CC and .BCC are optional; just use those lines for copies and blind
copies
Note 3. The .Send command sends the email automatically, if uses .Display
instead, it create the e-mail but do not sends automatically
Sub SendActiveSheetEmail ()
Dim Exten As String
Dim FormtN As Long
Dim OutApp As Object
Dim OutMail As Object
Dim OriginWKB As Workbook
Dim DestWKB As Workbook
Dim TempFilePath As String
Dim TempFileFolder As String
Application.ScreenUpdating = False
Application.EnableEvents = False
Set OriginWKB = ActiveWorkbook
ActiveSheet.Copy
Set DestWKB = ActiveWorkbook
With DestWKB
If Val(Application.Version) < 12 Then
Exten = ".xls": FormtN = -4143
Else
Select Case OriginWKB.FileFormat
Case 51: Exten = ".xlsx": FormtN = 51
Case 52:
If .HasVBProject Then
Exten = ".xlsm": FormtN = 52
Else
Exten = ".xlsx": FormtN = 51
End If
Case 56: Exten = ".xls": FormtN = 56
Case Else: Exten = ".xlsb": FormtN = 50
End Select
End If
End With
TempFilePath = Environ$("temp") & "\"
TempFileFolder = "Part of " & OriginWKB.Name & " " & Format(Now,
"dd-mmm-yy h-mm-ss")
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With DestWKB
.SaveAs TempFilePath & TempFileFolder & Exten,
FileFormat:=FormtN
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = "This is the email text"
.Attachments.Add DestWKB.FullName
.Send
End With
On Error GoTo 0
.Close savechanges:=False
End With
Kill TempFilePath & TempFileFolder & Exten
Set OutMail = Nothing
Set OutApp = Nothing
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Note 2. .CC and .BCC are optional; just use those lines for copies and blind
copies if you need, else just erase them
Note 3. The .Send command sends the email automatically, if uses .Display
instead, it create the e-mail but do not sends automatically
Sub Mail_Range()
Dim wb As Workbook
Dim iTempFolder As String
Dim iTempFile As String
Dim Source As Range
Dim Dest As Workbook
Dim iFormatNum As Long
Dim iExt As String
Dim OutApp As Object
Dim OutMail As Object
Set Source = Nothing
On Error Resume Next
Set Source = Selection.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Source Is Nothing Then
MsgBox "The source is out of range, please try again.", vbOKOnly
Exit Sub
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb = ActiveWorkbook
Set Dest = Workbooks.Add(xlWBATWorksheet)
Source.Copy
Dest.Sheets(1).Cells(1).PasteSpecial Paste:=8
Dest.Sheets(1).Cells(1).PasteSpecial Paste:=xlPasteValues
Dest.Sheets(1).Cells(1).PasteSpecial Paste:=xlPasteFormats
Dest.Sheets(1).Cells(1).Select
Application.CutCopyMode = False
iTempFolder = Environ$("temp") & "\"
iTempFile = "Selection of " & wb.Name & " " & Format(Now, "dd-
mmm-yy h-mm-ss")
If Val(Application.Version) < 12 Then
iExt = ".xls": iFormatNum = -4143
Else
iExt = ".xlsx": iFormatNum = 51
End If
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With Dest
.SaveAs iTempFolder & iTempFile & iExt, FileFormat:=iFormatNum
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = "This is the email text"
.Attachments.Add Dest.FullName
.Send
End With
On Error GoTo 0
.Close savechanges:=False
End With
Kill iTempFolder & iTempFile & iExt
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Sub SendWorkbookEmail()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = "[email protected]"
.CC = "[email protected]"
.BCC = "[email protected]"
.Subject = "This is the Subject"
.Body = "This is the email text"
.Attachments.Add ("C:\examplefile.txt")
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
INTERACTION WITH POWERPOINT
Note 1. It is possible to adjust the position and size of the chart changing
bold highlighted text
Note 2. Inside VBA editor, click in tools, reference and then scroll down to
Microsoft PowerPoint object library, check the box and then press OK
Sub Excel_chart_to_PPT ()
Dim PptApp As PowerPoint.Application
Dim iSlide As PowerPoint.Slide
Dim ChartObj As Excel.ChartObject
On Error Resume Next
Set PptApp = GetObject(, "PowerPoint.Application")
On Error GoTo 0
If PptApp Is Nothing Then
Set PptApp = New PowerPoint.Application
End If
If PptApp.Presentations.Count = 0 Then
PptApp.Presentations.Add
End If
PptApp.Visible = True
For Each ChartObj In ActiveSheet.ChartObjects
PptApp.ActivePresentation.Slides.Add
PptApp.ActivePresentation.Slides.Count + 1, ppLayoutText
PptApp.ActiveWindow.View.GotoSlide
PptApp.ActivePresentation.Slides.Count
Set iSlide =
PptApp.ActivePresentation.Slides(PptApp.ActivePresentation.Slides.Count
)
ChartObj.Select
ActiveChart.ChartArea.Copy
On Error Resume Next
iSlide.Shapes.PasteSpecial(DataType:=ppPasteMetafilePicture).Select
iSlide.Shapes(1).TextFrame.TextRange.Text =
ChartObj.Chart.ChartTitle.Text
PptApp.ActiveWindow.Selection.ShapeRange.Left = 25
PptApp.ActiveWindow.Selection.ShapeRange.Top = 150
iSlide.Shapes(2).Width = 300
iSlide.Shapes(2).Left = 600
Next
AppActivate ("Microsoft PowerPoint")
Set iSlide = Nothing
Set PptApp = Nothing
End Sub
Note 1. It is possible to adjust the position changing the highlight bold text
Note 2. Inside VBA editor, click in tools, reference and then scroll down to
Microsoft PowerPoint object library, check the box and then press OK
Sub Selection_to_PowerPoint()
Dim iRange As Range
Dim PptObj As Object
Dim iPresent As Object
Dim iSlide As Object
Dim iShape As Object
Set iRange = Selection
On Error Resume Next
Set PptObj = GetObject(class:="PowerPoint.Application")
Err.Clear
If PptObj Is Nothing Then Set PptObj =
CreateObject(class:="PowerPoint.Application")
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
Application.ScreenUpdating = False
Set iPresent = PptObj.Presentations.Add
Set iSlide = iPresent.Slides.Add(1, 11)
iRange.Copy
iSlide.Shapes.PasteSpecial DataType:=2
Set iShape = iSlide.Shapes(iSlide.Shapes.Count)
iShape.Left = 100
iShape.Top = 160
PptObj.Visible = True
PptObj.Activate
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
INTERACTION WITH WORD
Note. Inside VBA editor, click in tools, reference and then scroll down to
Microsoft Word object library, check the box and then press OK
Sub CopyRangetoWord()
Dim WodAPP As Word.Application
Dim WordDOC As Word.Document
If Not TypeName(Selection) = "Range" Then
MsgBox "Out of range, please try again.", vbExclamation, "Range Error"
Else
Set WodAPP = GetObject(, "Word.Application")
Set WordDOC = WodAPP.ActiveDocument
Selection.Copy
WodAPP.Selection.PasteSpecial Link:=False, DataType:=wdPasteRTF, _
Placement:=wdInLine, DisplayAsIcon:=False
Set WordDOC = Nothing
Set WodAPP = Nothing
End If
End Sub
51. EXPORT ACTIVE SHEET TO MICROSOFT
WORD
This routine export the information of used range to a new file in Microsoft
Word and save the file with the same name and the same directory.
Note. Inside VBA editor, click in tools, reference and then scroll down to
Microsoft Word object library, check the box and then press OK
Sub Worksheet_to_Word()
Dim Question As Integer
Question = MsgBox("This macro export all used range, do you want to
continue ?", vbYesNo)
If question <> 6 Then
Exit Sub
End If
Set Object = CreateObject("Word.Application")
Object.Visible = True
Set newObject = Object.Documents.Add
ActiveSheet.UsedRange.Copy
newObject.Range.Paste
Application.CutCopyMode = False
Object.Activate
On Error Resume Next
newObject.SaveAs Filename:=Application.ActiveWorkbook.Path & "\"
& ActiveSheet.Name
End Sub