Professional Documents
Culture Documents
VBA Excel BOOK
VBA Excel BOOK
Sub min_max()
'
' min_max Macro
'
N = Range("D1")
Max = Cells(2, 1)
Min = Cells(2, 1)
For i = 3 To N + 1
If Cells(i, 1) < Min Then Min = Cells(i, 1)
If Cells(i, 1) > Max Then Max = Cells(i, 1)
Next
Range("D3") = Min
Range("D4") = Max
End Sub
Chapter
1
2
3
4
5
6
7
7.1.
Introduction
Table of Contents
What is programming?
Problems 1
From Excel Macros to VBA code
Problems 2
Program Flow and the Structured Programming (using IF
and Select Case)
Problems 3
Programming the Cyclic structures (Loops)
Problems 4
Sorting and Searching
Problems 5
Elements of Drawing in VBA
Problems 6
Selected Cases (with solutions and/or ideas how to solve
them)
Several algorithms from the number theory (Prime numbers,
means, Factorial, Fibonacci)
Using String Functions
Transferring Data
Travel Agency Problem
The Pizza Place
Improved Pizza Place
The Basketball Arena Problem
Simple Payroll Model
7.2.
7.3.
7.4.
7.5.
7.6.
7.7.
7.8.
Index
Appendices Hints for EXCEL 2003 Users
Hints for EXCEL 2013 Users
Page
0
1
2
7
8
26
27
54
55
68
69
79
81
89
90
87
96
99
103
105
108
111
117
125
127
128
What is programming? 1
Given the general nature of that question, and the fact that programming is seen as a
hideously complex subject, you are probably expecting a highly convoluted and
technical answer. In truth, it's quite easy to say what programming is, so it is:
Programming is breaking a task down into small steps.
The major idea is to present how some task should be done, and then you can do it!
Lets consider one simple example.
Example 1.1: Create an algorithm to find the minimum (min) and the maximum
(max) number in the given list (array, vector) of numbers using only one cycle (just
using comparisons while going through the list only once)?
We will assume that the list is not sorted or ordered in ascending (descending) order!
But, if they are sorted, then the first one should be min (max) and the last one max (min)
and we are done! In all other cases we need to work! Lets put that the first number is
the min and also the max of all numbers in the list. Probably it will be wrong2, but we will
do it anyway! So, if the list of numbers is X(1), X(2), X(n), lets put max=X(1) and
min=X(1). The next is to compare them with X(2). What could happen? If X(2) is greater
than max, then we should say that the max=X(2), or if X(2) is less than min, then,
min=X(2). In other cases, do nothing! After that, we need to repeat the same questions
with all remaining numbers from the list (X(i), i=3n): X(3), X(4),X(n). That way we
created an algorithm. It can be presented using graphical symbols, using pseudo code
or, since it is relatively simple, directly using a programming language!
Let us explain it in more details by solving for one simple situation with only 5 numbers.
Input numbers are 4, 6, 2, 9, and 7, or in the mathematical notation X1 = X(1)=4, X(2)=6,
X(3)=2, X(4)=9 and X(5)=7.
Our algorithm said: put X(1) to be the min and the max:
min=X(1), so min=4
max=X(1), so max=4
now, lets compare with X(2), where X(2)=6
If X(2) > max, then max=X(2) in our example: 6 is >4, so max=6
If X(2)< min, then min=X(2) in our example: 6 is not < 4, so min remain to be 4
Now, lets compare with X(3), where X(3)=2
If X(3) > max, then max=X(3) in our example 2 is not >6, so max remain 6
If X(3) < min, then min=X(3) in our example 2 is < 4, so new min is = 2
Etc.
Several quotes in this chapter are from: Matt Gemmell, Scotland Software
http://web.archive.org/web/20060110133319/http://www.scotlandsoftware.com/
2
Is there a case when it is true?
2
What we noticed is that there is a cycle or a loop in which the index goes from 2 to n (in
this example, n=5 since there are 5 members of the list). After noticing that, we can
present this algorithm graphically (Figure 1.1) or using a pseudo-code (Figure 1.2):
n, X(1),
X(2),,X(n)
Max = X(1)
Min = X(1)
c= 2 to n
Yes
Input: n, X(c), c =1 to n
Max = X(1)
Min = X(1)
Repeat for c=2 to n
If X(c) >max replace max with X(c)
If X(c) <min replace min with X(c)
If c < n, then replace c with c+1 and run the test
again
Else
Output: Max, Min
X(c)>Max
Max=X(c)
Yes
X(c)<Min
Min=X(c)
Max, Min
In the Figure 1.1 we used common symbols for flowcharting. Recently, instead of
drawing, majority of programmers will rather use the pseudo-code, presented in Figure
1.2.
We can recognize the three basic parts of any program: Input (data), Procedure
(transformation), and Output (information). Practically, we transform data to generate
information.
What makes programmers life more interesting is that when designing a program
programmer should start from the Output: what information we need to generate and
present at the end? Obviously, we are not expecting to find or guess the values of the
information, just we need to select which information we need. In the previous example,
3
we try to find min and max from the list of numbers, so these two values are in the
output. Obviously, in this case, we will not transform any number from the list; we will
just compare values and present the results.
The process of presenting the algorithm in a programming language is called coding.
For doing that, we need to know syntax and semantics of a selected programming
language3. Computer will follow exactly what programmer (you) typed: because
Computers are very, very stupid4.What it means is that programmers are in the total
control, which can be good or bad! There is very, very, small chance that computer will
make a mistake (probability is 10-12)!
After writing a program, depending which programming language was used the next
step will be to compile the program (into the language which will be understandable for
the machine = computer). Sometimes, program will not compile, and the compiler will
point out errors. Typically, those errors (mostly typos or simple omissions) you can fix in
a short time period. Very often, this is called fixing the syntax errors or the first level of
debugging = finding bugs (problems) in the program. Then, you need to run compiler
again and maybe again, until the compiler will not find errors. After that, program is
ready for testing with the input values. Programmer should prepare a set of input data
and move to the next step: to run the program. What could happen in that step? The
best scenario is that program is working fine, a bit less fortunate output is that program
sort of works, but the worst scenario is that program is not generating good outputs at
all! Then the next step is to do logical debugging of the program (fixing errors if some
of them occurred).
The debugging process could be very complicated and frustrating! To help yourself,
you can try to go step-by-step in execution of the program. One simple trick will be to
insert several temporary outputs in the critical points to see the numerical values of
selected variable(s) reached so far in the process5. When you choose the values to test
the program in the debugging process, choose the simplest numbers (values) possible.
Reason being is that you can follow the computations using pocket calculator or just
pencil and paper! Do not forget to eliminate those temporary outputs when the program
will be debugged and will start running correctly. When the program finally produced
correct result for some input, the more detailed testing will be necessary!
There is hundreds of programming languages, many of them are still popular (Java, C++, VBA), but
some others are not used anymore (COBOL, FORTRAN, PL/1)! In this text we will discuss the syntax and
semantics of the Visual Basic for Applications (VBA), which is typically suggested to be the first
programming language to learn. The term BASIC stands for Beginner's All-purpose Symbolic Instruction
Code. The all-purpose means that it can be used for any type of applications. From the BASIC family of
languages, we selected VBA since it is available with Excel (you do not need to purchase any additional
software) and majority you are already, not just very familiar, but also very fond of Excel!
4
Ibid 1
5
Later in the text we will present some debugging options in VBA which you may find useful
4
One of the biggest challenges in programming is when a program is giving good results
but only for selected set of input values: program will halt or never stop for some
input data. The program should work correctly for all possible inputs6, even if somebody
enters wrong data (purposely or by mistake). Using our example, you assume that user
will not input negative value for n (just a reminder, the n was the number of members in
the list)! In reality, there is in fact a minimal chance of happening something like that,
but you should consider this option when finalizing your program. Imagine the situation
that the first person who will test the program will try to see what will happen if the
number of members in the list is negative, or if he/she will enter a letter instead of a
number for n?! So, in our algorithm, we need to add (some) instruction(s) to solve that
problem.
It is good practice to give your colleague to test your program and vice-versa! Usually,
you are not able to see your omissions or mistakes!
Our next step, after refining and finalizing the program is to create a short write-up or
documentation for the program (explaining the problem, solution or approach, inputs,
outputs, and add some comments). The simplest way to keep the complete
documentation (and to have a backup) will be to create a folder in the safe place (USBflash drive or CD/DVD) with several files: the source code, executable file (if using the
compiler) and the documentation (text file). That way, when you will need this or a
similar program again, you can reuse the code or part of the code.
Program Execution
Computer executes program in a sequence as instructions are placed unless there is
change in a flow based on using some of the Control Structures, most often IF
statement or Loop statement. Every compiled instruction is parsed in even smaller steps
to the level, which can be understood by the computer: translated into the Machine
Language7.
Modern computers are extremely fast, executing millions of operations per second. Still,
programmers are always trying to make their programs to be efficient as possible. To
measure the speed of execution, we need to count the number of comparisons,
multiplication and divisions in the program (number of additions and subtractions is
irrelevant since it is so fast that it is not measurable at all). Many programmers like to
Sometimes, programmers will point out several levels for good programs: it works for small sample of
given input data, it works for some additional input data, or it works for all input data. Think about this
statement and solve the algebraic linear equation (or check the solution in Example E )
7
For example, to add two numbers using machine language, like x=a+b, computer needs several steps:
move the first number(a) from the memory in the accumulator, then add to it the second number (b)
and then send the result to the address where is x, replacing the current value of x with the new value.
5
compete on creating the algorithms to make program with higher speeds! Readers more
interested can find comparisons of algorithms (mostly for sorting) in many books (the
best known is book by Knuth: The Art of Computer Programming in three volumes) and
on the Internet. For example, when comparing the efficiency of algorithms for sorting
(ordering) records, mathematicians compare the number of operations and the size of
extra memory needed during the sort procedure (like the worst-case scenario vs. the
best-case scenario). Some of the sorting algorithms we will discuss in chapter 5.
If the list is very long, there are significant differences, while for the most common
business applications programmers use algorithms given with the database or other
software packages (without trying to optimize and/or change).
There are many classical examples in comparing algorithms; it was very important in
the earlier stages of computer science history, when computers were much slower and
when the memory has longer access time and I/O times, with limited capacities and
when the fast memory was very expensive.
Programming Terminology
Some people make a distinction between scripting and coding, while the final product
in both cases is called a source code (which is in fact a text file). Usually, scripting is
writing a program to be interpreted (translated into machine language every time
before execution)8, while the coding assumes writing a program to be compiled and
saved like that and then directly executed. After compiling, computer generates
additional file, called executable file. To run a program, you need the executable file,
and this is what programmer leaves as his work to the users.
Compiled program (or the exe version) is not readable / understandable for humans.
Because of that programmer must be very careful to keep the source code (there is no
way back or reverse process: from exe to source code)! If there is a need for any
updates, all changes must be done in the saved source code and then compiled again.
After that, a programmer can replace the old executable file with the new one.
Obviously, when we use interpreter, all changes in the source code will be immediately
available for the interpretation, and you even do not need to save the changes before
the execution.
When using the full VB language (not VBA), programmer can easily create the executable (or exe) version of the
code. When using VBA, it is rather complicated, but it is possible to create COM or DLL version, in which case the
DLL will be a better choice. Microsoft offers help at the site:
http://msdn.microsoft.com/en-us/library/aa166223(v=office.10).aspx
Problems
1. What will be different in the solution for the Exercise 1 if you need to find only min
of the set of numbers?
2. Based on the discussion in the text, update the algorithm to be able to handle
unusual inputs for n, like negative number or a letter.
3. Create an algorithm (and present it as a flowchart or a pseudo code) to solve a
linear algebraic equation A*X+B=0 (where A and B are input values). Hint: After
checking some conditions X=-B/A is a solution, but
4. Can you expand your solution of the Problem 3 to be able to solve a set of
several, say 10 equations of that type?
5. Using the solution for the Exercise 1, try to create a solution which will not only
find the min and max, but also remember and present in the output which
indexes those two numbers have? Lets name those indexes (or counter
values) as Cmax and Cmin!
6. Make two algorithms to calculate the average (or arithmetical mean) of a given
set of numbers!
7. Create an algorithm to calculate a discount: if an article is <= $100, discount is
10%, but if the article is over $100 discount is 15%.
8. Create an algorithm to calculate a bonus pay: if a sales person made revenue of
less than $1000, no bonus, else, for every $1000 more, his/her bonus is 1% of
the revenue (e.g. for over 1000 is 1%, for over 2000 will be 2%, for over 3000 will
be 3% etc).
9. Assume that you need to calculate the total value of the merchandise in a
warehouse. The input data are: quantities and the purchase prices for all items
on hand.
10. Assume that management grouped all items in separate product groups. Make a
price list knowing that the sales price is calculated using the mark-ups based on
product groups. Think about two alternatives: a) the markups by groups are input
data, or b) they are assigned by the groups, similar like in the problem 8.
Example 2.1.
Let us assume that we need just to clean existing data in the range D5:D14 to get ready
for a new input. In this example, after creating a button in a sheet, before clicking the
Recording button in the wizard window we renamed the macro to Reset_all. After clicking
the Record button, as mentioned earlier, Excel offers the possibility to assign the shortcut combination for execution of this macro. Since we will not use it, click the OK button
and start recording. For this macro, the only action is to highlight the range for input data
and to press the Delete key on the keyboard to delete the existing data. During the macro
recording, the action to delete was executed (compare figures 2.1. and 2.3.). To see the
code, developer can right-click the created button (on the Figure 2.3 named Button 3),
select Assign macro from the pop-up menu and click Edit button and choose which code
you want to see (Figure 2.4). The code is displayed in the Figure 2.5.
One
of
the
major
Properties
window
lists the
properties
and values
related to
each
object
(this one is
for the
workbook)
Please note: This textbook is printed in black_and_white technique. When using VBA, system uses
color coordination: any text following the (apostrophe symbol) is treated as a comment (will not
be executed and it will be in green color and in this text is a bit lighter), reserved words are in blue
(like End Sub), while the syntax error will be in red (like writing: Lop instead of: Loop and Loop is in
blue).
10
Chart
Workbook
Cell
Property
Address
Comment
Formula
Value
ChartTitle
ChartType
HasLegend
HasPassword
Name
Path
Format
Formula attached in it
Object
name
Property
name
Value assigned to
the property name
Notice the
space!
Variables
When naming variables, we have to try to use meaningful, mnemonic names that are
easy to understand and to make it easy to follow the code. Variable name MUST start
with a letter; the shortest variable name may have only one letter. It is not recommended
to extensively use abbreviations since it is possible that either you will forget later their
real meanings or that somebody will inherit your program to update it and will not be
able to figure out what is going on!
There are many reserved words in VBA which programmer cannot use for the variable
names. To be sure to avoid this problem it is recommended to use names like my_record,
my_date, or even to use words from some other language (not English) for the variable
names. As you noticed from the code of the Excel macros (Figure 2.4.), for all variable
names use single words (without spaces), for example, for the variable yearly sales put
an underscore: yearly_sales or type together: YearlySales. VBA interpreter is NOT CASE
sensitive: It means that for the VBA interpreter the variable YearlySales is the same as
yearlysales (but not the same as yearly_sales, which is also legal VBA variable name);
also x1 is accepted as the same variable as X1, while 1X is an illegal variable name: VBA
will not let you to continue your program after entering such a variable name and you will
get the message: Compile error (compiler expected that some operator was missing
between 1 and X).
It is helpful to put some short explanations in the program, particularly when using short
names (abbreviations). Using comments in VBA is very simple: only rule applied is that
every comment MUST start with (apostrophe). A comment line could be anywhere in the
program (even the symbol could be anywhere in the right side of the line in which there
is a VBA instruction). A comment line (or comment text) will not be interpreted and it will
be in the color green on the screen (and visible when editing or reviewing the code in the
VBA Editor), see examples 2.2 and 2.3.
DIM Statement
The DIM statement allows programmers to Declare variable types (like currency, string,
integer, double) and to Reserve a contiguous memory range to be allocated to an array,
which might be one-dimensional (vector or list), two-dimensional (matrix or array) or a
13
tree-dimensional array. While a variable names declaration is optional (see the enxt
paragraph below), using DIM for assigning memory ranges for arrays is obligatory in VBA.
DIM is the reserved word and its text will be in blue color on your screen in the VBA editor
window.
VBA programmer needs to decide between two options for declaring the variable names:
1. Implicit Declaration: in this case programmer will use DIM statement just for
dimensioning and eventually for declaring a few selected variables, but all
remaining variables are treated as the type of Variant (the Variant data type is
explained later in the text)
2. Explicit Declaration: in this case ALL variable names must be declared and their
data types assigned using the DIM statement. DIM is used for dimensioning if
needed in the program. When a programmer requires Explicit Declaration, this
request must be placed at the project level, using the command: Option Explicit.
(See example 2.8.) Note: The great majority of programming languages and
software packages require explicit declarations for all variables!
The DIM statement syntax: it may be used just for declaring the data type to the variable
name:
DIM variable_name AS data_type
Or just for the dimensioning:
DIM array_name(100)
where the given number of elements in an this array, array_name is 101 since there is
default array_name(0). Obviously, instead of 100, we can put any integer which is
appropriate for the problem. Hint: DIM statement in VBA may be used dynamically, please
refer to Chapter 4, example 4.3 where we discuss using the cycles (loops) in programs.
Finally, DIM statement can be used for both, dimensioning and declaring in the same
line, as: DIM array_name(100) AS data_type
When typing VBA code, after placing a space after
the text: AS, VBA compiler will show the list of all
available objects and among them designer will
choose the wished variable type (Figure 2.8).
Example 2.6: Selecting the currency data type
for the variable X using the combo box (this
combo box showing all options pops up when
Figure 2.8: Using the combo box to
programmer will put a space after the word AS),
Figure 2.8; when the data type is found, just assign data type
double click its name. Obviously, if you know the correct term, you do not need to use the
14
combo box, you can just type the data type (be careful with spelling). After choosing a
data type, the line will change the color showing Dim and As Currency in blue:
Dim X As Currency.
If variables are not declared, the default option for VBA is to use the Variant Data Type
(and to run program in the IMPLICIT mode) allowing VBA to assign variable types based
on data values (like in Excel). Because of that, it is not necessary to have a DIM statement
in all VBA programs. Using the variant data type is convenient for short programs, but
there are some issues with it (see Example 2.7).
The next table showing DATA TYPES is generated using the VBA help menu:
Data Type Summary
The following table shows the supported data types, including storage sizes and ranges.
Data type
Storage size
Range
Byte
1 byte
0 to 255
Boolean
2 bytes
True or False
Integer
2 bytes
-32,768 to 32,767
Long
(long integer)
4 bytes
-2,147,483,648 to 2,147,483,647
Single
(single-precision
floating-point)
4 bytes
Double
(double-precision
floating-point)
8 bytes
-1.79769313486231E308 to
-4.94065645841247E-324 for negative values; 4.94065645841247E-324 to
1.79769313486232E308 for positive values
Currency
(scaled integer)
8 bytes
-922,337,203,685,477.5808 to 922,337,203,685,477.5807
Decimal
14 bytes
Date
8 bytes
Object
4 bytes
String
(variable-length)
10 bytes + string
length
0 to approximately 2 billion
String
(fixed-length)
Length of string
1 to approximately 65,400
Variant
(with numbers)
16 bytes
Variant
(with characters)
22 bytes + string
length
User-defined
(using Type)
Number required by
elements
The range of each element is the same as the range of its data type.
Example 2.7: Making a syntax error in a variable name could cause a real problem
with many calculations since the default value of ALL variables in calculations is 0. Let us
name the average sales to be Avg_Sales. After calculating them, the value is 2345.00. If
15
the profit is defined as 10% of the average sales, then, Profit=Agv_Sales*10%, but output
value for the profit will be = zero! What happened and why?
Answer: notice the typing mistake in the name Agv_Sales instead of for Avg_Sales when
calculating profit! Because of this typo, and because this code is running in the implicit
(typical) mode, VBA accepted a new variable: Agv_Sales assigned the value of zero to
this variable and calculated profit happen to be 0 instead of 234.50!
For almost all business applications you may choose among the next data types:
Currency, Single, or Integer (for numerical), Date (for dates) and String (for textual data).
To use the EXPLICIT mode, programmer will type:
Option Explicit
at the MODULE level and after that start building a procedure. If you put Option Explicit
you need to declare all variables in all programs in that module by using:
DIM variable_name AS variable_type
at the beginning of the program or before the each procedure in advance of using a
variable itself.
Example 2.8: There are two major points to locate in the next figure:
1. Option Explicit is entered ABOVE the procedure (SUB);
2. Variable n was not declared and the
compiler halted during the trial run.
When this situation happen, you need to
click the OK button and to fix the error
by declaring the variable (in this case:
n). After clicking the OK button in this
Figure 2.9: Variable n was
message box and fixing the problem in
VB Editor, do not forget to click the
not declared and compiler
Reset button in the VB Editor main
stopped the program
toolbar (icon looks like a dark blue
square, see in the Figure 2.10).
Figure 2.10: Run, Break and Reset are the three most important icons in the
VBA menu. Please note that some computers do not have Break/Pause taster
on the keyboard! If you made a mistake and your program went into an infinite
loop and you need to stop the program execution, this Break button could be
your saver!
When
transferring
data from an
Excel
worksheet, not
16
declared variable names will not give any obstacles. If program will use the InputBox or
some other way for data entry (using files), it is highly recommended to DECLARE
VARIABLES (using DIM) even if you do not want to use the Explicit Option. The reason
is that the comparisons of data values and calculations using the type of Variant may
generate some errors in results.
ASSIGNMENT STATEMENT
So far, we learned to declare variables and to bring them from the Excel worksheet. In
this second task we already used the Assignment Statement and it is quite simple. To be
able to make better programs, we need to be more familiar with the Assignment
Statements.
The syntax of this statement is just to place the = sign between the variable name (left)
and the expression (or another variable name on the right side of the = sign). It means
that computer will calculate the value on the RIGHT side of the = sign and ASSIGN
this value as the NEW VALUE for the variable name placed on the LEFT side of the =
sign! In this process, the existing value of the variable on the left side of the = sign
before executing the Assignment Statement is LOST! Using the pseudo-code it looks
like an assignment of the type: A<= B.
Lets suppose to have two variables: Var_A and Var_B. The simplest assignment
statement may have the following syntax:
Var_A=Var_B
This statement will assign the current value of Var_B to Var_A (actually, it will replace the
existing value of Var_A with the current value of Var_B). After execution of the assignment
statement, both Var_A and Var_B will have the equal values, while the original value of
Var_A is eliminated (lost).
Example 2.9: Assume that the values for variables a and b are in the range A2:B2.
A) Bring them into the VBA program, execute the assignment
A=B
and return the values to the range A4:B4. What happened?
B) After that, using original values for a and b from A2:B2, run the next three assignment
statements:
Temp=a
a=b
b=Temp
and copy (put) all three values into range A6:C6.
17
Solution: The purpose of this program is to show what is happening with variable values
when using assignment statements. Notice in the part B) that the sequence of these three
instructions EXCHANGED or SWAPPED values a and b! Program is assigned to the
Button named: Execute Switch (program name should not have a space in the name).
Solution using implicit declaration is presented in the Figure 2.11. Compare assignment
statements: a=Range(A2) with Range(A4)=a to understand the assignment function
Now, we are ready to apply simple mathematical expressions into assignment
statements. As we mentioned, the expression must be on the right side of the = sign and
the result is assigned as a new value of the variable on the left side of the = sign.
Figure 2.11.: This Sub is assigned to the button: Execute switch. After pasting a button we used option
to record a macro, but we created only one click which generated one line of code: Range(A2).Select,
and then we clicked Stop recording. After opening the macro code for editing we removed the text:
Select and inserted a= in front of Range(A2) . All other code is entered using the VBA editor. Please
notice that in the program we are using assignment statement a=Range(A2) to transfer the value
from the cell A2 to become the value of the variable a. The other options for transferring data from
and to a sheet will be described in the text in the section: Linking VBA modules with existing
worksheets. After clicking the Button to run the program, result is in the rightmost part of the figure.
Please compare the change of values using different assignment instructions.
Like we experienced in Excel, VBA calculates using the mathematical priorities of the
operations first: ( ), ^, *, /, +, - and then evaluates the expression strictly from left to right.
It is a good practice to use parenthesis if needed and to be sure that the calculation will
be executed according to our wishes. Assuming that VBA will get it right, programmer
may wish to omit the parenthesis and the consequence might be a wrong result. We can
use the whole chapter to discuss programmers errors: starting from simple omissions all
the way to not understanding what should be done!
For example, expression
my_output= 200 / 5 * 4 gives value 160,
but if we actually needed
my_output= 200 / (5 * 4)
18
we need to put the parenthesis! Try the result for 200/5/4 with and without parenthesis!
Another typical mistake, calculating the mean of two numbers (2 and 8), somebody may
put my_mean=2+8/2 instead of my_mean=(2+8)/2 or mean=AVG(2,8) Hint: the average
function in VBA is AVG nor average like in Excel! In both cases, VBA and Excel AVOID
using the fixed numbers in the program (worksheet) calculations but rather use the
variable names (cell addresses)!
Since we are using symbolic variable names (without being sure which values the user
will put for the input), we must take care of the functions domain when preparing these
expressions. In the case of an error, the program execution stops and the line where the
problem was found will get the yellow background! In that situation, programmer will need
to find and solve what was the problem, which means to eventually change the code or
to add some additional line(s) or add some other instruction for automatically error
checking. After that, click the Reset button and try to run the program again (to locate the
Reset button in VBA Editor, see the Figure 2.10.)
The most common logical mistakes when dealing with math functions are:
1. Using a variable my_var in the assignment my_output=1/ my_var before
assigning a value to my_var! All variables are having the initial value of zero, and
it will make division by zero!
2. During calculation, variable my_var happen to be negative. Without checking its
value, programmer may put my_root=SQR(my_var) causing the error message.
Please notice that VBA function for square root is: SQR(argument) and it differs
from Excel function for square root: SQRT(argument)
3. During calculation, variable my_var changed its value and happen to be zero.
Without checking its value, programmer may put my_output=1/my_var causing the
error message (like in the first case).
from or to that sheet. When done with using this sheet, do not forget to use the instruction
to be back:
Sheets(sheet_name_base).select
to be back to the sheet named sheet_name_base where is the button holding your
macro (in our case it is Sheet1)!
Reminder: in this book, all text in Italics MUST be replaced with the correct text before
using these instructions in the program. Please note that the text of VBA code and
recorded macros will not AUTOMATICALLY change if you will change the Sheet name or
data position if the data were supposed to be transferred using the Range(address)
option after making the VBA program (or creating a macro)!
The statement Range(cell address) assumes static (fixed) label for the address on the
currently selected worksheet. As presented in the Example 2.9, the Range function works
both ways: to get a value from the selected cell in the worksheet and to put (return) value
in the selected (same or different) cell in the worksheet.
Example 2.10: Several correct and incorrect ways of using assignment and the Range
functions:
Correct
Incorrect
My_var=Range(B6)
My_var=Range(A8)
Range(C2)=My_var+2
My_var=Range(X)
Counter = Counter + 1
Counter+1 = Counter
Range(C3)=Range(C7)* My_var-76
Range(A3)+Range(B4)= My_var
A=1/Range(A4)
x=Range("A1").Select
Y = Range("A1:A5")
DIM X(10)
but ONLY if Y is not Declared as a vector; it picks x = Range("A1:A5")
up ALL values from the range. You can paste it Even it seems logical it does not work! See the
the same way, e.g. Range("B1:B5") = Y
comments on the left side in this table! To do it,
More than that if you put Range("B1:F5") = Y, for now, you may transfer data individually and
the content from B1:B5 will be filled repeatedly it will work, but later you will do it with using a
in every column of the whole range (no cycle or a loop (in Chapter 4.)
transposition will occur!) Try: Range("B1:F1") =
Y
Compiler will discover all those incorrect expressions (Try!) and program will stop during
interpretation compilation (or more precise, during: compilation phase of interpretation).
If no syntax problems with instructions, program may stop during the execution because
of wrong data (e.g. value in cell A4 is zero in the statement A=1/Range(A4) ).
Many problems will require dynamic selection of cells from which we need to transfer
data, or where to place the output values. For example, we are creating a list of customers
and we need to append the next customer below the last entered one! In this case we
20
cannot use fixed addresses since we do not know how many customers we might have
in advance! In addition, we do not want that user will open the program to update or
change the code.
If the data are to be manipulated from variable cell addresses during the program
execution we need to apply special approach and we need to use the function:
CELLS(row, column).
This is known as the dynamic data allocation between VBA and the worksheet. VBA does
not recognize regular Excel addressing with letters used for columns and numbers for
rows, except when we use the static addressing using: Range(Letter_Number). VBA
requires that we use the mathematical notation, which counts rows and columns from the
northwest corner (like the matrix notation in the Linear Algebra) and puts first ROWS,
then columns. For example: A1 is 1,1 B1 is 1,2 and B3 is 3,2.
To be able to use this notation in the VBA, we need to use the built-in VBA function:
CELLS(r,c) where r is a row number and c is the column number. Values for r and c are
positive integers or the variable names (with already assigned integer values >0)
representing the numbers for appropriate row and column.
The CELLS(r,c) function can only be used in VBA (when coding macros and programs),
not in Excel itself.
Example 2.11: Lets create an example for the previously mentioned problem: how to
copy values from static addresses into the other sheet BUT in the appropriate row (not
to copy over the existing data)! One of several possible solutions1 will be discussed in
more detail here.
We will use the function =COUNTA(A:A). This function2 could be placed in any cell in the
spreadsheet, except in the column A (why?) and will return the number: how many cells
in the column A contain any data (text or numbers)! Lets put this function in the cell G1.
Solution: The next two Figures 2.12 (a, b) represents the Input sheet, where a sales
representative is collecting input data. After that, he/she will click the button: Add
customer to the database and that way program will transfer the customers data to the
Another solution can be realized using a recordable macro: first insert a row (pushing the previous data
down) and copy the new data into this newly inserted row (it will make the last data to be the first). This
and other options and ideas how to solve these types of problems are discussed in Chapters 3 and 7.
2
Notes: 1. Using Excel function =COUNTA(A:A) we count any kind of texts or numbers (alphanumerical
data) in the whole column A, while using COUNT(A:A) we count only numerical data in the column A; 2.
To get the total of all numbers in a column B you may use =SUM(B:B); 3. To calculate the average value in
the column B, use =AVERAGE(B:B), etc; It is also applicable for the rows, like =SUM(10:10) will total all
numbers in the row 10 (this function could not be in ant cell in the row 10).
21
appropriate row (and column) in the sheet: Management. In this copying the columns
receiving data are not changed.
When using the function CELLS, it is possible to put simple calculations for creating
values for r and c, but it cannot be another function call. This is the reason why we have
the instruction to make the calculation for the new_row as new_row=Range(G1)+1
before being able to use it in the statements like: CELLS(new_row,1) = variable
Using this algorithm, values for all
transferred variables will be
pasted in the appropriate row
based on a value assigned to:
new_row, which is actually the first
available row for new customers.
Figure 2.12.b: Notice the function COUNT(A:A) in the Formula bar, showing that there
are 4 rows used in column A (the title row and entered 3 members)
See the code in Figure 2.13. The program name is Button1_click() because we used the
option to Record a macro from Excel when we started the code (which we usually do),
but it is suggested to change the name of the macro!
22
Note: Since the cells for the source data are fixed (the row and column numbers used to
transfer input data in the program are constants), we used the Range notation. If a
programmer would like to be consistent and to use CELLS(r, c) function through the whole
program, the first three rows will become
First=Cells(4,3)
Last=Cells(6,3)
Phone=Cells(8,3)
2. Using the InputBox option. It is convenient when user need to enter single
value, during the program execution (see examples in this section)
3. Prepare data in a file for entry and position it (preferably) in the same folder
where is the Excel file with your VBA program (please, see examples in
Chapter 3).
Also, there are three common ways to organize data OUTPUT from any VBA program:
1. Create data in VBA and transfer them in a worksheet using Range or Cells (as
it was discussed above)
2. Using the MsgBox option. It is convenient when user need to see a single value
during the program execution and make a decision base on that. Also, it is used
for debugging the program to show the current value of one (or more)
variables during the execution (as mentioned in Chapter 1)
3. Prepare data to be sent (or dumped) to the file (one or more files) for later
Printing (or just viewing). This file or files will be created in the same folder
where is the Excel file with its VBA program. Note: you can use the same file
for Input and Output (please, see examples in Chapter 3).
To input a value, you can use the InputBox. When creating an InputBox, VBA offers help
to better organize appropriate parameters, Figure 2.14:
Figure 2.14.: Parameters to create InputBox. Please note that all options in square brackets are
not necessary. Also, do not type: As String after the right parenthesis.
Figure 2.15: Parameters to create MsgBox. Please note that all options in square brackets are not
necessary. Also, do not type: As VbMsgBoxResult after the right parenthesis.
24
Problems
1. Solve the Example 2.3 using explicit VBA declarations.
2. Give at least three examples to discuss the consequences in the Excel worksheet
after copying, deleting/inserting rows or columns and moving the formula!
3. What will happen when executing your program (or a macro) if you change the
worksheets name you used in the program? Try it!
4. Expand the Exercise 2.11 using Date and Time stamps. Try static and dynamic
versions and discuss the differences!
5. Solve the expanded option of the Exercise 2.11 adding a suggestion given in the
Figure 2.10 about cleaning space to input data for the next customer.
6. Create an algorithm to translate Excel notation into CELLS(r, c) notation and
code a VBA program which will do it!
7. Solve the Example 2.13 using data from a worksheet.
8. More about measures transformation: transform inch to cm and meter to yard!
Solve the problem using Input and Message boxes.
9. Solve the problem 8 using data from a worksheet.
10. Mama Mia pizzeria is delivering food and charging delivery based on the order
size: for orders less than $15, the delivery charge is $3, else $0. Using Excel
prepare calculations and using two buttons list orders with added delivery costs in
the Sheet named: Small_Delivery and other orders in the sheet named:
Big_Delievries.
26
The concept of structured programming started in the late 1960's with an article by Edsger
Dijkstra. He proposed a "go to less" method of planning programming logic that eliminated
the need for using the Go To statement2.
Structured programming could be defined as a technique for organizing and coding
computer programs in which a hierarchy of modules is used, each having a single entry
and a single exit point, and in which control is passed downward through the structure
without unconditional branches to higher levels of the structure. Three types of control
flow are used: sequential, test (selection), and iteration (but not branching).3
Many authors refer to programs with many Go To statements as spaghetti programming
(why?) It is possible to realize all programming needs by using special iterative controls
without using Go To statements. Older programming languages like FORTRAN and
COBOL were using only one kind of loops (known as counting loops) and in that
situation, the Go To statements were necessary and used a lot. Also, it can be proven
that having only IF and Go To control structures we can code any program! We will use
the Go To statement in several examples to show this idea as an introduction to the
Chapter 4.
We already discussed many examples of the SEQUENTIAL flow. We are adding the next
two simple examples to introduce the using of the files for input and output. This approach
is known as file programming or using the legacy systems. It is important for all
programmers to exercise this option since there are many organizations using this kind
of data management, which was developed using variety of older programming
languages (but it is relatively rarely used in VBA programming). After these examples,
this chapter covers many programs with SELECTION controls (IFTHEN,
IFTHENELSE and Select Case), while the ITERATIVE flow is presented in the
Chapter 4.
Example 3.1. This example exploits one of the oldest ways of programming techniques
and it is to use one Input file for data Input and one Output file for information output,
organized specifically for that program. For this example, the input file is prepared and
named: My_Numbers.txt. It has one row with three numbers. Program needs to calculate
their squares and cubes4. Place the output in the file powers23.txt. Hint: In this example
we used Notepad to create the input file. Notepad can also be used to review the output
file. The simplest positioning of input file will be in the default folder (e.g. most often it will
be My Documents). Else you need to write down the complete path where the file is put
Ibid
Slightly modified from http://www.its.bldrdoc.gov/fs-1037/dir-035/_5154.htm
4
We are not calculating more complicated functions since we will not use selection in this example (e.g.
can you calculate a square root of ANY given number?)
28
3
with the file name. The output file will be placed in the default folder (or again programmer
must put the complete path for the location).
Solution: This program has very simple flow: Program takes three values from the Input
file and assigns them to variables: a, b and c. After that, program executes Calculation
and then sends data and information to the Output file using the Print statement.
Reminder: Comments in the program are following the symbol (and the text will appear
in green color), also, the symbol could be anywhere in the program (not necessary at
the beginning of the program line)
Figure 3.1: Input (left) and Output (below) files. Obviously, output
file will require formatting to allow user to better see the results!
Sub power23( )
Open "My_Numbers.txt" For Input As #1 ' Open file for input
Input #1, a, b, c
' Read data into three variables
Close #1
' Close input file
a2 = a ^ 2
b2 = b ^ 2
Calculations and assignment
c2 = c ^ 2
statements
a3 = a ^ 3
b3 = b ^ 3
c3 = c ^ 3
Open "Power23.txt" For Output As #2
' Open file for output
Print #2, a, a2, a3, b, b2, b3, c, c2, c3
Print to file
Close #2
Close file
End Sub
Before running the program, we need to prepare the input file: my_numbers.txt (it was
entered as a text file using the Notepad). The output in the file Power23.txt, visible via
Notepad, too:
Example 3.2: If a programmer will put a bit more efforts, it is possible to create more
user-friendly oriented output file for this example. You may wish to consult VBA Help
about various formatting options using the key words: Print # Statement. The program
for this example (basically alternative solution for the example 3.1) is named
print_formats() . The Figure 3.2 shows a modified program code which creates more user
friendly output. In this program we used the input file named My_Numbers instead of
My_Numbers.txt which was also made using the Notepad, but saved without the file name
29
extension. Do not use a real Word Processor (like Word) to make the input file since a
file produced that way will contain formatting symbols and it may cause various problems
in execution VBA programs.
Figure 3.2: The VBA code for more user oriented solution
Note: more about formatting the output file is discussed in Example 3.14
including the VBA. The IF statement can be applied for many programming flows: from
the simplest cases, to the most complicated situations. There are three distinct options
for IF statements in VBA. Combining them we create the nested IF statements, to be able
to design all programming needs.
In VBA code, the simplest IFTHEN function has the
syntax:
IF condition THEN action
next statement
From the graph (Figure 3.4) we can see that the Next
statement will be executed after action (if condition is true)
or without execution of that action if condition is false. We
have to be very careful not to misuse this option,
particularly when applying it in mathematical expressions.
Please notice that the word action is used in singular it
means ONLY ONE action can be placed after the word:
THEN.
Example 3.3: One classical example for using the simple IF statement (without
changing the program sequential flow) is to calculate the ABSOLUTE value of an
expression (or just for a variable). Let us discuss several options when calculating the
absolute value.
Option 1: REPLACE the value of my_variable with its absolute value.
a. The appropriate VBA code is
IF my_ variable < 0 THEN my_variable= - my_variable
b. with using the built-in function ABS:
my_ variable=ABS(my_ variable)
Option 2: CREATE a new variable and to assign to it the absolute value of the original
variable.
a. You can use VBA code:
Abs_my_variable = my_variable
If my_variable < 0 then Abs_my_variable = - my_variable
b. Alternatively, using the IF statement in Excel: Assume that my_value is in
the cell A5, and we need its absolute value in B5. Then, in B5 we can put
an IF statement:
=IF(A5<0,-A5,A5)
or just
=ABS(A5)
Example 3.4: One of the typical applications to learn using IF statement in any
programming language is to apply them into discussion when solving simple
31
mathematical problems. There are many ways how to discuss and how to solve the linear
algebraic equation a*x+b=0. Do not rush saying that it is obvious: x= -b/a, since the a
could be=0, or both a and b could be =0; designer needs to organize all possible outputs
with discussion! So far, we learned only one option for IF statement and we will use just
this option here. Also, note how the logical operator AND is used in the IF statement in
VBA which is much simpler that in Excel when using the logical operators:
Solution1:
Public Sub calcs()
' Solving equation a*x+b=0 using three message boxes
a = InputBox("Enter the coefficient a (for: a*x+b=0)")
b = InputBox("Enter the coefficient b (for: a*x+b=0)")
If a <> 0 Then MsgBox "X=" & -b / a
If a = 0 And b = 0 Then MsgBox "Any number"
If a = 0 And b <> 0 Then MsgBox "Not defined"
End Sub
In the next solution, we apply an option to change the value for x based on different criteria
allowing the usage of the same variable for all three different outputs.
Solution 2:
Public Sub calcs()
' Solving equation a*x+b=0 using one message box
a = InputBox("Enter the coefficient a (for: a*x+b=0)")
b = InputBox("Enter the coefficient b (for: a*x+b=0)")
If a <> 0 Then x = -b / a
If a = 0 And b = 0 Then x = "Any number"
If a = 0 And b <> 0 Then x = "Not defined"
MsgBox "X=" & x
End Sub
Figure 3.5: Input box for a (entered -2), for b (entered 6) and a message box for the result (x=3).
The procedure has prefix: Public. It means that it is available in any module of the Excel
file in which it resides. All inputs are realized using the InputBox-es and we used the
MsgBox for the output. Please notice the use of the logical operator: AND to create a
condition for the IF statement. If you need to use a combination of the logical operators
32
in the same instruction, it is suggested to use parenthesis to ensure the proper order of
execution. Please notice the flexibility of VBAs VARIANT data type: depending of the
data value, variable x is number or text!
Example 3.5: In many applications, based on the preliminary results (or user inputs),
program needs to continue using one of several possible paths. This problem cannot be
resolved using only the recordable macros, without VBA intervention5.
This example uses a short survey to decide about accepting or not-accepting an item for
display. Based on the survey score, if item is accepted, program continues with the sheet:
Accepted, but if it is not accepted, program continues with the sheet Rejected. Consider
the next Figure 3.6 showing the survey and two calculations: for the average and Max. If
answers generate the average below 2.5 and there are no bad grades, e.g. max answer
is less or equal 3, program flow moves to the sheet: Accepted, but if it is not achieved,
flow goes into sheet Rejected. Both sheets (Rejected and Accepted) have the same
headers and the same way of appending data in the newly generated row 3 (which is
done by inserting a new row in
the row 3 and pushing all
existing data below that row
down).
Program
creates
variables using the values from
the sheet Survey and uses
two IF statements based on the
given criteria for Average and
Max. Only one of these two
statements will be executed
and, independently where the
flow control leads the program,
the continuation is the same!
Figure 3.6: Input data for the Item evaluation. If the average is
below 2.5 and Max is <=3, item is accepted and the program
flow continues on that sheet (notice the sheets Accepted and
Rejected in the figure)
For more ideas about copying data under selections, please read a mini-case: Transferring Data
in Chapter 7.
33
Figure 3.7: Header for the Accepted Items. New data will be placed in the row 3
and all data will be pushed down. The Rejected sheet has the same layout.
A short note about the Int(value) function: This function returns the integer part of the number, for
example Int(2.3)=2 but also Int(2.8)=2. This function differs from the ROUND function:
ROUND(value_to_be_rounded, number_of_decimals), e.g. ROUND(2.3,0)=2, while ROUND(2.8,0)=3.
34
This code starts with assigning the value to the variable x from a sheet (from cell B7)
where it was calculated. Next, we calculate Int value of x. The third line of code is a
statement to make the appearance of the MsgBox only if there is a problem. Please
review the next few lines of code:
x = Range("B7")
x_int = Int(x)
If x <> x_int Then MsgBox "x it is not an integer", vbInformation, "Info about X
FUNCTION PROCEDURES
This simple IF statement can be very useful when applied in the FUNCTION
PROCEDURES. First we introduce how to create a Function Procedure.
Example 3.7: Make a VBA Procedure to help mortgage consultant to automatically
adjust the loans interest rate based on assumed risk to be applied when lending bigger
amounts.
Start from the VB editor and if it is the first program to be coded, create a module and
then click add Procedure. In the dialog box type in the name (your choice, no spaces in
the name) and choose type: Function and Scope: Public.
If you choose the Private Scope then the Functional Procedure will be available only in
this module (Module1).
Figure 3.8:
Starting a new
procedure
35
After clicking the OK button, VBA will create the first line:
Public Function mortgage_PMT()
and the last line:
End Function
Initially the list of arguments, in the first line for this function is empty. Depending on the
needs, we can add one or more arguments to be exchanged during the program
execution. We will add variables p (for the principal) and months (for the number of
months).
Additionally, our function will use a value from the cell B4 as an initial interest rate
(currently = 0.0425). This model will adjust interest rate before calculating the monthly
payment for a mortgage. We are considering three scenarios:
a) If p is between 100,000 and 300,000 it makes mortgage to be a greater risk and will
have a higher interest rate for a quarter of percent from the initial value;
b) If the p is over 300,000 the risk is even bigger and the interest rate is higher for the half
of percent from the initial value, and
c) the third scenario is based on the length of the mortgage, if the number of periods is
smaller (e.g. = 180 instead of 360) than the interest rate is a bit smaller (e.g. for 0.0025),
independently of the loan amount.
A monthly payment is calculated using the Excel function PMT and assigned to the
function name: mortgage_PMT (to be used as an output).
This function is used through the sub-procedure which can be assigned to any Excel
object (most often a button, as we used in this case) or can be executed using the Run
button (Figure 2.8). After receiving the values for p and months directly from Excel sheet
previously created function is called (to be used or executed) in the statement:
monthly=mortgage_PMT(p, months)
Figure 3.10: Input / Output sheet. The VBA code for the Sub and Functional procedures is presented
in the next figure. Scroll bar needs to be extended to allow higher loans and because of that scroll
bar is linked to the cell C3, while in C2 is the formula =100*C3. Interest rate is entered as a simple
value. For the numbers of months we used the Combo box control from the ActiveX menu to
directly transfer selection. Monthly payment calculated in B6 does not include the eventual risk,
while the value in B7 includes the risk after running the sub-procedure. Estimated taxes are in
current dollars (having in mind the inflation over years, this amount will worth less in future).
36
It transfers values for p and months into function and receives a value that is assigned to
the function name in the procedure itself. In this example, the calculated value is
transferred back to the worksheet (or it can be presented using the MsgBox).
Figure 3.11:
Function and Sub
Procedures to
support the example
3.6. Function PMT
has the same name
and structure in VBA
and in Excel.
The next option of using IF function is known as the Block IFTHEN statement (Figure
3.12):
IF condition THEN
action1
action2
END IF
next statement
If condition is true, the next statement will be executed after
all statements: action1, action2 are executed (it could be
one or many actions), or without execution any of these
statements if the condition is false. Notice the different
syntax. There is no any instruction following the THEN in the
same line. After the list of actions is exhausted, it is
necessary to insert a line: END IF. This line allows that
program flow will continue with the next statement.
Example 3.8: Write a program to solve a quadratic equation if the coefficients are in
cells A2, B2 and C2. Results present using Message box(es) and in cell(s) D2:E2.
One possible solution is presented below:
Sub Poly2()
a = Range("A2")
b = Range("B2")
c = Range("C2")
D=b^2-4*a*c
Range("D2:E2") = " "
If a = 0 Then
MsgBox "Equation is not quadratic"
Range("D2") = "Equation is not quadratic"
Exit Sub
End If
If D < 0 Then
MsgBox "No real solution"
Range("D2") = "No real solution"
Exit Sub
End If
x1 = (-b + Sqr(D)) / (2 * a)
x2 = (-b - Sqr(D)) / (2 * a)
MsgBox "X1=" & x1 & " X2=" & x2
Range("D2") = x1
Range("E2") = x2
End Sub
(or more) of them could be another IF statement, and it will be called a nested IF
statement (see example 3.9).
Example 3.9: What corresponds to: Else of the statement X>5? Answer: X< 5, but
also X=5. This could cause some problems if programmer will forget the third option.
Because of that, sometimes people will say non-negative and it does not mean positive,
but, positive or zero!
Example 3.10: There are many mathematical functions differently defined for the
various values of the independent variable (x). For example, find the function value if the
function is defined: y=sqr(x) for x>=0 and y=sqr(-x) for x<0. In this case the VBA code will
be:
Sub if_then_else()
x = InputBox("Please enter value for x")
If x >= 0 Then
y = Sqr(x)
Else
y = Sqr(-x)
End If
MsgBox "x=" & x & " y=" & y
End Sub
Example 3.11: Modified example 3.5 using the IF-THEN-ELSE option will have change
in the section S (Selection) of the program. Original code uses two IF statements:
The next example is organized with using macro recording and with adding just a small
programming intervention when using the IF-THEN-ELSE statement.
Example 3.12: There are many simple games to play using built-in functions for
generating random numbers. Probably the simplest one is presented in the next
worksheet (Figure 3.14.), while the code is presented below the figure.
39
After tossing a coin (actually, clicking the button named: Tossing), frequencies are
collected to present the probabilities. Formula in G4 is ratio between number of Heads by
the number of Tails, while the formulas in G5 and G6 divide the number of Heads (or
Tails) by the total number of experiments. Random numbers are saved in the sheets Tails
and Heads.
Figure 3.14: This problem will use simple IF-THEN-ELSE statement in the code.
Now, we are ready to explore the third MsgBox option (which was announced in the
previous chapter). VBA offers many possibilities to enhance the appearance and the
functionality of the MsgBox objects. Complete list of options is available from the VBA
Help (keyword: msgbox functions).
As introduced earlier, the MsgBox syntax is:
MsgBox(prompt [, buttons] [, title] [, helpfile, context])
Placing the different codes for the buttons option user can create different appearance
and the functionality of the MsgBox. When using more than one button, user needs to
use the assignment statement which will be similar to:
My_variable= MsgBox(prompt [, buttons] [, title] [, helpfile, context])
In this case, My_variable will get the value which depends on the button which user
clicked after reading a message on the MsgBox, for example:
my_option=MsgBox(Would you like to continue, vbYesNo, Ready to play more?)
after executing the message box, value of the variable my_option will be either vbYes or
vbNo (hint: not Yes / No). Using vbYes or vbNo programmer will enable the programs
flow based on users choice!
From the VBA Help menu, partial list of setting is presented on the next page:
Constant
vbOKOnly
vbOKCancel
vbAbortRetryIgnore
vbYesNoCancel
vbYesNo
vbRetryCancel
vbCritical
vbQuestion
vbExclamation
vbInformation
Value
0
1
2
3
4
5
16
32
48
64
Description
Display OK button only.
Display OK and Cancel buttons.
Display Abort, Retry, and Ignore buttons.
Display Yes, No, and Cancel buttons.
Display Yes and No buttons.
Display Retry and Cancel buttons.
Display Critical Message icon.
Display Warning Query icon.
Display Warning Message icon.
Display Information Message icon.
After choosing MsgBox with more buttons, assigned variable will get values starting with
vb, like VBYes, vbNo,vbCancel. It can be used in a variety of simple problems.
Example 3.13: The Excel tool Goal Seek is very useful for What-if Analysis, only issue
is that, after running this routine, user cannot see the starting value he/she wanted to
update or discuss the changes, so user needs to remember or write it down (which is
completely against building IS applications!) One of the classical usages of Goal Seek
Analysis is in the Break-Even Production problem: Suppose you are making initial
production plan to produce one product. There are start-up costs: S and producer has it
41
independently of the amount of goods: X to be produced, and on the cost side there are
also unit costs: C per produced item. On the revenue side, there is amount to be sold as
X*L (where the L is the estimated level of
sales to be achieved presented as a
percent, and obviously L<=100%) to be
multiplied by the price per unit: P. This is
very simplified model, the simplest option
being L=100%. We will leave the model
discussion for some of the business
classes. For the suggested model, Profit
could be calculated as P=X*L*P-(S+X*C).
There are actually 2 variables: X and L
and typically in applications, based on
experience user will set the level for L to
be between 80% and 95%. The model is Figure 3.15: Break-Even Model
presented in a worksheet (Figure 3.15).
Below the model is the button which contains the program for using the Goal Seek tool
from Excel. When using this model, the first step to be considered is by changing ONE of
the input variables to get the break-even point, e.g. to cover the expenses! In this case,
in the Goal Seek tool we need to put that the value in B7 is zero and Goal seek will give
us the new value for the production, but it could be any other variable selected (sale price,
percent sold, unit cost or start-up cost). More than that, we can put any value for the target
value in the Goal Seek and do what-if Analysis for that case, too. As mentioned above,
for all of the suggested options, we have the problem that after running the Goal Seek we
will either lose the result or we will lose the value of the variable we selected to be changed
while pursuing to meet the target. The next program is organized in a way that user will
choose which ONE of the three optional variables to change to get the suggested level of
profit. In the model we used readymade MsgBox with three buttons and assigned options
to them. User can create three buttons on the form instead! What is not quite user friendly
are the built-in names for the buttons in this type of MsgBox.
Depending on that, in the next step user can decide which value to keep (the program
name is: Keeper) after choosing an option from the MsgBox: Revert to old value!
Choosing yes, the production level in the model will be reverted to initial old value of
280, else, it will remain 125 while the profit level is now equal to target =0.
The program code is presented below:
Hint: There is no need to use If-Then Else in the last IF statement of the program since
the Goal seek by default put the new value for the selected variable (in this case in B4).
42
Program execution:
Figure 3.16: Message box will allow user to choose which variable to vary. Independently which
button user will click, the message box (left) will appear and user will enter the target value for
the profit. If user selected Yes it means that the production will be varying and after choosing
the target profit to be zero, the next message box will appear near the model, so user can
compare the new value for the production: 125 with the old value of 280! Finally, user decides
to keep the new value or to revert to the original value.
43
Example 3.14: In this example we will use the IF-THEN-ELSE function, but also, we
will introduce the first time how to use the cyclic data input! Let us suppose that there
are many items ready to be put on sale! If the item is over $100, company is offering 20%
discount, but if the original price is not over $100, then the discount will be 10%. List of
items contains Item ID, Description and the original Price. Since the programmer does
not know how many items are in the list, the best way will be to organize reading the list
line by line, until there is no more data! VBA offers built in option
Do While Not EOF Loop
to check if there is the end of file or not. If there are more lines, system continues to read,
else stops the loop. Program could be assigned to any control object, most commonly to
a button, which is the most simplest for execution. It is possible not to assign the program
to any control object. When saving the program, it must be saved as an Excel file with
extension file_name.xlsm (as usual).
Solution: Notice that we printed header before starting a Loop for data entry to avoid
repetition of the title. Data are entered line by line. After reading a line, values are
assigned to variable names, the price is compared with the given criteria and the new
price is calculated. After that, one line is printed in the output file. After finished reading,
we need to close both files.
Sub pricing_cycle()
Open "Price_list.txt" For Output As #2
Print #2, "Item ID"; Tab; "Description"; Tab; Tab; "New Price"
Open "Items.txt" For Input As #1
Do While Not EOF(1) ' Loop until end of file.
Input #1, item_id, des, Price ' Read one line of data
If Price > 100 Then
new_price = Price * 0.8
44
Else
new_price = Price * 0.9
End If
Print #2,
Print #2, item_id; Tab; des; Tab; Tab; new_price
Loop
Close #1 ' Close input file.
Close #2 ' Close output file.
End Sub
Input and output files are presented next:
Figure 3.20: Input file (Items.txt) and the
output file (Price_list.txt) for the
example 3.5. Hint: Formatting of the
output is not used in this example (for
details about refining the output please
use the built-in VBA help or on-line VBA
help)!
Example 3.15: To introduce the nested IF statements we will recycle the example
3.4, and again solve a linear equation a*x+b=0 (a, b are input data, while x is information
or output).
Sub Button1_Click()
'Solving a*x+b=0
Program will first clean the output cell C2
Range("C2") = " "
a = Range("A2")
b = Range("B2")
If a <> 0 Then
x = -b / a
Range("C2") = x
Else
If b = 0 Then
Range("C2") = "Infinitesimally big number of solutions (any x is a solution)"
Else
Range("C2") = "Solution is not defined"
End If
End If
End Sub
45
Example 3.16: The IF statement in VBA can be used to execute the physical
branching of the design of the Excel program (similar to Go To option). This option is very
simple and will be used in many prototyping cases (compare to Example 3.5). This
excerpt is from a small business case for car sales: if a customer selects to purchase car,
this code will transfer jump to the Sheet Purchasing Options, while the option to lease
the car is in the sheet Leasing Options:
If Range("B6") = 1 Then
Sheets("Purchasing Options").Select
Else
Sheets("Leasing Options").Select
End If
Hint: this code is not covering the option that customer will give up (or balk), and in this
situation we can use nested IF statements, like it is presented below. Alternatively, you
can create a solution using three separate IF statements.
If Range("B6") = 0 Then
Sheets(Balking Options).Select
Else
If range(B6)=1 then
Sheets("Purchasing Options").Select
Else
Sheets("Leasing Options").Select
End If
End if
.
This example gave the excellent introduction to one of the special selection options
offered by the VBA and this is the Select Case statement. The Select Case is very useful
when there are three or more options to be considered for selection. When using the
select Case statements there are fewer chances for mistakes than making nested IF
statements and it is recommended to use instead of the nested IF.
e_bonus = 0
actually means:
if sales < 2000 then e_bonus = 0
If any of the conditions will be fulfilled,
Select Case instruction will move flow
control to the End Select. Because of that
be very careful when creating intervals to
cover the interval having in mind that
you can use the Case Else at the end!
.
47
We can use the equations in the Case statement. For example, in many problems we
need to change the program flow based on the selected indicator value: program will
calculate the shipping costs, derive the amount of tax deductions based on number of
children, give a number of points during multiple choice exam based on the option student
bubbled or will estimate the amount of the fine to be paid for the Parking Ticket7 based
on the indicator policeman selected.
Example 3.18: (The Parking Meter Mini Case). There is a list of most frequent parking
violations (for the Green Zone):
1
2
3
4
5
Expired Meter
No Parking Zone
Double Parking
Blocking Garage / Driveway Entrance
Parked in a Handicap Place
$25
$50
$100
$150
$400
All fines are tripled in the Red Zone or doubled in the Blue Zone of the city.
A program is based on this data. The input values are: Number indicating the violation
type and the City_Zone Code (Figure 3.22) while the output shows all inputs and the fine.
One of the possible solutions is presented on the right side.
Figure 3.22: Input Boxes (left and middle) and the output box (right, enlarged)
Sub Parking_Fines()
' Parking_Fines Program
violation_code = InputBox("Please enter the violation code")
city_zone = InputBox("Enter color code: 1 for green, 2 for Blue or 3 for Red")
Select Case violation_code
Case Is = 1
fine = 25
Case Is = 2
fine = 50
Case Is = 3
fine = 100
Case Is = 4
fine = 150
Case Is = 5
Example 3.18 is based on an idea from Shelly, Hoisington, Microsoft Visual basic 2010
(Comprehensive),Course Technology, Boston, MA, 2011
48
fine = 400
Case Else
' if the policeman omitted to put the reason
fine = 50
End Select
' if the policeman omitted to put the city zone (not to be treated as blank fine =0!)
If city_zone <= 0 Or city_zone > 3 Then city_zone = 1
fine = fine * city_zone
MsgBox "violation_code=" & violation_code & " Zone=" & city_zone & " Fine =" & fine
End Sub
Example 3.19: A little bit more user friendly will be the another solution for the example
3.18 using the controls from in the Excel spreadsheet. It is more compact version of the
program and more user friendly for data entry (not for people who did parking violation).
Since there are two sets of option buttons (Figure 3.23), user who is entering data must
choose from these buttons and there is no need for the statement Case Else in the Select
Case block.
Sub Parking_Buttons()
' Parking_Buttons Macro
violation_code = Range("C15")
city_zone = Range("F15")
Select Case violation_code
Case Is = 1
fine = 25
Case Is = 2
fine = 50
Case Is = 3
fine = 100
Case Is = 4
fine = 150
Case Is = 5
fine = 400
End Select
fine = fine * city_zone
Range("E20") = fine
End Sub
Figure 3.23: Please note the frames around the group
of option buttons: they are necessary for individual
selections of option buttons from the two groups!
CREATION THE BUTTONS, and they are not based on the buttons location on the
Sheet!
Problem was constructed by a very well known French gambler DeMere. He asked the famous mathematician of
that period B. Pascal to help him in solving it! It was one of the problems when Pascal started to develop the
theory of probability!
50
Program is designed to use the random numbers produced in Excel using the built in
function
RandBetween(a,b)
which generates Uniform random integers between a and b. To use this function in a
VBA statement, program will have an assignment statement of the type:
var_name = Application.WorksheetFunction.RandBetween(a, b)
The number of experiments: n, which outcomes will be counted is an input value. In this
solution n is entered using the InputBox. Because of that it is recommended to declare
this variable as Integer. Also we declared the counter of experiments: c to be an integer.
To have a better comparison, program requires having more than 10 experiments (we
suggest more than 100). We use IF with GOTO combination to simulate the loop
(statements with the GOTO and appropriate labels are bolded in the program list).
Public Sub DeMere()
Dim c, n As Integer
n = InputBox("Please enter the number of experiments")
If n < 10 Then
MsgBox "Not enough data for the experiment"
Exit Sub
End If
c=0
S12 = 0
S13 = 0
my_loop:
D1 = Application.WorksheetFunction.RandBetween(1, 6)
D2 = Application.WorksheetFunction.RandBetween(1, 6)
D3 = Application.WorksheetFunction.RandBetween(1, 6)
If D1 + D2 + D3 = 12 Then S12 = S12 + 1
If D1 + D2 + D3 = 13 Then S13 = S13 + 1
If c = n Then GoTo my_results
c=c+1
GoTo my_loop
my_results:
MsgBox "S12=" & S12 & ",S13=" & S13
End Sub
51
Example 3.21: There are N employees. The input file: Employees contains employees
IDs, number of hours worked during the two weeks period and the indicator between 1
and 5 showing the wage rate (1 is for $8.5, 2 is for $17 etc.) Calculate and present the biweekly wages for all employees and calculate the total amount needed to pay all workers.
One possible solution is presented below. There are two weak parts of this solution:
user needs to know the number of employees who submitted hours worked and for each
employee this file has information about the wage rate. Alternative solution could be
designed with using the two files: master file with employee IDs (possible some other
attributes like: names, addresses) and their wage rates which needs to be merged with
a temp file showing only employee IDs and hours worked. Merging and/or searching
program is needed to align the IDs in both files (if using merging, both files must be
sorted). One example for merging is in the next chapter and one example for the payroll
is in chapter 7: Simple Payroll Model, case 7.8.
Sub wages()
Dim n, r, ID As Integer
Dim hours_worked, wage_rate As Single
min_wage = 8.5
n = InputBox("please enter the number of employees")
r=0
Open "employees.txt" For Input As #1 ' Open file for input.
Open "biweekly.txt" For Output As #2 ' Open file for output.
Print #2, Tab; "Bi-weekly wages"
Print #2, ' Print blank line to file.
reading:
r=r+1
Input #1, ID, hours_worked, wage_rate ' Read data into three variables.
wage = hours_worked * wage_rate * min_wage
Print #2, "ID:"; ID; Tab; "wage="; wage ' print all for one employee
If r <= n - 1 Then GoTo reading
Close #1
Close #2
End Sub
52
Figure 3. 25: Input file (left)
and the Output file (right). To
create nicer output list we
will need to use formatting
when creating a file: biweekly
during the program
execution.
Example 3.22: Using the EOF option count the number of members in a list of numbers
and find the max value in the list.
Please notice that we assumed that the list contains at least one number. If the list is
empty (input file has no data), VBA will send a message: Input Passed End of file! We
are using two separate inputs for finding max (if we needed just to do counting, it can be
done with only one input statement). Since the output is short, we are not using the output
file. Instead of MsgBox, good solution could be to paste the information into a worksheet!
Sub max_count()
Open "my_list.txt" For Input As #1
Input #1, my_number ' Read one line of data
Count = 1
My_Max = my_number
Do While Not EOF(1) ' Loop to read data until end of file.
Input #1, my_number ' Read one line of data
Count = Count + 1
If my_number > My_Max Then My_Max = my_number
Loop
Close #1
' Close input file.
MsgBox "From given:" & Count & " numbers," & " Max=" & My_Max
End Sub
Figure 3. 26: Input
file (left) and
MsgBox as the
Output (right)
53
Problems
1. Solve example 4 using just Excel options (where will be your result?):
a. With nested IF without using the logical functions (hint:
=IF(A2=0,if(A3=0,Any number, ...
b. With using the logical functions (hint:
=IF(AND(A2=0, A3=0),Any number,
2. Experimenting with the ROUND function. This function works both in VBA and in
Excel. Verify that the Round function can be applied to big numbers, like
=ROUND(22222,-3) will give the value: 22000 and =ROUND(2222567,-3) will be
2223000! Create a table showing how Round could be used for three very small,
three usual and three very big numbers (use other numbers not those shown
above).
3. Combine ideas from Examples 3.6 and 3.7 to design a program to solve many
equations if the coefficients are prepared in an input file (put at least 5 sample pairs
of the coefficients including one of each special cases)!
4. Solve the example 3.13 without using the nested IF statements
a. Using VBA
b. Using Excel only
5. Solve the example 3.15 using Lookup tables in Excel (without VBA)!
6. Using the EOF (End of File) option solve the problem discussed in Example 3.20
7. In the Example 3.20, we suggested to manage the output differently. Write a few
lines of code to edit the program with a) creating the output file and b) transferring
output information in the worksheet!
8. Solve the Example 3.21 to find the minimum of squared values from the list given
in the file my_list.txt
54
As mentioned above, the VBA offers three basic loops: FORNext (or counting loop),
Do WhileLoop and Do UntilLoop.
When studying the syntax (Figure 4.2 for the For Next option) please notice that [Any
text in square brackets is optional]
The syntax for all three basic loop controls is presented in the text and we start with the
simplest one:
FOR Next loop (Figures 4.2 shows pseudo code and 4.3 shows the flowchart) allows
that a statement (or collection of
statements) will be executed a given
number of times knowing that the
value of counter, growing from start
(by step) should never be greater
than the value of end. If the step=1
then it should be omitted.
Figure 4.2: Pseudo code for the For Next Loop
1
This figure is the same as Figure 2.10; it is put here to help reader not to waste time searching around
55
Among the Statements in a cycle you may use the EXIT FOR command if you need to
leave the cycle before the end of the loop (the next action will be to execute the Next
statement). Obviously, it is NOT
POSSIBLE TO JUMP INTO THE
LOOP! Variables: counter, start, end
and step must have numerical values
before being used in the FOR
statement. This type of loop controls
the value of the variable counter at the
bottom of the loop, so it will be
executed at least once and it might
cause problems in some applications.
Example 4.1:
Let us start with a simple problem:
Calculate the absolute value (or any Figure 4.3: The FORNEXT Loop. If the value for the
other function of your choice) for all
counter is < end, its value is being changed by adding
numbers in the column B. In the
column A are just their order numbers the value of step (or 1 if the variable step is omitted).
(used just for illustrative purposes). In some cases the step value can be negative!
This simple problem will be solved Pseudo code is in Figure 4.2.
using all three types of loops2 and we
will always use this problem to be the first problem after introducing syntax for the
appropriate loop. Depending on the function, user can solve the problem using only
Excel, too.
Input data are presented in the Figure 4.3, while a solution using the: For Next loop is
below:
For a programming practice you may solve this problem using the IF and GOTO option. As an Excel
practice consider making a macro for automatic execution (not with placing a function in C2 and then
using the fill-in or copy option, which is another solution, but it is not recommended now! Why?
56
Sub For_Click()
last = Range("E1")
For Row = 2 To last + 1
Cells(Row, 3) = Cells(Row, 2)
If Cells(Row, 2) < 0 Then Cells(Row, 3) = -Cells(Row, 3)
Next
End Sub
Interesting line of the program is For Row = 2 To last + 1 showing the issues with
counting based on the fact that the FORNext loop examine the exit criteria (condition)
an the bottom of the loop. Output results are obvious and we will not waste space to
present them.
Example 4.2: Solve the previous problem by creating a vector to transfer data. There
is no standardized terminology and we will use vector for one-dimensional matrix, array
for two-dimensional matrix and matrix for higher dimensions. In this simple example,
introducing vector may be seen as an extra work (often called the overkill) for this
problem since it can be solved very elegantly without using arrays (vectors), but it is a
good illustration about transferring data from a worksheet into vector and back.
To use vectors (and arrays) programmer needs to use the DIM option to reserve the
selected number of consecutive cells in the memory for the members of a vector or of
an array. In this example we put that the max number of elements is 101 using the Dim
statement DIM X(100), since by default, there is a place for X(0).
Sub using_vector( )
Dim x(100)
my_end = Range("E1")
For counter = 1 To my_end
x(counter) = Cells(counter + 1, 2)
If x(counter) < 0 Then x(counter) = -x(counter)
Cells(counter + 1, 3) = x(counter)
Next
End Sub
When we reserved 101 places for the vector X, the number 100 for some readers may
look very big, but for some others really small! To better manage space, it is possible to
create a DYNAMIC allocation for the vector (or array, matrix) size.
The syntax is:
DIM vector_name()
and then to adjust the size from the inside of the program by using the instruction:
REDIM vector_name(variable_name)
where the value for the variable_name must be created before using it in this instruction
and to be numeric and positive.
57
Example 4.4: Using ideas developed in Example 4.2 or 4.3 solve the next problem:
Coordinates (x,y) for any number of points are in columns A and B. Find the point which
is the closest to coordinate center (0,0). Hint: using the Pythagorass theorem, distance
between (0,0) and (x,y) is d=sqr(X^2+y^2) .
Sub distance()
N = Range("D1")
Dim D(50)
' Calculating all distances
For c = 1 To N
D(c) = Sqr(Cells(c + 1, 1) ^ 2 + Cells(c + 1, 2) ^ 2)
Next
' Finding min value and the closest point
my_min = D(1)
min_point = 1
For c = 2 To N
If D(c) < my_min Then
my_min = D(c)
min_point = c
End If
Next
' Put the min distance next to the point
with it!
Cells(min_point + 1, 3) = my_min
End Sub
Figure 4.4: Data Entry in the range A2:B10, result
is in the column C
58
After running this program, the solution shows that the distance between (0,0) and the
point (1, 2) is 2.24 and it is the shortest one! If you want to run the program again with
different points, please delete the appropriate range in the column C (or just make a
macro to do it for you)!
Example 4.5: Array is given in the range (Cells(1,1), Cells(My_rows, My_Columns)),
where the array dimensions differ from problem to problem based on the user entries.
Find the minimum value in each
row and the max value in each
column of this array.
Hint: We will place one solution
using the array, but this problem
can also be solved using
Figure 4.5: Data Entry in the
individual vectors. In our
range A1:E15, results are in the
example, array has 15 rows and
next figure in the column F and
5 columns.
row 16.
Solution is in the figure 4.6 (the
max and min values are bolded)
Sub min_max_problem()
My_Rows = Range("H1")
My_Columns = Range("J1")
Dim MY_ARRAY() As Integer
ReDim MY_ARRAY(My_Rows, My_Columns)
'fill the array
For rr = 1 To My_Rows
For cc = 1 To My_Columns
MY_ARRAY(rr, cc) = Cells(rr, cc)
Next
Next
' find the minumum in each row
For rr = 1 To My_Rows
my_min = MY_ARRAY(rr, 1)
For cc = 1 To My_Columns
If MY_ARRAY(rr, cc) < my_min Then my_min = MY_ARRAY(rr, cc)
Next
Cells(rr, cc) = my_min
Next
' find the maximum in each column (notice the code reuse from finding minimum)
For cc = 1 To My_Columns
my_max = MY_ARRAY(1, cc)
For rr = 1 To My_Rows
If MY_ARRAY(rr, cc) > my_max Then my_max = MY_ARRAY(rr, cc)
Next
Cells(rr, cc) = my_max
Next
End Sub
59
Figure 4.7: Data entry organized in the range A1:D3 (upper) and the math
notation (lower). Program should present results in the range A5:B5
60
next step. We are examining several ideas how to control program execution by having
different stoppers.
Example 4.7: Lets solve the problem introduced in the example 4.1 using the Do
WhileLoop. The first solution is based on existence of the order number! If there is no
order number in a cell, Excel assumes that in that case the value in the cell =0, so if
there is nothing entered in that cell, its value =0 and the program stops.
Sub My_while_1()
r=2
Do While Cells(r, 1) > 0
Cells(r, 3) = Cells(r, 2)
If Cells(r, 2) < 0 Then Cells(r, 3) = -Cells(r, 3)
r=r+1
Loop
End Sub
Example 4.8: Lets solve the problem introduced in the example 4.1 using the Do
WhileLoop, but, without using the order numbers from the column A. Obviously, the
criterion used in Example 4.7 is not correct in this case since it is possible to have a
value =< 0 in the input data! In this solution we are using the information about the total
number of input values from the cell E1: =count(B:B) and we count rows while the
counter is smaller or equal to the upper limit: tot + 2. Please notice that tot is the value
from E1 and that there are two rows of headings above the input data.
Sub while_count()
tot = Range("E1")
r=2
Do While r <= tot + 2
Cells(r, 3) = Cells(r, 2)
If Cells(r, 2) < 0 Then Cells(r, 3) = -Cells(r, 3)
r=r+1
Loop
End Sub
As you can see, this solution is very similar to the previous solution using the ForNext
loop. Also, it is presented as a solution using the Do UntilLoop in the Example 4.12.
Example 4.9: This solution of the previous problem will use the order numbers from
the column A and stops when there are no more data (no more order numbers).
Program stops if an order number is wrong (or missing)!
62
Sub My_While_Click()
rr = 2
Do While Cells(rr, 1) = rr - 1
x = Cells(rr, 2)
If x < 0 Then x = -x
Cells(rr, 3) = x
rr = rr + 1
Loop
End Sub
Example 4.10: Using Do While Loop in a mathematical analysis problem. One of
more complicated problems in the Mathematical Analysis which many people are not
able to grasp is the problem of understanding limits of the functions in some more
complicated cases. Numerical analysis might help in those situations. Assume that we
are looking for Lim (1+x)^(1/x) for x->0 (function is not defined for x=0). It is not obvious
that the lim will be the number: e. Lets try to calculate the function value when x tend
towards zero: x->0 to see which values are we getting. From the Excel EXP(1) function
we can see that the approximate value for the number e is 2.71828
Solution: In the numerical process a given function is in the separate procedure called:
Limit. The program is organized to have three stoppers to disallow infinite loops 3. User
can use this program for many other functions. When placing other function, only real
change will be to organize to have limit x -> 0 and no other changes are needed. When
you will choose the input values in the worksheet, start relatively near zero, make
epsilon very small (for example 10^(-6)). Usually, people will make a value for delta
(delta is making x to go towards zero) a bit bigger than epsilon, but it is not required,
(delta could be smaller than epsilon).
To add one more stopper, program
counts iterations. For the max number
of iterations we experimented with
numbers between 100 and 500 (in the
program, we reserved up to 500
spaces for the functional values). At
Figure 4.10: Setting up the iteration criteria
When we use Solver, there are built-in several instructions with adjustable values on how the program will stop:
Time, Number of Iterations, Precision, Tolerance, Convergence! In practice, typically we did not changed those
default values since they are set up for the majority of business problems and were taking care about the type
of problems and expected solutions. If using Solver for Linear Programming problems in Excel before 2010 we
needed to open Options and click: Assume Linear Model and Assume Non-Negative. If using the newer versions
of Excel (2010 or 2013), we do not need to click the Options button (unless we need to change default settings),
just to select Simplex LP for linear programming problems.
63
Function limit(x)
limit = (1 + x) ^ (1 / x)
End Function
Sub limit1( )
Dim epsilon, Delta As Single
Dim it, max_it As Integer
In many programs we need to start with initializing
Dim My_val(500) As Single
some values to start the process! It is called Data
epsilon = Range("B2")
Initialization. All newly introduced variables will have
Delta = Range("B3")
initial value of zero, unless we use assignment
x = Range("B4")
statements to change their values.
max_it = Range("B5")
it = 2
My_val(1) = limit(x)
x = x - Delta
My_val(2) = limit(x)
Do While Abs(My_val(it - 1) - My_val(it)) > epsilon
condition 1
x = x - Delta
If Abs(x) < epsilon Then
condition 2
MsgBox "x is reaching limit, function might be undefined"
Exit Do
End If
If it >= max_it Then
condition 3
MsgBox "Precision not reached for given Max_it"
Exit Do
End If
For this example we used FOR NEXT
it = it + 1
loop with counting backwards to show
My_val(it) = limit(x)
the tail part of the output (last 10
Loop
values) at the top of the sheet (see in
my_row = 2
the Figure 4.7 below). The value closest
For counter = it To it - 10 Step -1
to the limit is in the cell D3.
my_row = my_row + 1
Cells(my_row, 4) = My_val(counter)
Next
End Sub
64
DO UNTIL LOOP
DO UNTIL control is used similarly like the Do
While Loop. If condition (see Figure 4.12) is not
true, the loop will not start. Programmer needs to
organize ending by changing the condition value,
or by using the Exit Do statement to exit the cycle.
Sometimes, user may even use the Exit Sub
option to not only stop the loop, but also to stop
the program execution.
Figure 4.12: Pseudo code for the Do
Example 4.12: Lets solve the problem 4.1 again using the Do Until Loop but
assuming that there is no list of order numbers (idea to use the previous solution fails,
why?) we will use the counter posted in the cell E1 (in E1 we have =count(B:B) ).
Sub Button1_Click()
tot = Range("E1")
r=2
Do Until r = tot + 2
Cells(r, 3) = Cells(r, 2)
If Cells(r, 2) < 0 Then Cells(r, 3) = -Cells(r, 3)
r=r+1
Loop
End Sub
Please note: the counter (r) used to stop the loop in fact works until tot+1, but it stops
when reaching the value tot+2 (stopper is at the beginning of the loop)! Compare with
the other solutions using other loop options.
65
Example 4.13: Simple application for using Do Until Loop structure. Column A
contains Item numbers, column B their Purchased prices and the column C their Sales
prices. Find if there is an item having the markup4 less than 10% of the purchased price,
e.g., we can use the formula: Purchased_price *1.1 <= Sales_price . In the program
we will use two controls to stop the run since the loop will not stop if there is no item
satisfying the condition! Create a message box to show the row in which the item is
found and highlight that row and both prices.
Sub Markup_problem()
my_row = 2
Do Until Cells(my_row, 2) * 1.1 >= Cells(my_row, 3)
If my_row >= Cells(1, 6) + 1 Then
MsgBox "Not found"
Exit Sub
End If
my_row = my_row + 1
Loop
MsgBox "Item found in row " & my_row
Range(Cells(my_row, 1), Cells(my_row, 3)).Select
End Sub
Markup is the ratio (in some cases a difference) between the sales price and the purchased price. Depending on
the product, it could be very high (over 40% for furniture) or very low (<5%, for bread), and anything in between.
66
(Do While and ForNext) and several block IF statements. Please not that the
condition with DO Until loop is being checked BEFORE the loop execution and it is the
reason for having loop condition: my_row = Cells(1, 6) + 2.
Sub Markup_problem_all()
Dim Found(100) As Integer
it = 1
my_row = 2
Do Until my_row = Cells(1, 6) + 2
If Cells(my_row, 2) * 1.1 >= Cells(my_row, 3) Then
Found(it) = my_row
it = it + 1
End If
my_row = my_row + 1
Loop
If it = 1 Then
MsgBox "Not found"
Exit Sub
End If
For cc = 1 To it - 1
Cells(cc + 1, 4) = Found(cc)
Next
End Sub
Problems
1. Find what you need to change in the solution of the example 4.4 to find the point
with the max distance from the coordinate center! Hint: when selecting the
variable names, min and max are reserved words in VBA.
2. Find what you need to change in the solution of the example 4.4 to find the point
with the max (or min) distance from the GIVEN point T(3,3), not from the
coordinate center!
3. Locate the instruction:
Cells(rr, cc) = my_max
at the end of the program in Example 4.5. How come it is not writing the results
over the matrix itself? What happened with the counter(s)?
4. Using a small modification of the example 4.8, find the limits: Lim(sin(x)/x), for x>0 and Lim (x-sin(x))/(x^3) for x->0 (Hint: Using math rules check the results
analytically that they are 1 and 1/6).
67
5. Solve the Example 4.6 using the high school type of notations for the
coefficients!
6. In the Example 4.6 we did not do complete discussion! Please complete it based
on the similar discussion we did for the equation a*x+b=0.
7. Calculate the number of iterations in the following cycles:
FOR cc=1 to 5
FOR cc=1 to 5 tep 2
FOR cc=1 to 0
FOR cc=1 to 1
FOR cc=5 to 7 step -1
FOR cc=7 to 5 step -1
DO While 5 > 4
DO While 4 > 5
DO Until 5 < 4
DO Until 4 < 5
Do While tmax=60
Do While x=0
8. Create an example when using FORNext loop will generate the big mess e.g.
error message because of running the first pass through the cycle. Solve the
same problem using Do While or Do Until instead (and no big mess this time)!
68
Each record in a database (or file) has one unique (distinct) field called the Primary Key (PK). There are no two
identical records in a file or a table: even if all fields has the same content, their PKs MUST be DIFFERENT). Because
of that, sorting PK is actually solution to sort records without moving them around.
69
Example 5.1: This solution for the Bubble sort uses Do Until and ForNext loops.
Instead of using Do Until some authors recommend this algorithm as a good illustration
for using GOTO statement (GO TO is allowed in VBA, not in some other languages)!
Sub bubble_Until()
Dim X(100)
tot = Range("C1")
For rr = 1 To tot
X(rr) = Cells(rr, 1)
Next
Do Until i = tot
For i = 1 To tot - 1
j=i+1
If X(j) < X(i) Then
temp = X(i)
X(i) = X(j)
X(j) = temp
Exit For
End If
Next
Loop
For rr = 1 To tot
Cells(rr, 2) = X(rr)
Next
End Sub
Swapping the
elements X(i) and
X(j)
Presenting
the output
(sorted list)
70
Example 5.2: Bubble sort using two FORNEXT loops is similar to solution in the
Example 5.1 and it is probably the shortest algorithm based on the number of lines, but
is still needs at most O(N^2) operations!2 Additionally in this example we count the
number of swapping!
When exploring this solution please locate the different ending points for the two FOR
loops. Swapping two members is executed inside the internal loop.
In this solution we added the counter of swapping (OP). Running several tests (it was
not a scientific testing) the number for OP was from 0 (case when the input was already
sorted!) to OP = 36 in the case when the input list of all 9 different values was sorted in
descending order! The number of comparisons is: N^2 (loop inside loop)!
In Figure 5.3 the number of operations is 19. We tried if all elements were different and
usually got the values between 10 and 23.
Sub bubble_FOR()
Dim X(100)
tot = Range("C1")
For rr = 1 To tot
X(rr) = Cells(rr, 1)
Next
For i = 1 To tot - 1
k=i+1
For j = k To tot
If X(j) < X(i) Then
temp = X(i)
X(i) = X(j)
X(j) = temp
op = op + 1
End If
Next
Next
For rr = 1 To tot
Cells(rr, 2) = X(rr)
Next
Cells(1, 4) = op
End Sub
Based on the example from: Vulicevic, B and Crnkovic, J., Algoritamski Jezik FORTRAN IV, p.177, Univerzitet u
Beogradu, pp. 276, Beograd, 1984.
71
72
Searching Algorithms
The simplest (but also the slowest) solution is the SEQUENTIAL search. For the list of
N members it has on average N/2 comparisons: 1 in the best case or N in the worst
case scenario. The appropriate algorithm was applied in the Example 4.13 to illustrate
the Do Until loop. Another
(but quite similar) solution is
presented next, and we will
use it again in Case 7.8 at
the end of this book.
Example 5.4: Assume that
the input list is in the column
A. The value we are
searching for is entered
using the Input box (please
note to declare the value as Single or Figure 5.5: Beginning of the search (above) and the
Double if using decimal numbers).
result (below)
Using the Do Until loop find in which
row is the matching value, or if it is not found put a
msgbox with a comment and stop execution.
Sub seq_search()
tot = Range("C1")
Dim my_value As Single
my_value = InputBox("Please enter the value")
rr = 1
Do Until Cells(rr, 1) = my_value
If rr = tot Then
MsgBox "Value not found"
Exit Sub
End If
rr = rr + 1
Loop
Cells(rr, 1).Select Highlights the value we searched for
End Sub
If the list is sorted, there is a much faster algorithm: binary search. The idea is to SPLIT
the list into two sub-lists and to check in which one of the two sub-lists is the value we
are searching for, and then the process should be repeated until finding the matching
record.
73
We will use the same data from 5.4 (please note that in the example 5.4 was not
required that the input list is sorted and we did not used that fact).
Example 5.5: Let us name the first row as beg (from beginning), the last row as tot
(from total, which is calculated in cell C3). After entering my_value and checking in
those two points, the next step is to check in the mid-point which is calculated as
(beg+tot)/2 and we will take the integer value. Next, check if the search is over. If it is
not, my_value could be either in the left or in the right interval. If it is less than value in
the mid_point , we will search the left interval: (beg, mid_point) placing now that
mid_point=tot and start the loop over, else, new beg =mid_point and the new interval for
searching is (mid_point, tot). We placed a counter just in case to stop execution if the
my_value is not found! (Any type of the loop statement can be used)!
tot = Range("C1")
Dim my_value As Single
my_value = InputBox("Please enter the value")
If Cells(beg, 1) = my_value Then
Cells(beg, 1).Select
Checking the first and last point
Exit Sub
End If
If Cells(tot, 1) = my_value Then
Cells(tot, 1).Select
Exit Sub
End If
MY_max = Range("C1")
For cc = 1 To MY_max
The main iterative loop: We put
Mid_point = Int((beg + tot) / 2)
limit for iterations to be the
If Cells(Mid_point, 1) = my_value Then
number of elements in the list.
Cells(Mid_point, 1).Select
Exit Sub
End If
If my_value < Cells(Mid_point, 1) Then
tot = Mid_point
Else
beg = Mid_point
End If
Next
If cc > MY_max Then MsgBox "Not found after" & cc & " iterations"
End Sub
74
Example 5.6: We will apply the idea of the binary search to find one zero of the
continuous function F(x) in the interval [a, b], where a<b. The method is also known as
Halving the Interval. In the Figure 5.6 we have two possible scenarios: in the left side,
there is one zero (or an odd number of zeroes) and, algebraically, condition is
F(a)*F(b)<0. In the right side of the figure, we are captioning two zeroes (or no zeros)
and we have F(a)*F(b)>0. Conclusion: good selection means that F(a)*F(b) <= 0 (=
zero only if we are so lucky to correctly guess the zero in one of the edges). In reality,
F(c) could be very close to zero, but in many cases never EXACTLY =0 and we will
always stop the process either if we run out of the pre-selected number of iterations or if
the ABS(F(x)) < epsilon, where the epsilon is very small number, like 10^(-6)! Algorithm
is the same as for the binary search. After finding good interval, we are calculating c=
(a+b)/2 and checking if F(c) is the solution. If yes, we are done, if not, just check if
f(a)*f(c) <0, if yes, the new interval is (a, c), else the new interval is (c, b). Do not forget
to put both stoppers, as described above!
a
Figure 5.6: Possibilities with choosing the interval [a, b]. In the left side, after halving the
interval, c =(a+b)/2 will become the new a. On the right we need to change the interval (a,b)!
Figure 5.7: Input/output data after program execution. Value zero in C3 shows the function
value for x=0 (in E1). After entering an interval (value for a in C2 and for b in C3) we can see if
the F(a)*F(b)<0 (program is not able to see but to calculate it!
75
76
One of the common problems when people do data entry is to have entered duplicates.
Very often, duplicates happen when a person takes a break or a phone call and then
continues to do data entry or if several people are doing data entry without the good
plan when dividing the material.
Eliminating duplicates in the data is possible using Excel itself (option Remove
Duplicates, figure 5.8). Only issue in this case is that program is not showing WHICH
DATA were duplicates.
Figure 5.8: The DATA tab contains the button for Remove Duplicates option. Before using this option,
highlight the data set. Please note that this screen-shot is from the Excel program in the Office 2010
suite. For all our VBA examples we did not find differences between Microsoft Office versions (2007 vs.
2010), but there are differences in several Excel wizards (like when using the Pivot Table, Solver).
Example 5.7: Create a program to find duplicates in a list of data. After that, user may
decide to delete the duplicates or not. Suggested solution uses ForNext loops, but
programmer can use other loops instead. Input screen with the list is presented in
Figure 5.9. Cell D1 is used to count the number of elements in the list, while the cell D2
will be used to store the number of duplicates. In the column B, program will indicate
duplicates, while the list of indexes where are duplicates will appear in the column C. If
designer decides to eliminate duplicates, the original list (with duplicates) will be copied
into column F.
This program has several
characteristics: Vectors X and Y are dimensioned
to have max 100 elements each, which can be
easily changed in practice using redefining
option; program uses Cells(r,c) function to read
and write data in the worksheet; to assign the
value for the variable choice, we used the special
Figure 5.9: Input data
msgbox with buttons to assign the value as
with counters in D1
vbYes or vbNo; probably, the most important
(function visible in the
idea is to use the counting loop backwards when
Formula Bar) and in D2
deleting elements from the list (why?); finally,
and button to run VBA
swapping is used with a temporary variable,
code.
temp.
77
Sub duplicates()
tot = Range("D1")
Dim x(100), y(100)
For i = 1 To tot
x(i) = Cells(i, 1)
Next
k=1
For i = 1 To tot - 1
For j = i + 1 To tot
If x(i) = x(j) Then
y(k) = j
Finding duplicates by comparing ALL
Cells(j, 2) = Cells(j, 1)
elements to elements with higher
k=k+1
indexes (similar idea was used for
j=j+1
sorting)!
End If
Next
Next
For i = 1 To k 1 Putting the duplicates in the column C
Cells(i, 3) = y(i)
Next User decides what to do with duplicates (now the duplicates are in the column C)
choice = MsgBox("Delete duplicates?", vbYesNo, "Decision")
If choice = vbNo Then Exit Sub
For i = 1 To tot
If user decides to eliminate duplicates,
Cells(i, 6) = x(i)
program will use counting loops with
Next
backwards counting and swapping elements
For cc = tot To 1 Step -1
to fill the space after removing duplicates.
For rr = Cells(2, 4) To 1 Step -1
The code is continued on the next page
If cc = y(rr) Then
Cells(cc, 1).Select
Selection.ClearContents
For nn = cc To tot
temp = Cells(nn + 1, 1)
Cells(nn, 1) = Cells(nn + 1, 1)
Cells(nn + 1, 1) = temp
Next
End If
Next
Next
End Sub
78
Figure 5.10: Program found two duplicates, indicated in columns B and C (left). User decided to
eliminate them (right). Original list with duplicates is now in column F, while the list without
duplicates is in column A. Hint: it is not necessary that the duplicates be next to each other!
Problems:
1. Using the Bubble sort, order elements in the descending order! How many
instructions you need to change?
2. Solve the Bubble sort using IF and GOTO statements instead of using Do Until
loop (which is used in the example 5.1).
3. Solve the Bubble sort using Do While loop instead of using Do Until loop (which
is used in the example 5.1). Hint: Be careful, if using an infinite loop, you will
need to create the correct EXIT to stop it!
4. Modify Example 5.5 with writing the row number where the value we searched for
was found
5. Modify Example 5.5 using other loop control (Hint: make at least two exit criteria
since it is possible that the value we are looking for is maybe missing!)
6. Show that x=(a+b)/2 puts x in the middle of the interval [a, b]. (Hint: Easy)
7. Some authors suggest to divide the interval (A, B) not in half (midpoint = (A+B)/2,
like in the Example 5.6) but in the ratio: 1/3 and 2/3 based on the function values
in the starting points! For example, if f(A)=4 and f(B)= -13, then zero might be
closer to A than to B!
a. Proof that X=(2*A+B)/3 locates the point X closer to A, while Y=(2*B+A)/3
is the point closer to B
79
b. Change the halving algorithm into third-ing one by choosing which third
to use in every step!
c. Discuss possible savings on steps and execution time comparing your
solution for 6.b and the example 5.6 (use the same function and the same
interval when comparing!)
8. Modify the code in example 5.7 to find how many iterations you needed for a
selected interval!
9. After solving the previous problem, try to experiment with changing epsilon and
the number of iterations!
10. Solve the equation: 6-3.5*X-3.5*X^2+X^3 using different starting intervals
11. Solve the equation: 1+2*X+3*X^2+4*X^3+5*X^4+6*X^5 using different starting
intervals
12. Can you automate the thinking process used in two previous problems to cover
all values for x?
13. Make a program to try the algorithm developed in problem 12!
14. Another method to find a zero of the given function used in the numerical
mathematics is named after one of the most famous mathematicians and
physicists: Isaac Newton. His idea was to construct the tangent in a point and
then to find where this tangent cuts the x-axis, check the function value in that
point and continue constructing tangents until the function value in a point will be
smaller than given epsilon! The final value for x is accepted to be a zero of the
function (Hint: Difficult code).
15. Discuss eventual problems when using halving method for finding a zero of a
function!
16. Discuss eventual problems when using Newtons method (described in Problem
11) for finding a zero of a function!
17. Create list of 30 random numbers, multiply by 1000 and round them. Copy them
and save special as Values! Manually replace few of them to create duplicates.
Run the program with eliminating duplicates. Run the built-in Excel solution.
Compare results!
18. For finding duplicated in a list you may use the option under Conditional
Formatting! Find the option and try it! It is a visual solution and it is not
recommended for the long lists.
80
To draw a line, programmer will select two points in the coordinate system and the line
will connect them.
Please try the next code:
Sub trial_line()
Set My_line = Worksheets("Sheet2").Shapes.AddLine(0, 100, 200, 100)
End Sub
Figure 6.2:
Before (left)
and after
clicking the
button
Example 6.1: Create a coordinate system and put short lines indicating scale. In this
example, we are creating a new worksheet (in
the instruction Set t=) and the lines (shapes)
are creating in that sheet. We used idea to put
the coordinate system in (100,100). The
ForNext loop is used to create a scale on both
axes.
Figure 6.3: Coordinate system created using the sub
test_coord(). The program is presented in Example 6.1
(above) and the shape is in a worksheet with the white
colored background.
81
Sub test_coord()
Dim t As Worksheet, sh As Shape
Set t = ActiveWorkbook.Worksheets.Add
Create axes
Set sh = t.Shapes.AddLine(0, 100, 200, 100)
Set sh = t.Shapes.AddLine(100, 0, 100, 200)
Create dividers for the scale
For i = 1 To 10
Set sh = t.Shapes.AddLine(i * 20, 95, i * 20, 105)
Set sh = t.Shapes.AddLine(95, i * 20, 105, i * 20)
Next
End Sub
Based on this selection, one unit is 20 pixels (Figure 6.3).
Next, we would like to introduce the algorithm to transform data from regular
coordinate system into this one for presentation purposes. To transform the coordinates
for individual points into this coordinate system, programmer can use a simple set of
rules:
1. For X coordinate: add 100
2. For Y coordinate: multiply by (-1)
and add 100
Example 6.2: Draw lines from the
center of the coordinate system to points
P1(20, 40), P2(-20, 40), P3(-20,-40) and
P4(20,-40).
The program code:
Figure 6.4: Before preparing the code,
Dim t As Worksheet, sh As Shape
coordinates are transformed in the worksheet.
Set t = ActiveWorkbook.Worksheets.Add
'Creating coordinate system (reusing the problem 6.1)
Set sh = t.Shapes.AddLine(0, 100, 200, 100)
Set sh = t.Shapes.AddLine(100, 0, 100, 200)
For i = 1 To 10
Set sh = t.Shapes.AddLine(i * 20, 95, i * 20, 105)
Set sh = t.Shapes.AddLine(95, i * 20, 105, i * 20)
Next
'Hint1: For drawing a line use two points with: (start1, end1, start2, end2)
'Hint2: Coordinates are transformed in worksheet FourCorners (Figure 6.4)
Sheets("FourCorners").Select
Set sh = t.Shapes.AddLine(100, 100, Range("L3"), Range("M3"))
Set sh = t.Shapes.AddLine(100, 100, Range("L4"), Range("M4"))
Set sh = t.Shapes.AddLine(100, 100, Range("L5"), Range("M5"))
Set sh = t.Shapes.AddLine(100, 100, Range("L6"), Range("M6"))
End Sub
82
Example 6.3: Draw the function y=Integer(x). It looks like a steps function!
Coordinates for seven points for this function are presented in the Figure 6.6.
Figure 6.6: Original and
transformed coordinates for
the INTEGER (X) function.
Values are multiplied by 20
to fit into our new
coordinate system)
After running the code (below), the function is presented with white background in
Figure 6.7. Please note that the code for the
program Int_Steps reuse programs presented in
Examples 6.1 and 6.2.
Sub Int_Steps()
Dim t As Worksheet, sh As Shape
Set t = ActiveWorkbook.Worksheets.Add
Set sh = t.Shapes.AddLine(0, 100, 200, 100)
Set sh = t.Shapes.AddLine(100, 0, 100, 200)
For i = 1 To 10
Set sh = t.Shapes.AddLine(i * 20, 95, i * 20, 105)
Set sh = t.Shapes.AddLine(95, i * 20, 105, i * 20)
Next
Figure 6.7: Integer (step)
The function got points from worksheet: step
function
Sheets("step").Select
For p = 1 To 7
Set sh = t.Shapes.AddLine(Cells(p + 1, 5), Cells(p + 1, 6), Cells(p + 1, 7), Cells(p + 1, 8))
Next
End Sub
83
To be able to use different colors and to apply different styles of line, add arrows, etc.,
we will first introduce the WithEnd With block option. This block statement allows user
to add any number of characteristics needed in the design.
Let us start with using colors. Colors are represented as combination RGB (Red, Green,
Blue). The same idea is also used in many projecting systems during presentations in
classrooms or halls. Reminder: in the chapter 2 we already mentioned the RGB color
scheme (Example 2.2).
From the VBA Help menu we have: Application methods and properties that accept a
color specification expect that specification to be a number representing an RGB color
value. An RGB color value specifies the relative intensity of red, green, and blue to
cause a specific color to be displayed.
If user will not add the color option, all drawing will appear in the default color which is
light blue (typically for Windows 7).
Color
Red Value
Green Value
Blue Value
Black
Blue
255
Green
255
Cyan
255
255
Red
255
Magenta
255
255
Yellow
255
255
White
255
255
255
More than just a color, inside the With block, user can design many different
characteristics of shapes.
Example 6.4: Create a solid green line!
Sub green()
With Worksheets("Sheet6").Shapes.AddLine(10, 10, 250, 250).Line
.DashStyle = msoLineSolid
.ForeColor.RGB = RGB(0, 255, 0)
End With
End Sub
In this solution, people may complain about the
weight of the line. This problem will be discussed in
the next example.
Figure 6.8: A green line
84
Example 6.5: Create the INTEGER function using the thicker line and present the
function in black color.
We are reusing the first part of the
program from the problem 6.3. The
code is very similar, but we needed to
change the option for adding a
worksheet, but rather to use the
existing one giving the fixed name, in
this example it is S16. More than that,
we are changing the With End with
block by adding Weight =3 and
Fore.Color.RGB=(0,0,0) which
generate a thicker black line for the
function. More examples with With
End With block later in this chapter.
Figure 6.9: INT function in
black color
Sub Int_Steps_color()
Dim t As Worksheet, sh As Shape
Set t = Worksheets("S16")
Set sh = t.Shapes.AddLine(0, 100, 200, 100)
Set sh = t.Shapes.AddLine(100, 0, 100, 200)
For i = 1 To 10
Set sh = t.Shapes.AddLine(i * 20, 95, i * 20, 105)
Set sh = t.Shapes.AddLine(95, i * 20, 105, i * 20)
Next
Sheets("step").Select
For p = 1 To 7
With Worksheets("S16").Shapes.AddLine(Cells(p + 1, 5), Cells(p + 1, 6), Cells(p + 1, 7), _
Cells(p + 1, 8)).Line
.DashStyle = msoLineSolid
.Weight = 3
.ForeColor.RGB = RGB(0, 0, 0)
End With
Next
End Sub
Example 6.6: With a small change in the WithEnd with block, we can create
function line in a rainbow colors (only changed part of the program is presented
below):
85
For p = 1 To 7
r=0
g=0
b=0
If p = 2 Or p = 6 Then g = 255
If p = 3 Or p = 5 Then r = 255
With Worksheets("S17").Shapes.AddLine(Cells(p + 1,5), Cells(p + 1,6), Cells(p + 1,7), _
Cells(p + 1,8)).Line
.DashStyle = msoLineSolid
.Weight = 3
.ForeColor.RGB = RGB(r, g,
b)
End With
Next
End Sub
Hint: the underscore at the
end of the line for the
statement Withmeans that
we are continuing the
statement in the next line.
Example 6.7: It is simple to create a polygon line. If you will close it (see below),
system will fill it with the default color (for not
filled polygon use the addLine shapes, use
ideas from Examples 6.2 to 6.6). We selected
a diamond shape using original points (-50,
0), (0, 50), (50, 0) and (0,-50) and translated
into drawing coordinate system introduced in
Example 6.1. The transformed values of the
points are presented in the matrix Diamond
(see the special DIM statement used in this
example).
Figure 6.11: Diamond
created using the code in
example 6.7
86
Sub poly( )
Dim Diamond(1 To 5, 1 To 2) As Single
'Diamond has 4 corners
'The fifth one is repetition of the first corner to be filled
'In this solution the first index is the point indicator: 1,
e.g. P(1,x) and P(1,y) represent point P
Diamond(1, 1) = 50
Diamond(1, 2) = 100
'It means that the first point has coordinates (50,100)
Diamond(2, 1) = 100
Diamond(2, 2) = 50
Diamond(3, 1) = 150
Diamond(3, 2) = 100
Diamond(4, 1) = 100
Diamond(4, 2) = 150
Diamond(5, 1) = 50 'Last point has same coordinates as first
Diamond(5, 2) = 100
Set mydocument = Worksheets("Sheet1")
mydocument.Shapes.AddPolyline Diamond
End Sub
Please note: to see all available (built-in) shape objects (Type), refer to the VBA Help
under keyword: Shapes Objects or MsoAutoShapeType Enumeration.
The next examples were tested and produced wished shapes. Probably, reader will
choose one or two to see the figure sizes and colors. In all examples, the figure sizes
(position and the area covered by the figure), are always given with four values Left,
Top, Width, Height, using the addShape method:
expression.AddShape(Type, Left, Top, Width, Height)
Example 6.8:
Sub trialR()
'Fancy Right triangle based on an idea from the VBA help
Set myDocument = Worksheets(1)
With myDocument.Shapes.AddShape(msoShapeRightTriangle, _
90, 90, 90, 50).Fill
.ForeColor.RGB = RGB(128, 0, 0)
.BackColor.RGB = RGB(170, 170, 170)
.TwoColorGradient msoGradientHorizontal, 1
End With
End Sub
87
Example 6.9:
Sub trialT()
'Blue trapezoid
Set myDocument = Worksheets(1)
With myDocument.Shapes.AddShape(msoShapeTrapezoid, _
90, 50, 50, 60).Fill
.ForeColor.RGB = RGB(0, 0, 256)
.BackColor.RGB = RGB(256, 0, 0)
End With
End Sub
Example 6.10:
Sub trialS()
'Red Sun
Set myDocument = Worksheets(1)
With myDocument.Shapes.AddShape(msoShapeSun, _
90, 50, 50, 60).Fill
.ForeColor.RGB = RGB(256, 0, 0)
.BackColor.RGB = RGB(0, 0, 0)
End With
End Sub
Example 6.11:
Sub trialD()
'Purple Donut
Set myDocument = Worksheets(1)
With myDocument.Shapes.AddShape(msoShapeDonut, _
160, 250, 250, 160).Fill
.ForeColor.RGB = RGB(256, 0, 256)
End With
End Sub
Example 6.12:
Sub trialW()
'Yellow Wave
Set myDocument = Worksheets(1)
With myDocument.Shapes.AddShape(msoShapeWave, _
160, 250, 250, 160).Fill
.ForeColor.RGB = RGB(256, 256, 0)
End With
End Sub
88
Problems:
1. Watching the figure 6.4, find a solution using just two lines instead of 4!
2. If you do not want to use graphics, Excel offers variety of drawing options using
the tabular options for the functions and Scatter (XY graph). Draw at least 3
drawings using the Scatter!
3. Try to produce a simple cartoon (movie based on changing the location of an
object)
4. Using ideas from the Problem 3, try to produce a cartoon with using several
drawing objects (from examples 6.8 to 6.12)!
89
Using this program find the LCD for two numbers! After finding the GCF, both input
numbers are divisible by the GCF and the product of all factors is the LCD!
The code is below. The code is more user friendly than the original code for the GCF. In
addition, it offers the values for factorization (if user needs to use the fractions in a
calculation).
90
Sub LCD( )
Dim I, J As Integer
Range("A2:B2") = " "
Range("C2:C5") = 1
I = InputBox("Please enter the first integer")
J = InputBox("Please enter the second integer")
Cells(2, 1) = I
Cells(2, 2) = J
L1:
If I > J Then
I=I-J
GoTo L1
End If
If J > I Then
J=J-I
GoTo L1
End If
Cells(2, 3) = I
Cells(3, 3) = Cells(2, 1) / I
Cells(4, 3) = Cells(2, 2) / I
Cells(5, 3) = Cells(2, 3) * Cells(3, 3) * Cells(4, 3)
Cells(5, 2) = "LCD="
End Sub
91
Problem 2: Prime Numbers. There is given one natural number in the cell A2. Find if
this number is the Prime Number!
Hints:
1. Prime number is divisible ONLY by itself or 1 without a remainder! Please locate
the appropriate statement in the program: If (N / J) <= Int(N / J) Then in which
we are using the INT function (this function cuts the decimal part in division!)
2. Algorithm to find if the number is Prime is often used for testing the speed of the
computer and also to compare the programmers performances!
Sub prime_loop()
Range("A2:C2") = " "
N = InputBox("Please enter an Integer")
Cells(2, 1) = N
If N <= 0 Then
MsgBox "wrong input"
Range("A2:C2") = " "
Exit Sub
End If
If N <= 3 Then
Cells(2, 2) = N
Cells(2, 3) = "Yes"
Exit Sub
End If
For J = 2 To N - 1
If J > N Then Exit Sub
If J = N - 1 Then
Cells(2, 3) = "Yes"
Exit Sub
End If
If (N / J) <= Int(N / J) Then
Cells(2, 2) = J
If J <= N Then Cells(2, 3) = "No"
Exit For
End If
Next
End Sub
A bit faster solution can be organized by noticing that, if a number N is not the prime
number, it should be presented as N=X*Y . Then, one of numbers X or Y must be
smaller than the square root of N, or X=Y=N. Hint for the proof: Let K to be any
positive number. In this case, X*Y=(N/K)*(N*K). If 0<K<1, then N*K <N; if K=1,
X=Y=N; finally, if K>1, N/K <N.
After this modification, the program execution is shorter (but the code is not!)
Sub prime_loop_sqr()
Range("B2:C2") = " "
N = Cells(2, 1)
If N <= 0 Then
MsgBox "Wrong input"
Exit Sub
End If
If N <= 3 Then
Cells(2, 3) = "Yes"
Exit Sub
End If
J=2
Do While J <= Sqr(N)
If (N / J) <= Int(N / J) Then
Cells(2, 2) = J
Cells(2, 3) = "No"
Exit Sub
End If
J=J+1
Loop
Cells(2, 3) = "Yes"
End Sub
93
Problem 3: Calculate the Geometric mean for the absolute values of the given set of
N numbers. By definition, the geometric mean is Nth root of the product of all N given
numbers. Lets put P to be the product of all given numbers, and Nth root can be
presented as power to (1/N), G=P^(1/N), for N<>0.
Algorithm can first calculate P and then take Nth root, or it can take Nth root from all
number and then multiply results (which is a bit slower execution).
Input is in the column A and the number of input values is calculated in the cell C1
(Figure 7.1.5). Code associated to the button is below:
Sub GM()
'Enter numbers in the column A. N is calculated in C1 and the
'Geometrical Mean will be in D1
Dim m, p, temp As Single
n = Range("C1")
If n = 0 Then
MsgBox "Not defined"
Exit Sub
End If
If n = 1 Then
Cells(1, 4) = Cells(1, 1)
Exit Sub
End If
p=1
Figure 7.1.5: Input area. Result is in the cell D1.
Note: Alternative solution will be by using LN(x)
For i = 1 To n
and Exp(x) functions:
p = p * Abs(Cells(i, 1))
Next
temp = (1/n) * Log(p)
Cells(1, 4) = p ^ (1 / n)
Cells(1, 4) = Exp(temp)
End Sub
Sub HM()
n = Range("C1")
If n = 0 Then
MsgBox "No input data"
Exit Sub
End If
sr = 0
For m = 1 To n
If Cells(m, 1) = 0 Then
MsgBox "Wrong Input Data"
Exit Sub
End If
sr = sr + 1 / Cells(m, 1)
Next
H_Mean = n / sr
Cells(1, 4) = H_Mean
End Sub
Problem 5: Calculating the Factorial for the given number: n (user will input the value
during program execution). Please note that 0!=1 (by definition), 1!=1 and 2!=2.To allow
calculations for bigger numbers, declare the input value n as the long integer!
95
96
Figure 7.1.8.
Input area for the
Fibonacci
program
Several output values: for N=25, F(25)=75025, for N=40, F(40)= 102334155 and N=46,
F(46)= 1836311903.
Let us discuss several situations based on the wrong data entry:
1. If the user will enter symbol different than integer for N, system will send a
message: Type mismatch Run-time error 13.
2. If user will enter negative number, the message will be Subscript out of range,
Run-time error 9.
3. If user will put F(50), system will send a message Overflow presented in the
Figure 7.1.9.
In all of these cases user will need just to click the END button in the error message
window and to enter correct value for N (no need to Debug if error is based on the
wrong Input).
97
Sub Long_Click()
N = Range("C3")
Dim f(100) As Long
f(0) = 0
f(1) = 1
For k = 2 To N
f(k) = f(k - 1) + f(k - 2)
Next
Range("C4") = f(N)
End Sub
Instead of letting VBA to show the error message, you can add a code to test the input
data before execution. The next code could be entered at the beginning of the program,
after assigning the value from C3 to N and before the line for DIM:
tt = Application.IsNumber(n)
If tt = False Or n < 0 Then
MsgBox "Wrong Input"
Exit Sub
End If
98
Figure 7.2.1: user will enter coded text in a textbox, program will paste it in the cell A1 and the
decoded message will appear in row 12. Note: Receiving cell A1 MUST be formatted as Text in Excel!
99
Sub decoder()
Dim My_code(30) As String
Dim my_string, coded, decoded As String
coded = InputBox("Please enter coded text")
Cells(1, 1) = coded
For c = 1 To Cells(1, 6)
My_code(c) = Cells(10, c)
Next
my_string = Range("A1")
tot = Len(my_string)
For c = 1 To tot Step 2
pos = (c + 1) / 2
my_char = Mid(my_string, c, 2)
cc = 1
Figure 7.2.2: Input box with coded text (up) and the coded
Do Until my_char = My_code(cc)
text in A1 and the decoded text will be in the row 12 (next
cc = cc + 1
figure). Warning message in a shape of little green triangle in
Loop
the cell A1 is Excel message warning to user that the number
decoded = Cells(11, cc)
was entered as a text.
Cells(12, pos) = decoded
Next
End Sub
100
from decimal into hexadecimal notation. In this case using Scientific Calculator will be
very slow and it is with a big chance to make a mistake: user will need to manually save
the results by typing them into a list. After making this translation table, user can make
the tables for ADDITION and MULTIPLICATION in hexadecimal code if needed.
Lets enter numbers between 1 and 64 in the column A and fifteen hexadecimal digits
from 1 to 9 and letters A to F in the column B. Program takes the values from the
decimal list and places in the column C in hexadecimal code. Figure 7.2.4 represents
the upper left corner of the spreadsheet, before and after clicking the button to run the
program (by choosing I=1 to 5 in the loop, there will be the first 64 integers translated).
Public Sub DEC_HEX()
'PROGRAM CONVERTS DECIMAL INTO HEXADECIMAL
For I = 1 To 5
For RR = 1 To I * 16
If (Cells(RR, 1) >= (I - 1) * 16) And (Cells(RR, 1) <= (I - 1) * 16 + 9) Then
Cells(RR, 3) = Cells(RR, 1) - (I - 1) * 6
End If
If Cells(RR, 1) >= 10 + (I - 1) * 16 And Cells(RR, 1) <= 15 + (I - 1) * 16 Then
Cells(RR, 3) = (I - 1) & Cells(RR - 16 * (I - 1), 2)
End If
Next
Next
End Sub
Solution 3.a: Using the COUNTA(A:A) and CELLS(r,c) functions make this solution to
be the simplest. Input sheet is presented in Figure 7.3.1, while the output sheet is in
Figure 7.3.2 showing the use of COUNTA Excel function.
The program is presented below:
Sub Button1_Click()
last_name = Range("F4")
first_name = Range("F5")
Sheets("My_List").Select
next_row = Range("K1") + 2
Cells(next_row, 1) = last_name
Cells(next_row, 2) = first_name
Sheets("Input Page").Select
Range("F4") = " "
Range("F5") = " "
End Sub
Solution 3.b: Some people will claim that this will be the most useful solution since it is
also adding the order numbers in the receiving sheet. Like in the previous solutions, it is
not using any loop structure. Idea is to create a next order number for each input while
placing the data into the receiving sheet. These created order numbers are used to
generate the row numbers where to copy data! As usual, after transferring data,
program will clean the input area by placing the blanks.
Input sheet is in Figure 7.3.1. and the output sheet is in Figure 7.3.3. Program is
assigned to a button for its execution.
Figure 7.3.3: Received
two rows of data
Sub Button3_Click()
last_name = Range("F4")
first_name = Range("F5")
103
Solution 3.c: Readers will find this attempt to be the most interesting and unusual
solution since it uses the INFINITE LOOP! Using the Excel function ISTEXT program is
checking if the content of a cell in the output sheet is text. If there is no text there, the
new data can be placed! Please note that NOT ALL Excel functions used in worksheets
can be used in this type of instruction:
Var_name= Application.WorksheetFunction.worksheet_function(range)
Also, the text Application.WorksheetFunction. will not become in blue color when this
type of instruction will be entered
Condition is made that this loop might run indefinitely,
in the VBA program.
but it will actually stop the first time when the content of
The code is next (continued on
the cell addressed as (my_row,1) is not text! That way,
the next page):
Sub is_not_text()
last_name = Range("F4")
first_name = Range("F5")
Sheets("List").Select
my_row = 1
Do While my_row >= 1
system will find the first available row for entering the next
input: last and first name. Also, locate the instruction for
leaving the loop (Exit Do).
104
tt = Application.WorksheetFunction.IsNonText(Cells(my_row, 1))
If tt = True Then Exit Do
my_row = my_row + 1
Loop
Cells(my_row, 1) = last_name
Cells(my_row, 2) = first_name
Sheets("Input Page").Select
Range("F4") = " "
Range("F5") = " "
End Sub
Solution 3.d: This solution uses built-in Excel property that if no value is entered in a
cell, the value in this cell will be assigned to be a zero! Please note: All first five lines
and the last four lines are the same as for the solution 3.c. Only the new code is
presented below:
my_test = 1
Do Until my_test = 0
my_test = Cells(my_row, 1)
my_row = my_row + 1
Loop
Cells(my_row - 1, 1) = last_name
Cells(my_row - 1, 2) = first_name
Reader may like this solution since it is short and elegant: it does not use the Exit from
the Loop instruction but uses the properties of the variable: my_test!
Questions:
1. Solve this problem using FORNEXT Loop (hint: you may wish to use counter
like in solution 3.a)
2. Solve this problem using DO While Loop (see hint with #1)
3. Solve this problem using DO Until Loop (see hint with #1)
4. Modify the solution 3.a. to add order numbers for each row in the column A.
105
Figure 7.4.1:
Clerks screen.
call the customer to finalize the deal. Figure 7.4.1 shows one possible design for the
input screen. This worksheet has imbedded three Excel IF statements in cells E12, E14
(checking if there are no more than 330 days before travelling) and in D17 (to check if
the Return date is after the Departure date). In the range J1:J7 are time options to
select for Departure and Return flights (in this example we suggest to use the Combo
Box from the ActiveX toolbar (why?) and for the ticket type (data in the range L1:L3 we
suggest Combo box from the Form toolbar). Since more people look for the round trip,
model suggests clicking only if the one-way was requested.
After entering data, if there are no problems with dates, all data should be transferred
into the next sheet (when implemented, it should go directly to agents computer). This
transfer can be realized in several ways. We suggest the simplest solution by using
recordable macro to do it. In this case, program will first insert a new line in the sheet 2
and then copy data into this newly inserted row (as mentioned in the case 3). This
program reuses a macro which is assigned to the other button to delete data. If there is
a problem that clerk sees, clicking the If something. Button will just eliminate all data
without copying them (Hint: it is possible to insert a third button to delete only choices
without deleting D5:D8).
106
Solution:
Figure 7.4.2:
Receiving screen.
Sub Transfer_search_prices()
Sheets("Sheet2").Select
Rows("3:3").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Sheets("Sheet1").Select
To continue code in the next
Range("D5:D16").Select
line, VBA uses a combination:
Selection.Copy
space underscore
Sheets("Sheet2").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=True
Sheets("Sheet1").Select
Call reset_all
End Sub
Sub reset_all()
Range("D5:D16").Select
Selection.ClearContents
Range("D5").Select
End Sub
Questions:
1. Rename all sheets and change the code to match it (do not forget to test it)
2. Create other solution for transferring the data into sheet2
3. Create the third button based on the hint about partial deletions of data
4. Which column(s) and functions will be necessary to add to in the sheet2 (after
column M) to enable managerial reports?
107
2. Create the IF function to manage the received cash for a payment: assuming
only cash transactions, customer could give exact change, more or even less $.
Calculate the amount to be returned (change) in all cases. After that, to make a
system ready for the new customer all previously entered data should be
eliminated (but do not eliminate the formulas). As mentioned in the Case
description, even if you do not like this idea create this button just for fun. You
need to create a button (button label: New order) and record the appropriate
macro. You can use the Button object from the Form Controls toolbar. Hint:
Select Developer, locate Controls ribbon and choose the Insert option; Insert will
offer: Form Controls and Active X controls. It is easier to use the Form controls if
you want to record a macro.
3. To keep the orders (sales) and cash management history we suggested two
ideas in the previous cases: to create a macro using just recording or to make a
macro using the VBA coding! After deciding which data we need to generate
necessary information for the management. To create a heading, the easiest way
is to copy elements from the sheet and transpose them into the first row. If using
the template sheet, the cell addresses will match the ranges in this explanation.
After copying the range C10:C15, use Transpose option before pasting on the
Orders History sheet. The next problem is to make a macro to copy data (values
from range D10:D15) into different row after every transaction. Presented
solution uses the recordable macro to first "push" down the previous entry to
"make a room" for the next entry by always inserting a new row in row 3 (note
that row 1 has the main heading, and the row 2 working heading). Inserting a row
109
must occur before the copying the data. To insert a row, locate the combo box
below the Insert object under the Home ribbon and choose: Insert sheet
Columns. All steps are recordable if user will create button from the Form
Controls toolbar. After testing this button, user may delete button: New Order.
Using Excel functions COUNT(range) and SUM(range), designer could present the
"current" situation for the number of orders and the current grand total. Hint: since
designer cannot know the ranges in advance, it is possible to apply both functions to the
complete column. Only one condition is that functions are not in the same column which
is being examined. In this case, we can put functions in cells J2 and M2; in J2 put
=COUNT(A:A) and in M2 put =SUM(D:D). Note: Why the functions are presented in the
row 2, not somewhere below? Try!
Values from J2 and M2 will be used for the coding macros using VBA code.
After testing the previous macro, the only one reason why user could be unhappy is that
the transactions are presented in reverse order (the last transactions will appear at the
top of the list).
As suggested earlier, another solution will be using the VBA code. Name the sheet
where to copy: Orders History VBA. As before, developer will create a heading (range
C10:C15) first. The next problem is to make a macro to copy data (values from range
D10:D15) into different row after every transaction. One possible solution is by using the
VBA function: CELLS(r,c). As discussed in the Chapter 2, function CELLS(r,c) makes
connection between Excel and Mathematical notations for the cell addresses. Before
using the CELLS(r,c) function in the macro, values for r and c must exist as positive
integers (it allows designer to change the row or column numbers e.g. cell location
during the macro execution). As introduced before, the COUNT(range) function in Excel
counts number of NUMERICAL values in the range. If the first two rows are used for
headings, the initial value for COUNT(A:A) in the cell J2 is 0. It means that the first row
where we want to copy data into is 3, e.g. r=CELLS(2,10)+3. After the first order, the
value in J2 will become 1 and r will be 4, etc. One approach will be to record as much
as possible steps of a macro and to intervene with VBA only when needed (see the
code for the case 9: Improved Pizza Place. If you need to transfer many data and if they
are nicely organized ina row or in a column, instead of using several assign statements
we can declare (DIM) a vector and using a FORNEXT loop assign and transfer
values. This idea is useful if the number of values to be shipped is more than 4 (logic is
based just by counting lines of code).
110
Let us show this idea by creating a macro to copy all values for an order in the range
D4:D15, or in CELLS(r,c) notation it is (CELLS(4,4),CELLS(15,4)) using the vector
Keeper(12). Do not forget to use the DIM statement!
Note that the row is named new_row since we use the letter r for the row counter in the
first loop. The major part of the code is:
Dim Keeper(12)
For r = 1 To 12
Keeper(r) = Cells(r + 3, 4)
Next
Sheets("Orders History VBA").Select
new_row = Cells(2, 10) + 3
For c = 1 To 12
Cells(new_row, c) = Keeper(c)
Next
Notice that in the first part we collected data column-wise and we are distributing them
row-wise in the sheet Orders History. In this situation we transferred all calculated
data, which probably is not necessary in real situation, as we will change in the next
Case 6.
111
112
Figure 7.6.3: Heading for the Material management option. Hint: To better understand numbers, when
calculating the amount of the pizza material, the base unit is what is needed for the small pizza and the,
personal is 75%, medium is 200% and large is 400%. This material planning sheet is not precise enough
(not showing the type of pizzas, sodas and coffees (this is just a prototype).
Sub Pizza_Click()
If Range("D15") = "More Money, Please" Then
MsgBox "Bill not paid, collect more cash and then transfer"
Exit Sub
End If
The main part of the program is a recorded macro
Sheets("Order History").Select
Range("A3").Select
Selection.EntireRow.Insert
Sheets("Current Orders").Select
Range("D10:D16").Select
Selection.Copy
Sheets("Order History").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Sheets("Current Orders").Select
Range("C4:C9").Select
Application.CutCopyMode = False
Selection.ClearContents
Range("D14") = 0
Range("C4").Select
End Sub
The program for managing material is very similar (recorded macro, so will not print it
here).
113
Questions:
1. Prepare several ideas for the managerial reports based on the information
generated from this program.
2. Prepare several ideas how to use information generated in this program for a
marketing research or advertising activities.
3. Which statement or statements you need to put in the Main program to be able to
use the Material program in the main program?
The complete case (with the programs) is available upon request from the author.
114
Figure 7.7.1.
The Orders sheet is presented in Figure 7.7.2. Several Excel controls are applied. The
range N1:N11 is to be used for Combo box and it should not be visible during the
ordering process (to minimize the busyness of the sheet. There are two VBA programs
assigned to buttons (one for calculation the total amount to be paid and the other one
for transferring data to the managerial report).
115
Figure 7.7.2.
The program to calculate the total amount uses many elements of the VBA flow
controls: FORNEXT loops, Select Case, nested IF and very often CELLS(r,c) for data
transferring, MsgBox-es and Range(cell_address). Reader should not memorize the
programs instructions, but rather ideas used!
Sub amount_Click()
Dim prices(6)
Collecting data from the sheets Orders and the Arena Plan into the program
tt = Range("I5")
nt = Range("I7")
st = Range("I9")
Sheets("Arena Plan").Select
box_season = Range("B4")
lower_season = Range("B5")
For pp = 1 To 4
prices(pp) = Cells(pp + 5, 3)
Next
Sheets("Orders").Select
Checking the condition for seasonal tickets (not standing nor upper deck)
If tt = 1 And st > 2 Then
MsgBox ("Wrong seat selection for seasonal tickets")
Range("I5") = 0
Range("I7") = 0
Range("I9") = 0
End If
116
117
The Sold sheet is used by the program to check availability and also could be
used by the management to see which games are not selling good to give some
discounts, rebates or incentives.
Figure 7.7.3.
This sheet will give the sales history and can be used for a variety of calculations (grand
total, conditional totals per game, list by dates to follow when the tickets are mostly sold,
etc). We are leaving those additions to readers to continue the prototype.
Figure 7.7.4.
Note: To enhance the case, create another solution for the last program using the
vector for transferring data! How many rows of text will you save that way?
118
Sub Button6_Click()
Based on the sheet design, we sued the individual naming of all variables.
If you change design and put data in a consecutive cells, this program will be much
shorter by creating the appropriate vectors and using the loops for transferring data
tt = Range("I5")
nt = Range("I7")
Collecting data from the sheet
st = Range("I9")
Orders
dt = Range("e18")
am = Range("g17")
first = Range("e19")
last = Range("e20")
phone = Range("e21")
Sheets("Managerial Report").Select
new_row = Range("J1") + 2
Transferring data to the sheet
Cells(new_row, 1) = dt
Managerial Report
Cells(new_row, 2) = tt
Cells(new_row, 3) = st
Cells(new_row, 4) = nt
Cells(new_row, 5) = am
Cells(new_row, 6) = first
Cells(new_row, 7) = last
Cells(new_row, 8) = phone
Program moves back to Orders sheet
Cells(new_row, 9) = Cells(new_row, 2) - 1
to delete the transferred data and to
Sheets("orders").Select
check with the customer about
Range("I5") = 0
continued purchasing. If a customer
Range("I7") = 0
clicks the button Yes, his/her
Range("I9") = 0
personal data will not be deleted,
cont = MsgBox("More tickets", vbYesNo)
else it will be!
If cont = vbYes Then Exit Sub
Range("g17") = 0
Range("e19:e21") = " "
End Sub
119
Figure 7.8.1: Payroll system with color coordinated ranges: blue=relatively constant data, red= data
transferred from other sheets (Data-hr and periods), and green = formulas. This model is simplified
for learning purposes (only one tax and grouped other dues). The button Transfer and Calcs should
be executed when all data for the needed pay period are entered. Based on selected pay period,
program chooses the appropriate dates from the sheet periods and puts in cells E2 and G2.
The payroll process starts when user enters the number of hours for each employee
(Figure 7.8.2). Please notice that the individual data for an employee could be entered
anytime (and in any order), using three InpuBox-es (the first one is presented in Figure
7.8.2). After entering data, program will connect to the appropriate employees Emp_ID
and period and put data in the proper position (after that, the temporary data located in
the range D2:F2 will be deleted). Please note that both searches in this program are
sequential, which is making the program much simpler and it is acceptable for relatively
small number of records to be searched. Alternatively, reader can prepare a subroutine
120
for binary search to be called (two times) from this program to get better execution
speed when entering number of hours for all employees.
Figure 7.8.2: Input area for individual hours worked during the selected period.
Notice that data for Emp_ID = 2 are already entered and now we are entering data
for employee: 4 (not necessary to enter data in order by Emp_ID.
Program to enter number of hours for all employees (individually) is presented below:
Sub Button1_Click()
Range("D2") = InputBox("Enter Emp ID")
Range("e2") = InputBox("Enter Pay Period #")
Range("f2") = InputBox("Enter Number of hours for this period")
emp_ID = Range("D2")
Program has several error
tot = Range("L1")
detection points
maxper = Range("P1")
If emp_ID = 0 Or emp_ID = " " Then Exit Sub
If Range("E2") = 0 Or Range("E2") = " " Then Exit Sub
Manipulations with CELLS(r,c)
For rr = 5 To tot + 4
function help to avoid
If Cells(rr, 1) = emp_ID Then
transferring data via vectors
For cc = 2 To maxper + 1
If Cells(3, cc) = Range("e2") Then Cells(rr, cc) = Range("F2")
Next
End If
Next
Range("D2:F2").Select
Selection.ClearContents
End Sub
For readers not familiar with bi-weekly pay periods, based on a calendar year Excel
formulas (see the formula bar) will help to calculate the pay periods (please note that it
is possible that the first period goes over two calendar years). When using the Date in
Excel, designer needs to Format cells as the Date data type. After 26th period, the
formula is picking up 14 days over two years (e.g. in the cell C3 formula is =B28+14).
121
Program is presented on the next page. After that, user can click the button Delete all
existing which is actually creating a copy of a payroll and putting it in the new
worksheet created during the program execution.
122
Sub Payroll_Button1_Click()
Dim hh(100) As Single
ppn = InputBox("please enter the pay period number")
yy = InputBox("Please enter year")
Sheets("periods").Select
date_from = Cells(ppn + 2, yy - 2009)
Sheets("Data-hr").Select
n_emp = Range("L1")
For rr = 5 To n_emp + 4
hh(rr - 4) = Cells(rr, ppn + 1)
Next
Sheets("Payroll").Select
Range("G2").Formula = "=E2+14"
Range("j2").Formula = "=E2+15"
Range("C2") = ppn
Range("e2") = date_from
For rr = 5 To n_emp + 4
Cells(rr, 5) = hh(rr - 4)
Next
End Sub
As mentioned above, the last program in this case is a simple program to copy data in
the next blank Sheet (the sheet numbers will be Sheet1, Sheet2) depending how
many times the user needed to click the button to Delete existing data, but to actually
copy data. The last part of this program prepares the Payroll worksheet for the
calculations for the next period. User can change this button to copy the important part
of this worksheet (data for selected period) into another file for backup. This copying is
necessary since the personal data may change and in this case we cannot recreate the
old data (why?).
It is relatively simple to make another, more user friendly solution for this case by
adding one extra sheet (name it: Menu) with a simple Main menu on it. As we discussed
in Excel courses, designer can create menu by recording the Excel Macros, without
changing the automatically generated VBA code. When making menu, designer needs
to organize buttons from sheets to be back to Main sheet (not or leave the user in the
dead-end).
123
Sub Button2_Click()
Program needs to go to Data-hr sheet
Sheets("Data-hr").Select
to take the total number of employees
rr = Cells(1, 12)
(from the cell L12)
Sheets("Payroll").Select
Range(Cells(1, 1), Cells(rr + 4, 11)).Select
Selection.Copy
Sheets.Add After:=Sheets(Sheets.Count)
Cells.Select
ActiveSheet.Paste
After copying data into the next sheet, program will clean data in Payroll sheet
Sheets("Payroll").Select
Application.CutCopyMode = False
Range("C2").Select
Selection.ClearContents
Range("E2").Select
Selection.ClearContents
Range("G2").Select
Selection.ClearContents
Range("J2").Select
Selection.ClearContents
Range("E5:E19").Select
Selection.ClearContents
Range("c2").Select
End Sub
124
INDEX
& symbol, 43, 47, 48
=AVERAGE(B:B), 21
=COUNTA(A:A), 21
=SUM(10:10) , 21
Algorithm, 2, 3
Array (2 dimensional), 59
Assign Macro to a button, 8
ASSIGNMENT STATEMENT, 17
Binary search, 73, 74
Block IF statement, 37
Branching , 27
Break-even model, 42
Bubble Sort, 69, 70
Case Else, 46
CELLS(r,c) , 20
Challenges in programming, 5
Close file (input or output), 29
Code/coding 4, 6
Compile, 4, 6
Comment (put symbol and text will be green),29
Control Structures, 5,27
coordinate system for drawing, 83
Crammers rule, 60
Ctrl+: to input static time stamp, 23
Ctrl+; to input static date stamp, 23
Cycle / Loop, 3, 27
Data Types, 13 , 15
Declarations, 13
Decode a text, 99
Dijkstra, 28
DIM Statement, 13
DO UNTIL LOOP, 65
DO WHILE LOOP , 61
Do While Not EOF Loop, 44
Drawing colors (RGB table), 84
Drawing lines, 81
Drawing polygons, 86
Eliminate duplicates, 77
END IF, 37
END SELECT, 46
END SUB, 13
Excel macro, 8
Exit Do, 61
Exit For, 55, 92
Exit Sub, 38, 51
Explicit, 16
Expression.AddShape (), 87
Factorial function, 95
Fibonacci Numbers, 96
Finding a zero for a given function, 75
Flowchart, 3
FOR Next , 55
Limit of a function (calculating number: e), 63 (64)
FUNCTION PROCEDURES, 35
GCD, 90
GCF, 90
Geometric mean , 94
Go To Statement, 49
Goal Seek, 42
Harmonic mean , 94
Heap sort, 72
Hexadecimal Code, 101
IF Statement, 30
IFTHENELSE , 38
Infinite loop, 104
Input, 3
InputBox, 23
Integer(x) function, 83
Interpreter, 6
Interval "halving", 74, 75
Iteration , 27
LCD, (Least Common Divisor) 90, 91
LEN (), (string function), 99
Linking VBA modules with a worksheet, 16
Logical debugging, 4
Loops for Input/Output, 44, 61, 65
Loops in VBA program flow, 55
Machine language, 5
125
Mathematical notation, 2
MID(), (string function), 99
Modules in VBA, 9, 12
MsgBox, 23, 41
Nested IF, 40
Object.method 12
Object.property 11
Open file for input, 29
Open file for output, 29
Output, 3
Parallel Sort , 72
Parsing, 5
Pay period calculator, 122
Payroll Case, 120
Prime Numbers , 92
Print to file , 29
Procedure, 3
Procedures in VBA, 10
Program exe version, 6
Program Execution, 5, 6
Programming, 2
Pseudo-code, 3
RandBetween(a,b), 50
Read data file, 25
RANGE(cell_address), 18, 19
recording, 8
REDIM vector_name(variable_name), 58
Scripting, 6
Searching algorithms, 73
Select Case , 46
Selection , 27
Sequence , 27
Sequential search, 73
Sheets(name).select, 19
Sorting algorithms, 69
Source code, 6
String functions, 99
Structured programming, 28
SUB name (list) , 13
Temporary outputs, 4
Transferring Data, 102
Using combo boxes (Travel agency case), 106
Using String Functions, 99
Variables, 10
VBA Editor, 10
VBA, 8
WithEnd With , 86
Wrong data entries tests, 92, 93
126
127
128
Default Excel file extension is xlsx (Automatic!), but not good if using Macros in your
design!
When using MACROS in
your design, please be
careful to save your file
using the SAVE AS option
and choose the option:
Macro ENABLED
Worksheet!
File extension will be xlsm
(not xlsx)! Click the FILE,
then Save As and select
the location where you
want to save the file. Then
choose the file name and
type.
129