Jakov Crnkovic Introduction to Programming with Visual Basic for Applications (VBA)
Prof. Dr. Jakov Crnković
Introduction to Computer Programming With Visual Basic for Application
Introduction
This text is prepared for students who are taking the course in Informatics 2 at the University UDG, specializing at the Faculty for Information Systems and Technologies (FIST). In addition, this text will be used as a supporting material for students at the State University of New York (SUNY), School of Business, with concentration in Information Technology Management.
Prior to start using this book, student needs solid knowledge of Excel and Windows operating system. The major theme of this book is analyzing and designing simple models and applying the control structures to organize and execute programs in Visual Basic for Application (VBA) by means of Excel.
Typically, after this course students will continue programming using an object oriented language (Java or C++).
All programs that are presented in this textbook will be available on Web sites at both Universities. This course will be delivered as a hybrid course (partially online), and it assumes that students will need to do a great deal of work individually.
To be able to execute programs, students only need Excel 2007 (or 2010). An Internet connection will be used during the online part of the course and also to download selected programs and explanations.
Acknowledgements
The author would like to thank Prof. Dr. Veselin Vukotić, Davor Ćorić, Doc. Dr. Milica Vukotić and Mr. Žika Lazić for their longlasting support. In addition, my family members helped me a lot during the manuscript preparations; a special thanks goes to my son Marko Crnković, who tested majority of the programs.
0
Introduction to Programming with Visual Basic for Applications (VBA)
Chapter 
Page 

Introduction 
0 

Table of Contents 
1 

1 
What is programming? 
2 
Problems 1 
7 

2 
From Excel Macros to VBA code 
8 
Problems 2 
26 

3 
Program Flow and the Structured Programming (using IF and Select Case) 
27 
Problems 3 
54 

4 
Programming the Cyclic structures (Loops) 
55 
Problems 4 
68 

5 
Sorting and Searching 
69 
Problems 5 
79 

6 
Elements of Drawing in VBA 
81 
Problems 6 
89 

7 
Selected Cases (with solutions and/or ideas how to solve them) 
90 
7.1. 
Several algorithms from the number theory (Prime numbers, means, Factorial, Fibonacci) 
87 
7.2. 
Using String Functions 
96 
7.3. 
Transferring Data 
99 
7.4. 
Travel Agency Problem 
103 
7.5. 
The Pizza Place 
105 
7.6. 
Improved “Pizza” Place 
108 
7.7. 
The Basketball Arena Problem 
111 
7.8. 
Simple Payroll Model 
117 
Index 
125 

