Você está na página 1de 12

Vba Exercises

The problem:
A programmer wants to learn how to program in Microsoft Visual Basic for
Applications.
The context:
The programmer has seen Visual Basic and VBA code, but is not very familiar with
the syntax, and is not very familiar with the objects that are commonly used in VBA
code. The programmer has seen some TestFirst code, but has not learned how to
test her own code first. The programmer is not familiar with VBA's environment for
trying out individual lines of code, and does not have much practice stepping
through VBA code in the debugger. The programmer does have experience
identifying a problem, identifying what a solution to the problem should be capable
of, and verifying that the solution matches the problem requirements -- just in other
contexts. The programmer has reference material for VBA (including VBA's help, the
help within each Microsoft Office application, Google, and a very thick reference
tome). The programmer has access to the Refactoring book, which unfortunately
only has Java examples. The programmer has access to an experienced VB and VBA
programmer, whom she can ask questions of. The programmer has access
to MicrosoftOffice, includingMicrosoftWord, MicrosoftExcel, and MicrosoftAccess.
What this page tries to do:
This page will present a series of programming exercises. Each exercise will allow the
programmer to become familiar with one feature of VBA. By the time the
programmer is done with the exercise, the programmer will be able to explain the
concept, when it is useful, when it is not useful, and what some common problems
are with it. The programmer will have used the concept to solve a problem of her
own devising. The exercises will build on each other, and let the programmer
continually refresh and cement her knowledge of the earlier concepts. In other
words, it will use the SaxonMath? approach, not the CramStudying? approach. This
page will not present the answers to the problems -- those are left as exercises for
the programmer. (Per the context, the programmer can get the information she
needs to solve the problems.)
Recommended Coding Conventions:
In each of the exercises, it is a very good idea to follow these guidelines:
Always use Option Explicit
Always explicitly state whether a Sub, Function, or Type is Public or Private.

Always
explicitly
state
whether
an
argument
to
a Sub or Function is ByRef or ByVal.
Use the line continuation character to explicitly wrap long lines. This lets you
see all of your code in the IDE, and see it the same way when you print out.
Whenever possible, declare variables with a datatype; avoid implicitly
declaring them as Variant. If a variable needs to be a Variant, know why it
needs to be a Variant.
Exercise 1: The Excel VBE
In Excel, launch the VisualBasicEditor? (VBE).
Configure the VBE so that any new modules you create start with Option
Explicit.
In the VBE, show these features:
o The Project Pane
o The Immediate Window
o The Locals Window
o The Code Window
Write a line of code in the Immediate Window that computes something. For
example, if you have 3 spoons and 4 forks, how many pieces of flatware do
you have in all? Make VBE show you the result in the Immediate Window.
Optionally, exit VBE.
Optionally, exit Excel.
Questions about Exercise 1:
o What is the purpose of the Project Pane?
o What is the purpose of the Immediate Window?
o What is the purpose of the Locals Window?
o What is the purpose of the Code Window?
o What are the two ways you can tell the Immediate Window to show
you an answer in the Immediate Window?
Exercise 2: The Access VBE
Perform Exercise 1 in Access.
Questions about Exercise 2:
o How are the contents of the Project Pane different in Access than in
Excel?
Exercise 3: "OK" Message Boxes

In a VBE, write a line of code in the Immediate Window that computes


something. For example, if you have 3 spoons and 4 forks, how many pieces of
flatware do you have in all?
Make VBE show you the result in a message box.
Change the title of the message box. (It is often a good idea to have the title
briefly indicate the name and version number of the program you are writing.)
Add one of the standard icons to the message box, such as a question mark,
an information icon, a serious warning icon, or no icon.
Questions about Exercise 3:
o What argument(s) to the MsgBox command do you have to use?
o What argument(s) are optional?
o Are there any argument(s) that you did not use in this exercise?
o What does each argument do?
o In the programs you expect to write, which arguments to you expect to
use often? Why?
o In the programs you expect to write, which arguments to you rarely
expect to use? Why?
o What are the "magic numbers" for each kind of standard icon?
o Does VBA have any global constants that correspond to these "magic
numbers"?
If so, what are they?
If so, which is easier for you to look up or remember?
If so, which is easier for you to understand when you are reading
code?
Exercise 4: Trivial Functions
In Excel's VBE, write a function that takes one input (of type Variant), and
returns the exact same value.
Make the function a Public Function.
Make sure to indent the code inside of the function.
Call the function from cell(s) in Excel.
Try out the function with several kinds of data (such as strings or numbers).
Save your work.
Questions about Exercise 4:
o What is the difference between a Function and a Sub?
o Why can't you use a Sub to solve this problem?
o What is the difference between a Public and a Private routine?
o Why can't you use a Private routine to solve this problem?