Appendices 
Hints for EXCEL 2003 Users 
127 
Hints for EXCEL 2013 Users 
128 
1
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! Let’s 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! Let’s put that the first number is the min and also the max of all numbers in the list. Probably it will be wrong ^{2} , but we will do it anyway! So, if the list of numbers is X(1), X(2), …X(n), let’s 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=3…n): 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, let’s compare with X(2), where X(2)=6
If X(2) > max, then max=X(2) If X(2)< min, then min=X(2)
Now, let’s compare with X(3), where X(3)=2
If X(3) > max, then max=X(3) If X(3) < min, then min=X(3) Etc.
in our example: 6 is >4, so max=6
in our example: 6 is not < 4, so min remain to be 4
in our example 2 is not >6, so max remain 6 in our example 2 is < 4, so new min is = 2
^{1} 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 pseudocode (Figure 1.2):
Figure 1.1: Simple flowchart
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
Figure 1.2: Pseudocode for the max/min example. Hints: pseudocode could be more descriptive, e.g. you can say: if the value of X(c) is greater than current value for max, then replace it with X(c) or more symbolic, like using c <= c+1 instead of saying to replace the current value of c with c+1. Even more than that, usually, programmer will just put the notation c=c+1, which represents an ASSIGNMENT statement in VBA which might look like a bit confusing at the moment!
In the Figure 1.1 we used common symbols for flowcharting. Recently, instead of drawing, majority of programmers will rather use the pseudocode, 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 language ^{3} . Computer will follow exactly what programmer (you) typed: because Computers are very, very stupid ^{4} .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 ^{}^{1}^{2} )!
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 stepbystep 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 process ^{5} . 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!
^{3} 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 Allpurpose Symbolic Instruction Code. The allpurpose 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 inputs ^{6} , 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 viceversa! 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 writeup 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 (USB flash 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 Language ^{7} .
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
^{6} 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 worstcase scenario vs. the bestcase 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.
^{8} 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/enus/library/aa166223(v=office.10).aspx
6
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? Let’s 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 markups 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.
7
2. From Excel Macros to VBA code
In this section we will make a link between creating recordable macros in Excel and introduce simple VBA code to enhance the possibilities of recorded macros. This way added code will allow us to achieve certain initial characteristics of real programming.
Visual Basic for Application (VBA) is a programming language based on Visual Basic and applied for Microsoft products Excel, Access, Word, PowerPoint… In this section, we introduce selected VBA programming concepts and their implementation to enable end users to develop programs and combine them in system prototypes in Excel.
The four basic things one needs to learn about VBA:
1. There are many Excel macros which you need in applications, but cannot record them
directly: like the “Real” branching after selection (IF statements), Loops, Dynamic cell
addressing…
2. Knowing elements of VBA user will be able to edit (or update) recorded macro (not to
record again for just a small change) 3. User needs to be able to make a program in VBA since there are functions and applications not covered in Excel (also, some VBA programs are running faster than built in Excel solutions for the same problems).
4. User may ask designer (reader, you) to enhance appearance of an object or of a whole
menu or a worksheet. Having in mind that “User is always right”, designer needs to do extra work, for example, to use VB knowledge and create objects using the Control Toolbox instead of Form toolbox when using Developer Tab in Excel, which will allow
making more changes in controls’ appearances
Let‘s first do an brief overview about recording an Excel macro. Using the Developer tab, select the Insert option and choose the Form subset of controls. Click the button and past the button on the selected Excel sheet. At that moment, before clicking the Record button, from the Assign Macro dialog window, developer may assign a
name to the future macro. It must be the single word (no spaces). After that, click the Record button. Giving the name to recorded macros make sense since we will do some editing of macros in this chapter. The next step is to eventually assign a keystroke combination to run this macro, which is not recommended since the macro is already assigned to the button and it will be unnecessary effort to the user to eventually memorize the shortcut combination. After skipping this option, we are ready to record a macro.
8
Figure 2.2.: Assigning a short cut option to a macro
Example 2.1.
Figure 2.3.: Using the Assign Macro menu option to read (and/or change) the VBA code
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 short cut 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 rightclick the created button (on the Figure 2.3 named Button 3), select Assign macro from the popup 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
Figure 2.4.: Choosing the macro which VBA code we would like to see (visible after clicking Edit)
Figure 2.5.: VBA code for the selected macro: Reset_all
characteristics of the VBA code is that it is readable:
user familiar with Excel can easy understand what will
9
happen when the program (macro in this case) will be executed.
To be able to add some code to the previously recorded macro, we need to learn some elements of VBA syntax (how to code instructions in a selected language) and semantics (the meaning of instructions). As we introduced in Chapter 1, VBA is an interpretative language: during every execution, software first checks the syntax of a whole macro (program) and then interprets it and executes line by line (taking into account the control structures of the code). In VBA, every line is a separate instruction (the special symbol at the end of the line: “carriage return” identifies the end of the line, but it is not a visible symbol in the code).
VBA Editor
Using the Figures 2.4 and 2.5 we learned some details about the organization of the VBA programs. Figure 2.6 presents more details for the VBA editor.
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
Examples and Syntax for the Visual Basic Objects
Several Properties for selected objects 

Object 
Property 
Range 
Address 
Comment 

Formula 

Value 

Chart 
ChartTitle 
ChartType 

HasLegend 

Workbook 
HasPassword 
Name 

Path 

Cell 
Format 
Formula attached in it 
object.property = value
VBA is an objectoriented programming language and ALL tasks are performed by manipulating objects. Object could be a single cell, worksheet…Common Excel objects are Range, Name, Chart and Worksheet. Objects can be grouped into collection of objects, and they can be linked in the hierarchy like:
object1.object2.object3 , for example:
Activeworkbook.ActiveSheet.Range(“B3”)
But, if the cursor is already in that sheet, placing:
Range(“B3”)
will produce the same effect.
In the VBA, programmer can change object’s characteristics by modifying its PROPERTIES or by applying the METHOD to the object. To change the property, we use syntax:
object.property = expression Example 2.2:
Range(“C4”).Value=123
‘If it is an active cell, then you can use
ActiveCell.Value=123
‘Please note that using assignment statement,
Range(“C4”) = 123 ‘we produce the same result but in this case we are using the METHOD Example 2.3: Please note that all illustrations in this example have one line only:
Range(“D5”).Formula=”=Round(rand(),2)” ‘uses formula from Excel Worksheets(“Sheet1”).Name=”Input” ‘changes the sheet name to Input
Range("D1").Font.Bold = True
Range("D1").Font.Color = RGB(256, 0, 0)
Range("A1:A5").Interior.Color = RGB(0, 256, 0) ‘range A1:A5 is filled in green color
Range("C1:C5").Borders.Color = RGB(0, 0, 256) ‘range gets blue frame
‘changes fonts type to be Bold
‘makes fonts in the cell D5 in red color
11
Sheets(“Input”).Select
Other common simple methods are Clear, ClearContents, Copy…
Example 2.4: To clear the contents in the cell A1, program is simple, just one line of code (see in the Figure 2.7), after choosing the cell A1 we “clean it” using the method:
ClearContents. But, after that the formatting of that cell remained! Because of that, we added the second method: ClearFormats. Designer can type the method name or, if not sure in spelling, use the combo box with the list of options and doubleclick when you spot it. List is in alphabetical order and
designer may scroll all the way or just enter the first letter and combo will jump to the first option in the list starting with this letter.
Figure 2.7: Using builtin combo box to choose the method we need.
Next three examples use methods with parameter values. Please note the SPACE between selected method and the parameter values. Any misspelled word will stop execution and the message will be Object not defined or Overflow! Example 2.5:
‘To copy the content of A1 into H5 with formatting, use the method:
Range("A1").Copy Destination:=Range("H5") ‘To open the workbook (Excel file) Prime.xlsm (hint: Workbooks, not Workbook):
Workbooks.Open Filename:="Prime.xlsm" ‘To move the worksheet Output after the worksheet Input
Sheets("Output").Move After:=Sheets("Input")
‘
As mentioned in the figure 2.6, VBA is organized through Modules. Each Module has Procedures (procedure could be Private or Public). The type of a procedure could be either subprocedure (Sub) or a function procedure (Function). Procedure has Header (Sub or Function with the procedure name), one or more statements and the Footer (End Sub), following the simple scheme:
12
Sub name (list_of_variables) statements End Sub
where all text in italics should be replaced with programmer’s entries or a VBA code. A Sub or a Function statement could have an empty: ( ) list_of_variables if no variables are being exchanged through this procedure, which is visible for the program presented in Figure 2.5: Sub reset_all() .
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 onedimensional (vector or list), twodimensional (matrix or array) or a
13
treedimensional 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
Figure 2.8: Using the combo box to assign 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 programmer will put a space after the word AS), Figure 2.8; when the data type is found, just
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 

4 
bytes 
2,147,483,648 to 2,147,483,647 

(long integer) 

Single 

(singleprecision 
4 
bytes 
3.402823E38 to 1.401298E45 for negative values; 1.401298E45 to 3.402823E38 for positive values 

floatingpoint) 

Double 
1.79769313486231E308 to 

(doubleprecision 
8 
bytes 
4.94065645841247E324 for negative values; 4.94065645841247E324 to 1.79769313486232E308 for positive values 

floatingpoint) 

Currency 

8 
bytes 
922,337,203,685,477.5808 to 922,337,203,685,477.5807 

(scaled integer) 

+/79,228,162,514,264,337,593,543,950,335 with no decimal point; 

Decimal 
14 bytes 
+/7.9228162514264337593543950335 with 28 places to the right of the decimal; smallest nonzero number is 

+/0.0000000000000000000000000001 

Date 
8 
bytes 
January 1, 100 to December 31, 9999 

Object 
4 
bytes 
Any Object reference 

String 
10 bytes + string 

0 to approximately 2 billion 

(variablelength) 
length 

String 

Length of string 
1 to approximately 65,400 

(fixedlength) 

Variant 

(with numbers) 
16 bytes 
Any numeric value up to the range of a Double 

Variant 
22 bytes + string 

Same range as for variablelength String 

(with characters) 
length 

Userdefined 

Number required by elements 

(using Type) 
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
message box and fixing the problem in VB Editor, do not forget to click the Reset button in the VB Editor main 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 pseudocode it looks like an assignment of the type: A<= B.
Let’s 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 function’s 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).
Linking VBA modules with existing worksheet
There are several ways how to input data in a program. Since all readers are familiar with Excel, we will first explore this option. Also, it is the simplest one. When the VBA program is executed from a button attached to a sheet, programmer can directly use the cell addresses from that sheet to bring the data values in the program, transform them and return back to the same worksheet. If we are collecting data from fixed locations (ranges) and returning them to a fixed locations (into the same or to different ranges), we will use simple option RANGE(“cell_address”) in the assignment statement (as we already used in the Example 2.9) placing it on the right side when assigning values to variables or to the left side when returning values to the
Let us suppose that the button to which we assigned the code is in the Sheet1 (our “base” sheet). To manage data from different sheets, first we need to select the appropriate sheet using instructions: Sheets(“sheet_name”).select and then we can transfer data
19
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_var76 
Range(“A3”)+Range(“B4”)= My_var 

A=1/Range(“A4”) 
x=Range("A1").Select 

Y = Range("A1:A5") but ONLY if Y is not Declared as a vector; it picks up ALL values from the range. You can paste it the same way, e.g. Range("B1:B5") = Y More than that if you put Range("B1:F5") = Y, the content from B1:B5 will be filled repeatedly in every column of the whole range (no transposition will occur!) Try: Range("B1:F1") = Y 
DIM X(10) 

x 
= Range("A1:A5") 

Even it seems logical it does not work! See the 

comments on the left side in this table! To do it, for now, you may transfer data individually and 