o
o
o

If you do not specify Public or Private, what does VBA default to?
Why should we always explicitly specify Public or Private?
How do you tell VBA what value should be returned by a function?

Exercise 5: Calling Functions from Excel


In Excel, call the function you wrote in Exercise 4 using a hard-coded
parameter value.
In Excel, call the function you wrote in Exercise 4 using the contents of
another cell as the parameter value.
In Excel, call the function you wrote in Exercise 4 using the results of a
function.
Questions about Exercise 5:
o Are there any differences between the Public Function you wrote in
Exercise 4, and a built-in Excel function?
Exercise 6: If / Then / Else
Come up with a choice that needs one of two results, based on a condition.
In Excel, write a VBA function that performs this choice.
o Use the If Then Else feature.
o Make sure to indent your code so that it is easy to understand.
Try out the function in cell(s) of the spreadsheet.
Save your work.
Exercise 7: More Complicated If / Then / Else
Come up with a choice that is based on several conditions.
In Excel, write a VBA function that performs this choice. Use the If Then
Else feature.
Try out the function in cell(s) of the spreadsheet.
Save your work.
Exercise 8: If / Then / ElseIf / Else
In Excel, write a VBA function that performs the choice in Exercise 7.
o Use the If Then ElseIf Else feature.
o Make sure to indent your code so that it is easy to understand.
Try out the function in cell(s) of the spreadsheet.
Save your work.

Questions about Exercise 8:


o Is this code easier to understand than the code in Exercise 7?
Exercise 9: Select Case
In Excel, write a VBA function that performs the choice in Exercise 7.
o Use the Select Case feature.
o Note that Visual Basic's Select Case feature is very powerful. It can
handle numbers, strings, and ranges of values. It can also handle
expressions. Other common languages' Case statements have many
fewer options.
o If appropriate, include a Case Else statement.
o It is often a good idea to put comments in some of the Case statements,
especially the Case Else statement.
o Make sure to indent your code so that it is easy to understand. Two
examples are on the SelectCaseExamples page.
Try out the function in cell(s) of the spreadsheet.
Save your work.
Questions about Exercise 9:
o Is this code easier to understand than the code in Exercises 7 and 8?
Exercise 10: Guard Clauses
In Excel, write a VBA function that performs the choice in Exercise 7.
o Use GuardClauses, as explained in MartinFowler's Refactoring book.
Try out the function in cell(s) of the spreadsheet.
Save your work.
Questions about Exercise 10:
o How does the Exit Function statement work in VBA?
o How does the Exit Sub statement work in VBA?
o Is this code easier to understand than the code in Exercises 7, 8, and 9?
o In what situations does it make sense to use each approach?
o In what situations does it make sense to use a combination of
approaches?
Exercise 11: Make a Button in Excel
Show the "Toolbox".
Make a button in Excel.
Write a subroutine that is called by the button.

For example, show a message box.


Save your work.
o

Exercise 12: String Concatenation


Modify the message box text in Exercise 11, so that the message text is the
result of combining two or more strings.
Save your work.
Exercise 13: Let VBA See an Cell Value from Excel
Modify the message box text in Exercise 12, so that the message text includes
the value of a cell in the spreadsheet.
Save your work.
Exercise 14: Have Excel do something when a cell value is changed
See http://www.cpearson.com/excel/Events.aspx
In an Excel workbook, choose a cell.
Show a message box when this cell is changed.
Save your work.
Exercise 15: Factoring out shared code
Note: This is the ExtractMethod refactoring.
Choose a cell in another worksheet of the same workbook (as Exercise 14).
Show the same message box (as in Exercise 14) when the second cell is
changed.
Move the message box code to a new subroutine or function.
Inside each Worksheet_Change() event, call the new subroutine or function,
instead of having the details in both Worksheet_Change() events.
Save your work.
Exercise 16: Static Variables
Exercise 17: Using Guard Clauses to Avoid Infinite Recursion
Note: This is a variation on the SingletonPattern.
In an Excel workbook, choose two cells that you want to always have the same
value.