will work, but later you will do it with using a cycle or a loop (in Chapter 4.) it 

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 builtin 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: Let’s 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 solutions ^{1} will be discussed in more detail here.
We will use the function =COUNTA(A:A). This function ^{2} 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)! Let’s 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 customer’s data to the
^{1} 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.
Figure 2.12.a: Input sheet with a customer data and a button to transfer data into the appropriate row (in this case row 5) of the worksheet Management. The VBA code for this button is presented in the Figure 2.11. Hint: This example can be expanded by adding commands to delete customer’s data after transferring them to the database and that way prepare space for the next input.
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
Figure 2.13. VBA code to transfer data using the CELLS(r,c) option. There are two major points to be made about the code itself: 1. Instruction Sheets(“Management”).Select will allow to put data into that Sheet. There is no need to use this instruction at the beginning since the button is in the Sheet Input.(do not forget to be back to Input sheet if needed); 2. Using the CELLS(r,c) will allow pasting the data into currently next row, which is possible after using the instruction: new_row = Range("G1") + 1
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)
A Short Note about TIME and DATE
When creating a data entry, it is good idea to insert a time stamp. There are two time options: to use static (fixed) date and time (either by typing in or using a computer system’s values) or to use dynamic option by entering a VBA or Excel function.
To paste a static date in a cell using values from the system, select a cell and press the keystroke combination: Ctrl+; . If you need to insert a current time, use the three key combination: Ctrl+Shift+; (which means that you are actually making Ctrl+: ).
Please note that using dynamic options means that data and time varies depending when a spreadsheet is opened! To place the current date and time in the selected cell using a builtin function just type =NOW(), BUT, as we mentioned above, this data will CHANGE every time when you will open the Excel file! The static option is more useful from the data entry view, while the dynamic option makes more sense when creating reports.
Additional Options for Data management: InputBox and MsgBox
There are three ways typically used to organize data INPUT to any VBA program:
1. Create data in a worksheet and transfer them into VBA using Range or Cells (as it was discussed above)
23
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.
The simplest InputBox will be:
My_var = InputBox(“instruction what to do”,”InputBox name”)
For example, we can use:
x = InputBox("Please enter value not equal to zero", "Input for x")
The same code can be used to input data into a worksheet itself:
Range("B3") = InputBox("Enter a value for the price", "Price") When typing the text MsgBox, VBA offers the following options (Figure 2.15):
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
In this book, we will briefly discuss three varieties of the MsgBoxes:
a). MsgBox to export just a current value of a variable (simplest option, mostly used for short messages and when debugging a macro code). In this case the code is:
MsgBox variable_name
Hint: Applying a string function: concatenation: & in the MsgBox we may put:
MsgBox “Varibale name =”&variable_name
and this way we can present several values using only one MsgBox (see in Example
2.13)
b). MsgBox to export a text (comment), typically triggered by the specific value of a variable. For this option we will present short example 2.12.The syntax for this type of the MsgBox is:
MsgBox Prompt, Button, Title
c) MsgBox to allow user to answer Yes or No and to continue program or macro execution based on that answer. More details about this MsgBox in the Chapter 3.
Example 2.12: Suppose the program calculates the optimum number for the production level: X. This value X could be an integer or a decimal number. Placing the message in the box, user will see the message and will need to REACT since the program will not continue until clicking the OK button in the MsgBox (or by pressing the Enter key while a message box is on the screen):
MsgBox "Adjust X when X is not an integer", vbInformation, "Production level information"
Example 2.13: Code a program to transform the temperature in Fahrenheit degrees to Celsius centigrade, using two formulas: exact formula and a “shortcut” formula (see both formulas in the program code) and calculates the % of error made by using a “shortcut”
formula. Use InputBox and MsgBoxes to manage all data. Present all results! The code below is copied from the VBA editor (after testing the program). Input and Message boxes how they appear during the program execution are in Figures 2.16 and 2.17.
Sub transform() tf = InputBox("Please enter temp in Fahrenheit", "Welcome")
' Abbreviations:
' tcs  temp in Celsius using shortcut formula
' tcf  using real formula
' My_error is calculated as the absolute value of the relative error
' for the ABS value we used built in function ABS(argument) tcs = (tf  30) / 2
25
tcf = (tf  32) * (5 / 9) my_error = Abs(tcs  tcf) / tcf out = MsgBox(tcs, vbInformation, "Using shorcut formula") out = MsgBox(tcf, vbDefaultButton1, "Using real formula") MsgBox "tf=" & tf & ", tc_formula=" & tcf & ", tc_shortcut=" & tcs & ", Error=" & my_error End Sub
Figure 2.16: Please note that we selected different MsgBox “styles” and a “nice” number for the input
Figure 2. 17: For 68F we got integer values when using shortcut formula and the real formula! Usually, there are many decimals and the calculated error is typically presented in scientific (exponential) format!
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 worksheet’s 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
3. Program Flow and the Structured Programming
As we mentioned in the first chapter, flowcharting and pseudocode are methods to help us preparing program paths. We noticed that not all instructions in those algorithms follow the sequential flow (even the first example did not have only sequential execution of all instructions!). Majority of algorithms require possibilities to do flow controls and all programming languages have built in control structures to help programmer to achieve algorithms’ needs. It means that different lines of code could be executed depending on data values, calculated values during the execution or intervention by the user during the program execution (“Interactive” entry). Practically, during a single run, some instructions will be executed only once, some many times, some never (refer to example 3.4)!
The mechanisms that allow programmers to control the flow of execution of any program are called control structures.
Majority of programs presented in previous examples were simple SEQUENTIAL programs where all instructions were executed one after another (in a sequence). We can name it to be the first control structure: sequence. There is one additional algorithm with sequential flow (discussed in Examples 3.1 and 3.2).
Programming languages use additional three control structures. The list of all flow controls:
1. Sequence – program flow where all instructions are executed
2. Selection – the flow depends on the answer to selected question(s) and based on that program continue flows choosing between two or more options.
3. Iteration (repetition, cycle, loop) allows some program segment to be executed (or repeated) several times. Depending how it is designed, it is possible that the code will not be executed at all or executed a fixed number of times. Iteration can be accomplished with test: before loop starts, inside loops, or after loop instructions are executed, before running the next cycle. Programmer must be very careful when designing iterations and not let program to run indefinitely because of the wrong criteria placed to stop the cycle. In selected situations (like for many problems in the numerical analysis) we recommend to have more than just one criteria for stopping the loop (more in examples in Chapter 4).
4. Branching (“jumping”, “switching” or using: GO TO) – allows the program to jump to a different part of the program (and back, if needed). Many authors ^{1} share the opinion that this category is rarely used in modular structured programming, or that it is even “illegal” to use. Also, many newer programming languages do not support this control (like C++, Java )
^{1} Opinion from Kenneth Leroy Busbee , www.cnx.org, visited in January 2011
27
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 statement ^{2} .
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 (IF…THEN, IF…THEN…ELSE 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 cubes ^{4} . 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
^{2} Ibid
^{3} Slightly modified from http://www.its.bldrdoc.gov/fs1037/dir035/_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
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 Input #1, a, b, c Close #1 a2 = a ^ 2 b2 = b ^ 2
c2 = c ^ 2 a3 = a ^ 3
' Open file for input ' Read data into three variables ' Close input file
Calculations and assignment statements
b3 = b ^ 3 c3 = c ^ 3 Open "Power23.txt" For Output As #2 Print #2, a, a2, a3, b, b2, b3, c, c2, c3 Close #2 End Sub
' Open file for output ‘ Print to file ‘ Close file
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 userfriendly 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.
Note: more about formatting the output file is discussed in Example 3.14
VBA Control Structures: IF Statement
Program designer NEEDS TO FULLY UNDERSTAND the use of IF statement to be able to prepare codes for solving the majority of practical problems: from managing the transaction processes to decision making procedures (for example to do whatif analysis).
First, recollect how the IF statement in Excel is easy to use. The problem is that after executing the IF function the result is placed in the same cell where the function was invoked (which is also true for all Excel functions and formulas). This way, Excel IF statement is not really making a “switch” or a change in the program flow!
Because of that, we need to introduce (or review, if you are already familiar with it) the characteristics of IF statements which is used in computer programming languages
30
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 IF…THEN 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.
Figure 3.4: The simple IF flow
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 builtin 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 InputBoxes 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 VBA’s 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 intervention ^{5} . This example uses a short survey to decide about accepting or notaccepting 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)
Hint: It will be possible to improve this solution (code) after introducing the: IFTHEN ELSE statement. Appropriate VBA code is next
^{5} For more ideas about copying data under selections, please read a minicase: 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.
(Hint: box with the letter S means SELECTION between options):
Sub Select_and_Copy() Item = Range("B1") Producer = Range("B2") Packaging = Range("B3") Price = Range("B4")
Copying data from the Survey sheet into memory by assigning them to new variables
If Range("C15") < 2.5 And Range("C16") <= 3 Then Sheets("Accepted").Select If Range("C15") >= 2.5 Or Range("C16") > 3 Then Sheets("Rejected").Select
Rows("3:3").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove Range("A3") = Item
Range("B3") = Producer Range("C3") = Packaging Range("D3") = Price End Sub
Copying data from the memory into appropriate sheet using previously created variables
Discuss solution! What is the order of data in sheets Accepted and Rejected? Do you have the same row in both sheets?
Example 3.6: In the Example 2.12 (Chapter 2) we used MsgBox to stop the program execution to warn the manager to take a look at the value and then to decide what to do:
if this number representing the production level is integer, program should not stop and manager should do nothing, but if it not integer, manager should decide on how to round it and enter the value, depending on the constraints! Let us use the IF statement do it automatically, making a macro to do “checking”. If this number (x) is not an integer, macro suggests user to adjust the production level. A solution presented below is based on using the function Int(value) ^{6} and simple IF statement.
^{6} 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 loan’s 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.9: Naming a new procedure and choosing options
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 subprocedure 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 subprocedure. 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 IF…THEN statement (Figure
3.12):
Figure 3.12: The Block IF option
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.
37
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"
Figure 3.13: The IFTHENELSE
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
Probably the most used is the next option for IF statement IF…THEN…ELSE (Figure 3.10), and the syntax is below:
IF condition THEN Action(s)_t
ELSE
Action(s)_f END IF next statement
The next statement will be executed after either Action(s)_t, OR Action(s)_f but ONLY ONE of these options (or paths) might occur. This is known as distinct or exclusive OR option. Number of statements in each branch could be more than one and it is possible that one
38
(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 “nonnegative” 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 
Else
y
y
= Sqr(x)
= Sqr(x)
End If MsgBox "x=" & x & " y=" & y End Sub
Example 3.11: Modified example 3.5 using the IFTHENELSE option will have change in the section S (Selection) of the program. Original code uses two IF statements:
…
If Range("C15") < 2.5 And Range("C16") <= 3 Then Sheets("Accepted").Select If Range("C15") >= 2.5 Or Range("C16") > 3 Then Sheets("Rejected").Select
…
It can be modified to be more elegant and a bit easier for coding:
…
If Range("C15") < 2.5 And Range("C16") <= 3 Then Sheets("Accepted").Select
Else
Sheets("Rejected").Select End if
…
The next example is organized with using macro recording and with adding just a small programming intervention when using the IFTHENELSE statement.
Example 3.12: There are many simple games to play using builtin 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 IFTHENELSE statement in the code.
The code for the Example 3.12:
Sub Tossing() my_event = Range("B4") If my_event <= 0.5 Then Sheets("Tails").Select
Rows("2:2").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove Range("A2") = my_event Else Sheets("Heads").Select
Rows("2:2").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove Range("A2") = my_event End If Sheets("Random Input").Select
Range("C5").Select
End Sub
Please notice a lot of symmetry in the code. When creating a macro, we were able to RECORD almost all lines (program instructions) except: If, Else and End If.
40
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 program’s flow based on user’s choice!
From the VBA Help menu, partial list of setting is presented on the next page:
Constant 
Value 
Description 
vbOKOnly 
0 
Display OK button only. 
vbOKCancel 
1 
Display OK and Cancel buttons. 
vbAbortRetryIgnore 
2 
Display Abort, Retry, and Ignore buttons. 
vbYesNoCancel 
3 
Display Yes, No, and Cancel buttons. 
vbYesNo 
4 
Display Yes and No buttons. 
vbRetryCancel 
5 
Display Retry and Cancel buttons. 
vbCritical 
16 
Display Critical Message icon. 
vbQuestion 
32 
Display Warning Query icon. 
vbExclamation 
48 
Display Warning Message icon. 
vbInformation 
64 
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 Whatif 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 “BreakEven Production problem”: Suppose you are making initial production plan to produce one product. There are startup 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
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 “breakeven” 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 startup cost). More than that, we can put any value for the target value in the Goal Seek and do whatif 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 builtin names for the buttons in this type of MsgBox.
Figure 3.15: BreakEven Model
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 IfThen 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:
43
Figure 3.17: User enters value of zero (for the BreakEven Analysis), right.
Figure 3.19: Option to Revert using the MsgBox with two buttons!
Figure 3.18: The Breakeven value for the production level.
Example 3.14: In this example we will use the IFTHENELSE 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 builtin VBA help or online 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.
The Select Case Control Statement
As mentioned in the introduction to this flow control option, we will use a case statement when the number of alternative actions is bigger and when it becomes less convenient to use IF or nested IF statements.
The syntax is presented below:
46
Select Case expression_to_be_tested [Case expression_list_1 [statements_for_1]]
…
[Case expression_list_n [statements_for_n]]
[ Case Else [else_statements]] End Select
Example 3.17: Assume that you have to help manager with assigning bonuses to workers, depending on their sales levels. Bonus will be assigned as a % of sales depending on the sale level. For each of suggested sales intervals, CASE statement matches the value of the sales and calculates the bonus.
Sub bonus()
' bonus Macro
'
sales = InputBox("Please enter sales") Select Case sales Case Is < 2000 e_bonus = 0 Case Is < 3000 e_bonus = sales * 0.02 Case Is < 4000 e_bonus = sales * 0.03 Case Is < 6000 e_bonus = sales * 0.04 Case Else e_bonus = sales * 0.05 End Select MsgBox "sales=" & sales & " E_bonus=" & e_bonus End Sub
Figure 3.21: InputBox (left) is used to input sales of 5000, while the MsgBox (right) present the sales and the calculated bonus.
.
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 Ticket ^{7} 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 
Expired Meter 
$25 
2 
No Parking Zone 
$50 
3 
Double Parking 
$100 
4 
Blocking Garage / Driveway Entrance 
$150 
5 
Parked in a Handicap Place 
$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
^{7} 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.
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!
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
Hint: When creating two groups (or sets) of option buttons in Excel, you
need to group the first set (using the appropriate control from the Designer tab) before starting to create the other group of options buttons. Also, the numbers assigned to options depend on the ORDER OF
49
CREATION THE BUTTONS, and they are not based on the buttons’ location on the Sheet!
VBA Offers a Possibility to Use Go To Statements
Syntax:
GoTo User_Defined_Label To make this change of control (“jump”) possible, we also need the line User_Defined_Label:
Notice that the: (colon) is appended after the label’s name and also, the label name must be the only text in this line. The line User_Defined_Label: can be before or after the GO TO statement.
To illustrate the syntax, if there is a line of code GoTo New_Customer Then, somewhere in this program must be the line New_Customer:
Note: The Go To statement could be convenient for short macros and programs, particularly if we need to move the control to the other worksheet in the workbook. Good structured programming practice suggests AVOIDING using GoTo by using Loop statements, when appropriate, but developer needs to be very familiar with LOOP statements to be able to use them properly. As mentioned in the introduction, many programming languages do not support GOTO statement.
As we pointed out at the beginning of this chapter, we can “imitate” the loop (cycle) using the IF and GO TO statements (see the simple example below)! In the next chapter we will “tackle” the real LOOPS!
Example 3.20:
Simple game of dice: When rolling three dice, which event has a higher probability: event P12 meaning that the sum is 12 or event P13 meaning that the sum=13? Run that experiment n times (n is the input value) and count the frequencies for both events and compare them! Also, you may wish to solve the problem using the theoretical probabilities ^{8} for these two events!
^{8} 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
If n < 10 Then
MsgBox "Not enough data for the experiment" Exit Sub End If
c = 0
S12 = 0 S13 = 0 my_loop:
= InputBox("Please enter the number of experiments")
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
Figure 3.24: Outputs from two runs with 1000 experiments showing that S12 is more probable to happen: experimental P(12)=0.12 and P(13)=0.10! (Please check if these results match the theoretical results!)
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 bi weekly 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 "biweekly.txt" For Output As #2 Print #2, Tab; "Biweekly wages"
' Open file for input. ' Open file for output.
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
Chapter 4: Programming the Cyclic Structures (Loops)
VBA programming language offers possibility to use loop controls. To secure execution of a statement (or a block of statements) many times, based on a given condition when to start and stop, VBA offers three basic types of cyclic (iterative, loop) executions. When using loops it is easy to make a mistake causing that the loop will run “forever”, known as the “infinite” loop. Because of that, it is recommended to have more than one instruction to stop the loop! It is important to mention that there are some applications when programmers will purposely start with the infinite loop. In this case, inside the loop, the programmer will put at least one (preferably two conditions) for stopping the execution under selected condition(s)!
If there is a mistake and the loop went into infinite number of executions, to stop the VBA from running, user can press the Ctrl+Break keys at the same time or Esc key (in some keyboards without the Break key), or to click the BREAK button in the VBA editor window. After that, programmer should fix the program, open the VBA Editor and click the Reset button (next to Break button, see Figure 4.1 ^{1} , and try the execution again!)
Syntax for the cyclic structures is
based on the Microsoft’s VBA Help descriptions.
As mentioned above, the VBA offers three basic loops: FOR…Next (or counting loop), Do While…Loop and Do Until…Loop.
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.
Figure 4.3: The FOR…NEXT Loop. If the value for the counter is < end , its value is being changed by adding the value of step (or 1 if the variable step is omitted). In some cases the step value can be negative! Pseudo code is in Figure 4.2.
Example 4.1:
Let us start with a simple problem:
Calculate the absolute value (or any other function of your choice) for all numbers in the column B. In the column A are just their order numbers (used just for illustrative purposes). This simple problem will be solved
using all three types of loops ^{2} 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:
Figure 4.3: Input data for the: For… Next Loop. The number of elements in the list is calculated using the Excel function in E1.
^{2} 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 fillin 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 FOR…Next 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 onedimensional matrix, array for twodimensional 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
Please see the next example.
Example 4.3: Solving the problem 4.2 using DYNAMIC allocation for the vector X (the number of elements is calculated in E1, like in Examples 4.1 and 4.2.
Sub using_vector_and_Redim() Dim x( ) As Integer my_end = Range("E1") ReDim x(my_end) 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
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 Pythagoras’s 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 individual vectors. In our example, array has 15 rows and 5 columns. 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.6: Results are in the column F (for minimums) and in the row 16 (for maximums)!
In the previous examples, we introduced vectors and implicitly introduced matrices! In the next simple example, we will present how to solve simple system of 2 algebraic equations with 2 variables. The reason is to learn a little bit about using matrices. Please note that Excel contains complete matrix calculation for all needs of business users.
Example 4.6:
Using the Crammer’s Rule (by calculating appropriate determinants for a system) solve the 2 by 2 system of linear algebraic equations. Let us assume that the system is presented in a range (A1:D3) in an Excel worksheet (Figure 4.7.)
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
To solve the problem, we need to calculate values DS (system determinant), DX (determinant when the coefficients for x are replaced by the “right sides”) and DY (determinant when the coefficients for y are replaced by the “right sides”). After that, if DS<>0, solution is: x=DX/DS and y=DY/DS.
Program will use DIM, CELLS(r, c) and IF statements. Please notice the usage of indexes when doing input in the matrix M and vector V.
Sub syst2times2MV()
Dim M(2, 2), V(2) As Single
For c = 1 To 2 M(1, c) = Cells(2, c) M(2, c) = Cells(3, c) V(c) = Cells(c + 1, 4) Cells(5, c) = " "
Next
DS = M(1, 1) * M(2, 2)  M(1, 2) * M(2, 1)
If DS = 0 Then Range("B5") = "No unique solution" Exit Sub
End If
‘ cleans the output range from the previous result
Figure 4.8: After clicking, solution is x=1, y=7. Try for different input values (test your program)
DX 
= V(1) * M(2, 2)  M(1, 2) * V(2) 
DY 
= M(1, 1) * V(2)  V(1) * M(2, 1) 
x = DX / DS
y = DY / DS
Range("A5") = x Range("B5") = y End Sub
Notes: Some readers will conclude that using
matrices and vectors in this case is “too much” and that can be done faster using simple notation, like you used in high school a*x+b*y=c and d*x+e*y=f. In this case, code for solving the system will have fewer lines! And they are right! It will take 2 lines less and no cyclical structures! By the way, you can apply this approach directly in Excel!
61
DO WHILE LOOP is probably one of the most used types of loop control statements. Programmer has complete control when using this loop (no “required run”, no adding the next value to the counter before leaving the loop like with FOR…Next type). Programmer is in charge of changing the values if a counter is needed and there is no automatic adding the
Figure 4.9: Pseudo code for the Do While… Loop
next step. We are examining several ideas how to control program execution by having different stoppers.
Example 4.7: Let’s solve the problem introduced in the example 4.1 using the Do While…Loop. 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: Let’s solve the problem introduced in the example 4.1 using the Do While…Loop, 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 For…Next loop. Also, it is presented as a solution using the Do Until…Loop 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. Let’s 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
the end, program will post the last 10 values in the worksheet, near the input values.
Function is in the Procedure:
Figure 4.10: Setting up the iteration criteria
^{3} When we use Solver, there are builtin 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 NonNegative. 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 Dim My_val(500) As Single epsilon = Range("B2") Delta = Range("B3")
x = Range("B4")
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
x
‘condition 1
‘condition 2
= x  Delta If Abs(x) < epsilon Then
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
it = it + 1
My_val(it) = limit(x)
Loop
my_row = 2 For counter = it To it  10 Step 1 my_row = my_row + 1 Cells(my_row, 4) = My_val(counter) Next End Sub
Figure 4.11: Resulting values for the Limit show the values approaching the number e
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 Until…Loop
Example 4.11: Let’s now solve the problem 4.1
using the Do Until Loop. The 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 the program stops.
Sub My_Until() 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.12: Let’s 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 markup ^{4} 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
Figure 4.13: The several initial rows of input data
Figure 4.14: The message that the Item is found (up) and that item is highlighted (right).
This solution is also one example of the sequential search. Example 4.14: Using ideas and data from the previous problem find ALL items with small markups! After finding all those items, list their prices in the column D. We named the program: Markup_problem_all. In the program, we keep all of the matching row numbers as the elements of the vector FOUND. Program uses two types of Loops:
^{4} 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 For…Next) 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 (xsin(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 
DO While 5 > 4 
FOR cc=1 to 5 tep 2 
DO While 4 > 5 
FOR cc=1 to 0 
DO Until 5 < 4 
FOR cc=1 to 1 
DO Until 4 < 5 
FOR cc=5 to 7 step 1 
Do While tmax=60 
FOR cc=7 to 5 step 1 
Do While x=0 
8. Create an example when using FOR…Next 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
Chapter 5: Sorting and Searching algorithms
There are many sorting algorithms used in computer programming. From the early days, people tried to optimize the number of operations and the memory usage for these processes. Also, every time when having these discussions, we are assuming that the algorithm is made correctly (without extra steps)!
Usually, we are thinking about sorting a list of numbers, but in fact, we need to think about sorting RECORDS, which can be very lengthy process. Using the concept of linked lists used in data structures, sorting is actually reduced to sorting INDEXES of records ^{1} , not “moving” the whole records around.
In the next several examples we will discuss few sorting procedures. Depending on the length of a list (N), some of the algorithms are better (recommended) or not! The mathematical notation for the number of operations is the “big O” meaning the max number of operations to execute the algorithm. For example, what will be the worst scenario to sort a list of numbers in the ascending order? Yes, you are right: if they are already sorted into descending order! There are algorithms (like the most popular “Bubble” sort) requiring the maximum number of operations to be presented as O(N^2) , e.g. to sort 10 elements computer will use not more than 100 measurable computer operations (comparisons in this case). The second example which we are exploring in this text takes a bit more memory (based on one of programs we did earlier in this book), and it has also O(N^2) operations.
There is a group of algorithms requiring only O(N*log(N)) operations, which is for N=10 less than 5 comparisons (since the log is the Natural log)! But, the point is that the algorithms for those procedures are more complex. The bestknown algorithms are QUICKSORT and MERGESORT procedures; both use recursive functions and we will leave it for JAVA or C++ programming applications.
Bubble Sort
Bubble sort is a simple and wellknown sorting algorithm. As mentioned above, Bubble sort belongs to a group of sorting algorithms with O(N^2), which makes it quite inefficient for sorting large data volumes.
^{1} 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
Algorithm is based on the idea of pushing a bubble:
compare two elements of the list in a sequence. If the left is bigger than the right one, swap them and start over (and this why the procedure requires a lot of comparisons)! The procedure is completed when there are no more swaps.
The list of 9 elements to be sorted is in a worksheet in
the column 1. After sorting, sorted list will be placed in the column 2 of the same sheet.
Figure 5.1: Input list to be sorted (N=9; calculated in the cell C1)
Example 5.1: This solution for the Bubble sort uses Do Until and For…Next 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
Figure 5.2: Input and Sorted lists after the “Bubble” sort
Next
Loop For rr = 1 To tot Cells(rr, 2) = X(rr)
Next
End Sub
70
Example 5.2: Bubble sort using two FOR…NEXT 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
Figure 5.3: Input and Sorted lists after bubble sort (N=9 in cell C1), with the number of swapping counted in the cell D1 .
^{2} Based on the example from: Vulicevic, B and Crnkovic, J., Algoritamski Jezik FORTRAN IV, p.177, Univerzitet u Beogradu, pp. 276, Beograd, 1984.
71
Parallel Sort (as one of the several “dialects” of a Heap sort) This sorting algorithm is based on one of our earlier program which finds both, Min and Max elements in a list. The real application of this sort will be to sort PKs, not complete records since it is “memory hungry” method (it needs another list of the same size for holding a result). Example 5.3: Let us name the input list X(N). After finding the Min and the Max, the Min element is copied to be the first element of a new list, Y(N), while in the original list (X(N)) it is replaced with Max value, so, it cannot be the selected again! In the other loop, algorithm just looks for the next Min and replaces it with already found Max after copying it in the Y(N) list. We can use the input data from Figure 5.1, while the output is in the column D (Figure 5.4).
Sub parallel() Dim x(100), Y(100) tot = Cells(1, 3) For rr = 1 To tot x(rr) = Cells(rr, 1)
Next j = 1 Do While j <= tot my_max = x(1) my_min = x(1) maxi = 1 mini = 1 For i = 1 To tot If x(i) > my_max Then my_max = x(i) maxi = i End If If x(i) < my_min Then my_min = x(i) mini = i End If Next Y(j) = my_min j = j + 1 x(mini) = my_max Loop For rr = 1 To tot Cells(rr, 4) = Y(rr)
Next End Sub
Figure 5.4: Input and Sorted lists after parallel sort
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 Double if using decimal numbers).
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 sublists and to check in which one of the two sublists is the value we are searching for, and then the process should be repeated until finding the matching record.
Figure 5.5: Beginning of the search (above) and the result (below)
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 midpoint 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 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 Mid_point = Int((beg + tot) / 2) If Cells(Mid_point, 1) = my_value Then
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 preselected 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!
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
‘We are using the FUNCTION procedure Fun(x) and this way,
‘the main part of the program is reusable! Just change FUN(x)! Sub binary_zero()
a = Range("C2")
b = Range("C3")
eps = Range("C4") no_iter = Range("C5") If Abs(Fun(a)) < eps Then Range("C7") = a Exit Sub
End If If Abs(Fun(b)) < eps Then Range("C7") = b Exit Sub
End If If Fun(a) * Fun(b) > 0 Or a > b Then MsgBox "Find another interval" Exit Sub
End If
For cc = 1 To Range("C5")
c = (a + b) / 2
If Abs(Fun(c)) < eps Then Range("C7") = c
Here begins the main part of the program: iterations
Exit Sub
End If
If Fun(a) * Fun(c) < 0 Then
b 
= c 
Else 


Гораздо больше, чем просто документы.
Откройте для себя все, что может предложить Scribd, включая книги и аудиокниги от крупных издательств.
Отменить можно в любой момент.