Make it so that updating the first cell automatically updates the second cell.
(This is trivial -- just have a formula in the second cell that gets the value from
the first cell.)
Make it so that updating the second cell automatically updates the first cell.
(This is trivial, if you are willing to give up the ability to manually change the
first cell -- just have a formula in the first cell that gets the value from the
second cell.)
Create Worksheet_Change() event(s) for each cell.
o Have each Worksheet_Change() event call a subroutine -- but do not
make the subroutine set the value of the other cell yet. (If you do, you
risk an infinite loop).
o Use a static variable inside the subroutine to make sure that the guts of
the subroutine do not get called (indirectly) by the subroutine. You will
need to use a GuardClause, as discussed in Exercise 10.
o Now it is safe for the guts of the subroutine to set the values of both
cells.
Save your work.
Exercise 18: Text Box Events
In an Access database, create a form.
On the form, create two text boxes.
When the text in the first text box changes, update the second text box.
Save your work.
Questions about Exercise 18:
o What are the differences between using macros and code to perform
this update?
o What events can you use to trigger this update?
o When do these events occur?
o What order do these events occur in?
o Does triggering one of these events require triggering another event?
For example, single-click versus double-click.
For example, leaving one control and entering another control.
o Can you think of scenarios where you might want to use some of these
events?
o Are there any events where it is hard to think of scenarios that should
use them?
o Do any of your scenarios result in infinite loops?

Exercise 19: Syncing Two Controls


Add to and/or modify your code or macros in Exercise 18, so that when either
text box changes, the other changes to match it. Use the techniques from
Exercise 17 to avoid infinite loops.
Save your work.
Questions about Exercise 19:
o Does Access let you refer to the Text property of a textbox?
What does it mean for a control to "have the focus"?
Does Access let you refer to the Text property of a textbox that
has the focus?
Does Access let you refer to the Text property of a textbox that
does not have the focus?
o What is the "Value" property of a textbox?
o Does Access let you refer to the Value property of a textbox that does
not have the focus?
o Can you refer to the "Value" property of a textbox without explicitly
coding ".Value"?
Exercise 20: TBD
Exercise 101: Ask Simple Questions in Message Boxes
Come up with a problem that requires the user to make a "Yes / No" or "OK /
Cancel" choice.
Write a VBA function that asks this question of the user, and returns a value
based on the user's answer.
Try out your function.
Unfortunately, Microsoft gives you very few choices about what text is on
each button. If needed, edit your message so that it is very easy for the user to
understand which button they should press.
See what happens if the user closes the message box, instead of pressing one
of the buttons.
See what happens if the user tries to do something else in the program while
the message box is open.
See what happens if the user tries to use another program while the message
box is open.
Save your work.
Questions about Exercise 101:
o What argument(s) to the MsgBox command do you have to use?

o
o

What are the "magic numbers" for each kind of choice?


Does VBA have any global constants that correspond to these "magic
numbers"?
If so, what are they?
If so, which is easier for you to look up or remember?
If so, which is easier for you to understand when you are reading
code?

Exercise 102: Combining Features of Message Boxes


Modify your function from Exercise 101, so that it has a custom title.
Modify your function from Exercise 101, so that it has a standard icon, such as
a question mark, an information icon, a serious warning icon, or no icon.
Try out your function.
Save your work.
Questions about Exercise 102:
o How do you tell VBA to use both a custom icon and have more than just
an "OK" button?
o Does this mean that you need new "magic numbers"?
o If you wanted new "magic numbers", how would you declare them?
Exercise 103: Default Buttons in Message Boxes
If the user makes a mistake, think about which button is the safer choice.
Modify your function from Exercise 102, to make the safer choice the default
button.
Try out your function.
Questions about Exercise 103:
o What does it mean for a button to be the "default" button on a dialog
box?
o How do you tell the MsgBox command which button should be the
default choice?
o If you do not tell the MsgBox command which button should be the
default choice, which button is the default choice?
o What are the "magic numbers" for choosing the default button?
Exercise 104: Ask Complicated Questions in Message Boxes
Perform Exercises 101 - 103, but use an "Abort / Retry / Cancel" dialog box.
Questions about Exercise 104:

o
o
o
o
o

When would you want to use an "Abort / Retry / Cancel" dialog box?
Is it easy for the user to understand these choices? Why or why not?
What ways are there around this problem?
What should the program do if the user closes the dialog box from the
dialog box' toolbar?
What does the program do if the user closes the dialog box from the
dialog box' toolbar?

Requests for new topics


Indenting code
o Sub...End Sub, Function...End Function, If...Then...Else, For...Next,
While...Wend, Do...While, Do...Until
o Select...Case...End Select has four common indentation styles
Same line Case and action is good for short actions
Case statements can have either a half-indent or a full indent
o IDE options for how many spaces 1 tab equals (the default is 1 tab = 4
spaces)
o The VBA IDE lets you add or remove tabs easily, by selecting one or
more lines, and pressing Tab or Shift-Tab. This does not delete the
highlighted text.
Hiding rows in Excel, based on whether the row's cell in a particular column
has the value of "hide"
Deciding which row is the last row (that is actually used) in an Excel worksheet
Deciding which rows are in the Print Area of an Excel worksheet
Showing all the rows in an Excel worksheet
Hiding the rows in an Excel worksheet that have "hide" in a particular column
Ways to handle error conditions
o Break into the debugger
o On Error GoTo 0
o On Error GoTo (label)
o Putting the line of code that is likely to have an error in a subroutine of
its own
o Using if statements (and similar code) to avoid having the error
How to use the same code in multiple worksheets in the same Excel workbook
o Copy the code into each worksheet's code page
o Create a shared code module

Using the Worksheets() collection to get the worksheet object that has
a particular name
o Ways to tell a subroutine to update a particular worksheet
Passing the worksheet object
Passing the name of the worksheet
Passing the number of the worksheet in the collection (not
recommended)
Optimizations
o Reducing the flashing of the code that hides rows
String manipulation -- Left(), Right(), Mid(), Len(), InStr?(), Trim()
How to avoid errors when using these functions
Newer string functions
o Reversing strings
o Searching backwards in a string
o The Like operator
Common data types
o When to use Int or Long
o When to use Float or Double
o When to use String
o When you have to use Variant
Inputs from Excel that might be either a number or a string
Inputs from Access that might be Null
Passing objects (such as worksheets or cell ranges)
Passing pointers to/from Windows API calls
Switch statements in Access' SQL view
Iff statements in Excel's formula bar
Ways to find things in the help system
o F1 is sometimes context-sensitive
o The Language Reference
What is a collection or an object?
The differences between methods, properties, events, and
functions
What is an enumeration?
o Finding things in the help
o Google
Good habits when you work with someone else's code
o Giving credit for code found on the Internet
Good naming habits
o Name objects based on what they are
o

Name functions and subroutines based on what they do. If you were to
yell at the computer to do something, what would you yell?
o We are in the VowelGeneration -- it is good to be able to pronounce
your variable names, functions, and subroutines.
Optionally:
o Either consistently use VB's simplified HungarianNotation
o Or consistently do not use HungarianNotation
o

Discussion:
Re: "Whenever possible, declare variables with a datatype" + Re: "Always explicitly
state [...] Public and Private"
This is the "heavy typing" view of things rather than the scriptish "keep code short
and clean" philosophy. Perhaps the verbose approach is good during the learning
phase, but dynamic coding is a useful and powerful skill and this should be pointed
out. (This doesn't apply to "option explicit", which MS screwed up badly on.) --top
The "verbose approach" is also good when the requirements prioritize
static TypeSafety over terseness.
Well, okay. I just think the beginner should know about both styles and that they
both have their place. Even if you personally "hate" one or the other, a beginner has
to at least be ready for the different expectations and requests of the marketplace.
True, but I'd encourage beginners to especially avoid implicit Variant variables in
order to discourage questionable practices, such as using the same variable for
multiple, differently-typed purposes in the same code block. Arguably, "scriptish"
approaches using dynamic implicit typing should be considered an advanced
programming technique -- a sharp cutting tool for the expert, rather than a shortcut
for the beginner. New VBA programmers are all too likely to cause run-time type
errors due to careless or nave "beginners" coding. Manifest static typing may help
reduce the likelihood of this, whilst encouraging discipline and focusing the
developer's mind on the type and purpose of a given variable.
Students should be exposed to dynamic typing at some point. Perhaps VBx is not the
best language for such because of its messy rules and limiting declaration options.
See also:
VbClassic, VisualBasicForApplications, VbClassicSurvivalGuide,
MicrosoftOffice, MicrosoftAccess, MicrosoftExcel, TeachMeToSmoke
MsgBox, GuardClause, SingletonPattern, SelectCaseExamples

Você também pode gostar