An Introduction to Programming with Visual Basic for Applications [1 rev.2 ed.] 8876617167, 9788876617164

Programming is scientific creativity supported by study of theory. It is essential to know how a computer works and to h

770 127 950KB

English Pages 212 Year 2006-2015

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

An Introduction to Programming with Visual Basic for Applications [1 rev.2 ed.]
 8876617167, 9788876617164

Table of contents :
Preface vii
1 Introduction 1
1.1 Languages and Translators 1
1.2 The Integrated Development Environment 3
1.3 Building a Graphical Interface 5
2 A First Experiment 9
2.1 Exercises 14
3 Variables and Numerical Types 15
3.1 Numerical variables 16
3.1.1 Numerical Expressions 18
3.1.2 Evaluation of Numerical Expressions 18
3.1.3 Type Conversion Functions 21
3.1.4 Intrinsic Functions 23
3.1.5 Operators Priority and Associativity 23
3.2 Numerical Constants 24
3.3 Exercises 26
4 Keyboard Input and Screen Output 27
4.1 The MsgBox Instruction 27
4.2 The InputBox Instruction 29
4.3 Exercises 30
5 Conditional Execution 31
5.1 The If-Then Statement 31
5.2 Relational Expressions 36
5.3 Logical Expressions 37
5.3.1 The Or Operator 37
5.3.2 The And Operator 37
5.3.3 The Xor Operator 37
5.3.4 The Not Operator 38
5.4 Operators Precedence 38
5.5 The Select Case Statement 39
5.6 Exercises 42
6 Strings 45
6.1 String Variables 46
6.2 String Operators 47
6.3 String Functions 48
6.3.1 Len 48
6.3.2 Left 48
6.3.3 Right 48
6.3.4 Mid 49
6.3.5 Instr 49
6.3.6 Other String Functions 50
6.4 String Comparison 52
6.5 Exercises 54
7 Unconditional Jumps 55
8 Loop Statements 57
8.1 The For-Next Loop 58
8.2 Exercises 63
8.3 The Do-Loop Loop 64
8.4 Exercises 67
9 Arrays and Matrices 69
9.1 Matrices 71
9.2 String Arrays and Matrices 72
9.3 Exercises 73
10 Files 75
10.1 Opening a File 76
10.2 Closing a File 77
10.3 Writing to a File 78
10.4 Reading from a File 79
10.5 Exercises 83
11 Functions and Subroutines 85
11.1 Functions 88
11.2 Subroutines 89
11.3 Arguments and Formal Parameters 90
11.3.1 Arguments passage 91
11.3.2 Vector Arguments and Parameters 93
11.4 Static Variables 94
11.5 Non-local Variables 94
11.6 Variable Initialization 95
11.7 Recursion 96
11.8 Exercises 98
12 Compound Data Types 101
12.1 Exercises 103
13 Some Basic VBA Controls 105
13.1 The Label Control 105
13.2 The TextBox Control 106
13.3 The OptionButton Control 108
13.4 The CheckBox Control 109
13.5 Disabling and Hiding Controls 110
14 Good Programming Practices 111
14.1 Implicit Variables 111
14.2 Code Indentation 111
14.3 Comments 112
15 Debugging 113
16 More Complex Exercises 115
17 Solution to the Exercises 123
17.1 Chapter 2 - A First Experiment 123
17.2 Chapter 3 - Variables and Numerical Types 124
17.3 Chapter 4 - Keyboard Input and Screen 126
17.4 Chapter 5 - Conditional Execution 126
17.5 Chapter 6 - Strings 131
17.6 Chapter 8 - Loop Statements 137
17.7 Chapter 9 - Arrays and Matrices 150
17.8 Chapter 10 - Files 161
17.9 Chapter 11 - Functions and Subroutines 173
17.10 Chapter 12 - Compound Data Types 185
17.11 Chapter 16 - More Complex Exercises 187

Citation preview

CLAUDIO FORNARO

An Introduction to Programming with

Visual Basic for Applications Rev. 2

ii

© Celid, ottobre 2006 via Cialdini, 26 – 10138 Torino tel. 011.44.74.774 www.celid.it I diritti di riproduzione, di memorizzazione e di adattamento totale o parziale con qualsiasi mezzo (compresi microfilm e copie fotostatiche) sono riservati.

ISBN 88-7661-716-7 Stampa SATIZ (TO)

Table of Contents

iii

Table of Contents Preface ..............................................................................................................vii 1

Introduction ............................................................................................... 1 1.1 Languages and Translators ................................................................. 1 1.2 The Integrated Development Environment ........................................ 3 1.3 Building a Graphical Interface ........................................................... 5

2

A First Experiment .................................................................................... 9 2.1 Exercises ........................................................................................... 14

3

Variables and Numerical Types ............................................................. 15 3.1 Numerical variables .......................................................................... 16 3.1.1 Numerical Expressions ..................................................................... 18 3.1.2 Evaluation of Numerical Expressions .............................................. 18 3.1.3 Type Conversion Functions .............................................................. 21 3.1.4 Intrinsic Functions ............................................................................ 23 3.1.5 Operators Priority and Associativity ................................................ 23 3.2 Numerical Constants ........................................................................ 24 3.3 Exercises ........................................................................................... 26

4

Keyboard Input and Screen Output ...................................................... 27 4.1 The MsgBox Instruction ................................................................... 27 4.2 The InputBox Instruction ................................................................. 29 4.3 Exercises ........................................................................................... 30

5

Conditional Execution ............................................................................. 31 5.1 The If-Then Statement ...................................................................... 31 5.2 Relational Expressions ..................................................................... 36 5.3 Logical Expressions.......................................................................... 37 5.3.1 The Or Operator ............................................................................... 37 5.3.2 The And Operator ............................................................................. 37 5.3.3 The Xor Operator ............................................................................. 37 5.3.4 The Not Operator .............................................................................. 38

Table of Contents

iv 5.4 5.5 5.6

Operators Precedence ....................................................................... 38 The Select Case Statement ............................................................... 39 Exercises .......................................................................................... 42

6

Strings....................................................................................................... 45 6.1 String Variables ................................................................................ 46 6.2 String Operators ............................................................................... 47 6.3 String Functions ............................................................................... 48 6.3.1 Len.................................................................................................... 48 6.3.2 Left ................................................................................................... 48 6.3.3 Right ................................................................................................. 48 6.3.4 Mid ................................................................................................... 49 6.3.5 Instr .................................................................................................. 49 6.3.6 Other String Functions ..................................................................... 50 6.4 String Comparison ........................................................................... 52 6.5 Exercises .......................................................................................... 54

7

Unconditional Jumps .............................................................................. 55

8

Loop Statements ...................................................................................... 57 8.1 The For-Next Loop .......................................................................... 58 8.2 Exercises .......................................................................................... 63 8.3 The Do-Loop Loop .......................................................................... 64 8.4 Exercises .......................................................................................... 67

9

Arrays and Matrices ............................................................................... 69 9.1 Matrices ............................................................................................ 71 9.2 String Arrays and Matrices .............................................................. 72 9.3 Exercises .......................................................................................... 73

10 Files ...................................................................................................... 75 10.1 Opening a File .................................................................................. 76 10.2 Closing a File ................................................................................... 77 10.3 Writing to a File ............................................................................... 78 10.4 Reading from a File .......................................................................... 79 10.5 Exercises .......................................................................................... 83 11 Functions and Subroutines ................................................................ 85 11.1 Functions .......................................................................................... 88 11.2 Subroutines ....................................................................................... 89

Table of Contents

v

11.3 Arguments and Formal Parameters .................................................. 90 11.3.1 Arguments passage ................................................................... 91 11.3.2 Vector Arguments and Parameters ........................................... 93 11.4 Static Variables ................................................................................. 94 11.5 Non-local Variables .......................................................................... 94 11.6 Variable Initialization ....................................................................... 95 11.7 Recursion .......................................................................................... 96 11.8 Exercises ........................................................................................... 98 12 Compound Data Types ..................................................................... 101 12.1 Exercises ......................................................................................... 103 13 Some Basic VBA Controls ................................................................ 105 13.1 The Label Control........................................................................... 105 13.2 The TextBox Control ...................................................................... 106 13.3 The OptionButton Control .............................................................. 108 13.4 The CheckBox Control ................................................................... 109 13.5 Disabling and Hiding Controls ....................................................... 110 14 Good Programming Practices .......................................................... 111 14.1 Implicit Variables ........................................................................... 111 14.2 Code Indentation ............................................................................ 111 14.3 Comments ....................................................................................... 112 15

Debugging .......................................................................................... 113

16

More Complex Exercises .................................................................. 115

17 Solution to the Exercises ................................................................... 123 17.1 Chapter 2 - A First Experiment ...................................................... 123 17.2 Chapter 3 - Variables and Numerical Types .................................. 124 17.3 Chapter 4 - Keyboard Input and Screen ......................................... 126 17.4 Chapter 5 - Conditional Execution ................................................. 126 17.5 Chapter 6 - Strings .......................................................................... 131 17.6 Chapter 8 - Loop Statements .......................................................... 137 17.7 Chapter 9 - Arrays and Matrices .................................................... 150 17.8 Chapter 10 - Files ........................................................................... 161 17.9 Chapter 11 - Functions and Subroutines ........................................ 173 17.10 Chapter 12 - Compound Data Types .............................................. 185 17.11 Chapter 16 - More Complex Exercises .......................................... 187

vi

Table of Contents

Preface

vii

Preface Programming is scientific creativity supported by study of theory. It is essential to know how a computer works and to have the bases of logics and mathematics, but proficiency requires knowledge of the fundamental programming algorithms and techniques developed by the scientific community for the most classic problems. However, learning programming starts from knowing the language syntax and using it to describe a solution of a problem. This is the most complex obstacle, because it requires the development of a precise and procedural reasoning. This book was designed to be used in a course of programming basics. It is addressed to beginners, and therefore it only covers the basic procedural elements of the language; these, however, constitute the basis of each type of programming. The choice to adopt Visual Basic for Applications instead of other more powerful and “noble” languages is essentially due to its lower impact on beginners, together with its easiness in building visual interfaces. Moreover, the required software is also easy to find and install: it is included in every application of the Microsoft Office suite (Excel, Word, etc.). In addition, it may be worth noting that Visual Basic is one of the most used programming languages in the world. Understanding this book requires no previous programming experience and no mathematics skill other than some high school algebra notions. Many notes, tips, and solved exercises make it suitable for self-taught students as well. A special thank you goes to Professor Marco Mezzalama of the Politecnico di Torino and to Dr. Edoardo Calia of the Istituto Superiore Mario Boella for their kind suggestions and review. Biella, October 2006 Claudio Fornaro

viii

Introduction

1

Introduction

1.1

Languages and Translators

1

The goal of writing a program is substantially to “explain” to a computer the operations it has to execute to solve a problem. In order to instruct a computer about the operations it must execute, both the user and the machine must “speak” the same language. Man programs the activity of the computer by using this common language: a programming language. The languages used by humans and by computers are quite different though: the first make use of words (“add 2 to 5”), while only sequences of zeroes and ones exist for the latter. In more detail, the microprocessor (i.e. the CPU) only understands a language called the machine language. Every sequence of zeroes and ones has a precise meaning for the CPU: for instance the sequence “1011010” could mean “calculate a sum”. To ask this computer to calculate a sum, the programmer would issue the command “1011010”; if the execution of a different operation is desired, s/he would have to look up in the microprocessor manual the translation of this operation in machine language, and use this command. This process is very complicated and long, and this is the reason why the majority of programming languages are similar to human languages (English). These languages are called high-level languages and Visual Basic is one of them. Programs generically called translators carry out the translation of programs written in a high-level language into machine language. The programmer asks the translator to convert the instruction “calculate a sum”, the translator translates the instruction to “1011010”. When this machine code is given to the microprocessor, it clearly understands the request and computes a sum. A program is just a sequence of commands, more properly called “instructions”, expressed in a given programming language. The file that stores these instructions is the source program (or source code). There are two main kinds of translators:  compilers  interpreters

2

Chapter 1

A compiler translates the whole source program and saves it in a file called the executable file (or code); under a Microsoft operating system, these files have a .EXE or .COM extension. At this point, the source code is no more needed and executing the program is as simple as double-clicking on the name of the executable file. An interpreter translates the source program one instruction at a time, and immediately requests the microprocessor to execute it. The interpreter does not store the result of the translation in a file, and the instruction translated is deleted after it has been executed. The execution loop of an interpreted program can be represented as follows: 1) read an instruction 2) translate it to machine language 3) submit the translated instruction to the microprocessor for immediate execution 4) repeat from 1) to read the next instruction of the source program This means for instance that if the sequence of operations contained in a program requires that an instruction be executed more than once, it is translated each time. By comparing the two methods, we can make the following comments:  a compiled program runs faster than the corresponding interpreted program because there is no translation time to take into account when it is run;  a compiled program is easier to start (often a double-click on its icon is all you need); on the other hand, the use of an interpreted program is limited to expert programmers who know how to use the interpreter itself;  the end-user of a compiled program need not buy a costly interpreter;  the end-user of a compiled program is not allowed to modify the program source code because s/he does not have access to it (this is often the case for copyright preservation);  an interpreted program may be stopped, modified, and restarted from the interruption point without loosing time in a full or partial recompilation. In summary, an interpreter may be easier to use in the development phase of a program. The majority of the programming languages are only compiled (that is, an interpreter has not been developed for them), others are only interpreted and others (such as Visual Basic) have both compilers and interpreters. In particular, each program of the Microsoft Office™ Suite (Word, Excel, PowerPoint, Access, etc.) contains a Visual Basic for Applications (VBA) interpreter, while a professional Visual Basic (not “for Applications”) compiler is available either commercially or through free download from the Microsoft Web site. There are differences between the two versions, but the language philosophy is essentially the same and the passage from the one to the other is

Introduction

3

not so difficult. For the sake of brevity, in this text the term Visual Basic will refer to the for Applications version.

1.2

The Integrated Development Environment

Visual Basic’s Integrated Development Environment (IDE) allows the programmer to write and execute Visual Basic code, providing several program management, control, and verification tools. To open the IDE interface: 1. start one of the application programs of the Microsoft Office suite, Excel for example 2. select Macro from menu Tools 3. select Visual Basic Editor (steps 2 and 3 can be performed by pressing the Alt-F11 keys) If the system issues a security warning : 1. select Macro from menu Tools of the Excel window (not the one in the IDE); 2. select Security, in the “Security Level” Tab select “Medium”; 3. press the OK button and open the IDE; 4. terminate Excel and start it again. Now open the editor. The screen should look like the picture below

Menu Bar Project Explorer Toolbar Properties Window

4

Chapter 1

Note the two windows on the left side: the upper one reports information about the current project (Project Explorer); the lower one lists project properties (Properties Window). If they are not shown, select items Project Explorer and/or Properties Windows from the View menu. We will often use these windows and they will be explained later. Below the main window title we find the Menu Bar, through which all the IDE commands are made available. The most useful of them are:  File to open, save, and print a file  Edit to cut and paste text, undo editing changes, find text, etc.  View to show and hide windows like Watch Window and Immediate Window (used for debugging), Project Explorer and Properties Window, etc.  Format to help the programmer design the graphical interface (line up controls, etc.)  Debug to help the programmer find and correct program errors (this will be explained in a dedicated chapter)  Run to start (run), suspend, and stop program execution  Tools to customize the IDE (e.g. to add new controls or chose particular options)  Help to look up the VBA guide for help: this is a big and complete hypertext document with a vast amount of information and many examples. In order to have access to this feature, item “Visual Basic for Applications Help” must be selected during Microsoft Office installation. An updated version is available through Internet by selecting MSDN on the Web Under the Menu Bar we find the Toolbar, a collection of buttons to rapidly request the execution of common programming procedures, such as adding a new programming module, performing cut and paste operations, undoing a command, running a program, etc. The same commands may be requested through the Menu Bar, but with some more clicks. We will see how to use them when needed.

Introduction

1.3

5

Building a Graphical Interface

Visual Basic generates programs with a graphical interface; that is, each program will have at least a graphical window to interact with the user. We must create this window on the screen for each of our programs. Once started the IDE, click on this button: (left side of the Toolbar). Here is what you get:

Form

A white window opens, containing a gray dotted panel called a form. A form like this represents the main window of the program we are developing (the window is activated and shown when the program is run). The form can be resized moving the small white squares around it. The Project Explorer window reports that another element has been added, named UserForm1. This identifies the form we just added and all the related programming code we write for it. Each time a form (or a

6

Chapter 1

code module, as we will see in Chapter 12) is added, this window is updated to account for it. To remove an element from this window, right click on the element and select Remove from the menu (you will be asked if you want to save it or not). The form will be removed along with all the related graphical settings and programming code. The form we just created is empty, and we have to add some objects (called the controls) to interact with the user, essentially to get data and display results. Besides the two aforementioned windows, another small window was opened (partially overlapping the Project Explorer window). This is the Toolbox Window and groups the most common controls. If it is not displayed, single-click the form and/or press this button: (right side of the Toolbar). More objects can be displayed in this window, but we cannot consider them in this book. To know the name of a control, position the mouse pointer over it and after a second its name is shown in a small window (in figure you see a CommandButton control). Select a control by clicking on its icon, and then draw a rectangle on the form (or just click on it). As an example, we now see how to write text in the form. Select the Label control (icon A) by clicking on it. The mouse pointer turns to a cross sign with a nearby letter A. Position the pointer close to the top-left corner of the form, click with the left mouse button and, keeping it pressed, draw a box, and then release the mouse button. A Label control has been created; its name is automatically assigned by the system as Label1. It displays a text that is initially the same as the control name (“Label1”). You can tell which object of the form is selected from its surrounding dotted frame. The size and position of the selected object may be changed: resize the object by moving the eight small white squares on the frame (the pointer shape changes in a double headed arrow); move the object by moving the frame sides, avoiding the small white squares (the mouse shape changes to a double double-headed arrow).

Introduction

7

The Properties Window lists the properties of the selected object (in this case Label1 is selected). To change the label text, find the Caption property among Label1 properties (it is listed on the left column). Change the text “Label1” on its right by double-clicking on it and entering other text. Write “Subtractor”; then press the ENTER key. The procedure to change the other properties is similar. Now place a button at the center of the form (we will learn how to execute a program by pressing this button): select the CommandButton control icon (see the Toolbox Window figure again) and place a button in the middle of the form. The system automatically assigns the name CommandButton1 to this button. Set its Caption property to “Calculate”. Now try to get a form like the one depicted on the following picture by changing the Font property of both the Label and the CommandButton.

To have multiple copies of the same control, it is possible to repeat the previous procedure several times, but if they have to be identical the best solution is to Copy and Paste them. Select the object, select Copy from the Edit menu, select Edit/Paste as many times as you need, and rearrange the objects on the form (it is possible that the copies are pasted one over the other). The pasted objects have different names (automatically assigned by the system) but the same properties (and the same Caption property too). For example, when you copy control Label1 with caption “XYZ” and paste it three times, you get three new object named Label2, Label3, and Label4; all of them have the same caption “XYZ”. To change the same property in several objects in the form, select them by pressing the Control key and clicking on them. Sometimes it is useful to select

8

Chapter 1

them by drawing an imaginary single box around them: for this, select the arrow control in the Toolbox Windows. You can align and format more controls at once by means of the commands in the Tools menu. It is important to remember that an extensive help is always available, easily reachable through the Help menu or by pressing key F1. The second method gives a different help section according to the context. For example, if you press F1 while setting a property, the help section relative to objects is shown, while if you press F1 while programming, the help section referring to Visual Basic instructions is recalled. Due to the great amount of data contained in the help, finding what you need is not always easy; it is common (especially for a beginner) to spend some time looking for the required information. Moreover, this help is not designed to teach programming, but more to give complete technical details about a topic: it is a tool for a programmer. It is therefore sometimes difficult to use, but once you acquire some knowledge and skills, you will appreciate it.

A First Experiment

2

9

A First Experiment

To start, we will solve a simple problem: a Visual Basic program that prompts the user for two values, and displays their difference. These are the operations we want the computer to execute: 1) 2) 3) 4)

Ask for the first value Ask for the second value Calculate the difference of the first and the second value Show the result

Let us refine our program. First, where will we store the requested values? We have to provide some “containers” for numbers, “small boxes” to use to store values, retrieve them, substitute them with others. These “containers” are called variables. Each container is assigned a name to identify it and to distinguish it from the other containers. In our example, we will call our containers the X and Y variables, for the first and the second value respectively. Our program changes as follows: 1) 2) 3) 4)

Ask for the first value and store it in variable X Ask for the second value and store it in variable Y Calculate X - Y Show the result

The result of the difference of X and Y must be stored in a variable too: let us call it D. After this step, the program becomes: 1) 2) 3) 4)

Ask for the first value and store it in variable X Ask for the second value and store it in variable Y Calculate X - Y and put it in variable D Show D

Let us now express the four instructions in the most schematic way, without unnecessary verbosity. The numbering of lines is not needed: it is obvious that the instructions must be executed in the order in which they are written:

Chapter 2

10 Ask X Ask Y X - Y  D Show D

   

Input Instruction Input Instruction Computation Output Instruction

One of the more common ways to ask the user to enter a value is to open a small window with some text on it that explains what s/he should enter, provide a field where to type in and an OK button to press when done. Such a window is created by the InputBox instruction. Our instruction “Ask X ” now becomes: X = InputBox("Enter first value") When the interpreter executes this InputBox instruction, a small window with the text “Enter the first value” and an OK button will appear on the screen. Then the program will suspend the execution, waiting for the user to press the OK button or the ENTER key (see figure below). At that point, the value s/he typed in the window is stored in variable X (the store action is represented by the equal sign).

We write a similar instruction for “Ask Y”. Y = InputBox("Enter the second value") The calculation is performed by the third line of code. The equal sign takes the result of the expression on its right side and stores it in variable D: D = X - Y Note that the variable used to store the result is to the left of the equal sign and the calculation to be performed is to the right. This kind of instruction is called an assignment. Note that the assignment symbol “=” does not stand for equality; instead, you can read it as “takes the value of ”, so: “D takes the value of the result of operation X – Y ” There are several ways to display values; the most simple is to place what we want to display in a new small window along with an OK button to dismiss it. In Visual Basic, you can get this by means of the MsgBox instruction: MsgBox D

A First Experiment

11

Variable D is what we want to show (more precisely, we are interested in its content). This instruction produces a small window like the one represented below (variable D contains value 4).

Now our four-line program has become a real Visual Basic program that the interpreter is able to understand and execute: X = InputBox("Enter first value") Y = InputBox("Enter second value") D = X - Y MsgBox D Now we want the interpreter to read and execute these lines. There are many ways we can perform this action. We will use one we already know: the form with a button in the middle we created in the Section 1.3. By pressing the Calculate button, the instructions will be read and executed.

It is important now to introduce the important concept of event. The execution of the sequence of instructions of programs that do not have a graphical interface (as those written in languages such as BASIC, Fortran, C, etc.) is suspended only when some input value is required from the user. In languages where user interaction is based on a graphical interface, the programs usually execute some initial lines of code (if any) and then wait for an event to happen. According to the event it receives, one part of the program or another is executed. Microsoft Windows Operating System itself is event driven. So what is an event? It can be seen as a “signal” informing the system that “something” just happened. This could be a key press, a mouse click, a mouse

12

Chapter 2

movement, etc. A wide set of data is associated to an event. Consider, for example, a window like this:

A click on the Yes, NO or Cancel button generates an event of type click, but something must differentiate among the three of them because it essential to know which button has been pressed. In an event driven system, a part of a program (called a subroutine) is executed to processes each relevant event. In the previous example, different actions are be performed depending on which button has been pressed. Let us return to our program. Now we know that the Visual Basic code we just wrote must be associated to a subroutine that “answers” to the event click performed on CommandButton1. To associate our code to the button, doubleclick on the button itself: a window called UserForm1 (Code) opens; a couple of lines are already there. Place the four lines of our code between these two lines. You will get a window like this:

The first of the two lines automatically provided in the code window is: Private Sub CommandButton1_Click() It is composed of the following parts (ignore the Private keyword):  keyword Sub specifies that this is a subroutine: an isolated block of code lines  CommandButton1 says that this is a subroutine associated to the CommandButton1 button  Click() says that this subroutine is for answering to an event of type Click on that CommandButton

A First Experiment

13

Before executing our program, it is good practice to save it to disk. To do it, select Save from the File menu. This saves the program and the graphical interface along with the Excel workbook from where we started: our program and our interface are part of the Excel file. Excel (Word, PowerPoint, etc,) calls this program a Macro. Macro stands for Macroinstruction; that is, a new command that a skilled user creates to speed some repetitive or complex task. For example you can write a Word macro (and associate it to a new button on the Toolbar or a keyboard key) to change the selected text to Arial, italic, 12 points, red on purple font (a sequence which requires a long time to be executed manually) all in one go. We are now ready to execute (run) our program. In the main IDE window, in the top-center area of the Toolbar, there are three icons: . From left to right their meaning is: Run, Pause, and Stop. To execute the program, click on the small triangle (or press key F5). The program is now running. It displays the window with the Calculate button and waits. What is it waiting for? Events! Actually, the only event it is waiting for is the Click event on the CommandButton1 button (events that do not have a corresponding subroutine are ignored). Press the Calculate button (CommandButton1 button). The first of the two InputBoxes is executed: it displays a small window prompting for the first value. Enter a value. The input window does not disappear until we press the OK button or the ENTER key. At that time, the value you entered is stored in variable X and the execution continues to the next line of code, where the second InputBox is executed. After having entered the second value and pressed OK or ENTER, the execution continues to the next line. Here the subtraction is performed and the result is stored in variable D. This instruction does not involve the user (it is not an input/output operation), so its execution is not perceived by the user (it is extremely fast). After the assignment, the MsgBox instruction is executed; a window with the value of D is displayed. The window is closed when you press OK or ENTER; then the program starts waiting for an event again. To stop the program press the Stop button or close the window by clicking on the window top-right corner button: . Usually program termination is obtained in other ways, for example by pressing a button with caption End. As an exercise, insert such a button in the program. The associated subroutine will have only one instruction: End, which stops the program. If you performed the right actions, the newly created button is automatically named CommandButton2 and the CommandButton2_Click() subroutine has three lines (you wrote only the central one with keyword End). Remember that in order to modify a program

Chapter 2

14

it must not be running (if the system doesn’t allow you to modify a program, check if it is running and stop it). It is possible to write more than one instruction in the same line, providing they are separated by colons: D = X – Y : MsgBox D This practice is seldom used because it negatively affects the clarity and readability of the program. Long lines can be broken into two lines typing the “_” character preceded by a space and continuing to write in the following line. The two lines are logically the same. Lines can be broken everywhere a space character is allowed, but not within a string (you will learn about strings later in this book). For example, instead of writing: X = InputBox("First value", "Value", "0") it is possible to write: X = InputBox("First value", _ "Value", "0") In this example, you cannot break the line after the word First because in that case the space is within a string (i.e. enclosed in quotation marks).

2.1

Exercises

1) Write a Visual Basic program that prompts the user for 3 values A, B, and C and shows in three different MsgBoxes the results of the following calculations: A – B, A – C, and A – B – C. 2) Write a Visual Basic program that prompts for 2 values A e B, exchanges the content of the two variables, and shows them. For example, if A is assigned value 12 and B is assigned value 27, after the exchange A contains 27 and B contains 12). Do not solve this problem by writing a program that simply displays the variables in reverse order! In other words, the skeleton of your program should be this one: A = InputBox("Enter value for A") B = InputBox("Enter value for B") write the exchange operations here MsgBox A MsgBox B

Variables and Numerical Types

3

15

Variables and Numerical Types

We said that variables are “containers” for numbers; more properly, variables are data containers: numbers are just one possible type of data. Variable names are composed by at least 1 character, at most 256; the first character must be a letter, the others may be letters, digits, and the underscore character. It is good practice to use for variables names related to the meaning of their content: developing and debugging code will be easier and simpler. Variable names must not be language keywords; for example, you cannot name a variable InputBox, MsgBox, If, or For. Variables name starting with a lowercase letter are preferred. Valid variable names are the following: A i sum sum_2 sumRaisedTo2 Visual Basic does not distinguish between uppercase and lowercase letters, so variables SUM and sUM are the same. A variable can be used as a term in a mathematical expression (e.g. X – Y), or can be assigned a value in an assignment statement (e.g. S = 3 + 5). Note that the equal symbol “=” does not stand for equality, in mathematics A=B is an expression that indicates that A contains the same values of B, and vice versa. In Visual Basic (as in most programming languages) A=B means that A takes the value of B (B still contains that value: this is a copy of the value, not a transfer). So, while in mathematics A=A+1 is an absurd, in a programming language it means that after having executed this statement, A has been incremented by 1. Besides the name, variables also have a data type associated to them. There are variables suitable to contain integer values, variables suitable for floating point values, variables suitable for sequences of characters (called strings), variables suitable to contain only two logical values (True and False), and special variables suitable to contain any data type (called the variant type). More data types exist, but are outside the scope of this book

Chapter 3

16

The Visual Basic interpreter needs to associate every variable to a type. In case the type of a variable is not specified, type Variant is assigned. It is good practice to avoid the implicit declaration. It is also discouraged the use of Variant variables, due to some strange problems which may arise (we will see an example later) and, more important, because it may indicate that the programmer has no clear ideas of what s/he is planning to do with that variable. In a declaration (or definition), the data type of a variable is established and memory is reserved (“allocated”) accordingly. Usually all the variables are declared together at the beginning of the program (e.g. just after the Private Sub statement). The Dim statement is used to declare a variable: Dim Name As Type where Name is the variable name and Type its data type.

3.1

Numerical variables

In Visual Basic, there are two integer types (two’s-complement) and two real types (floating point IEEE P754, mantissa and exponent). The two integer types are called Integer and Long; the two real types are called Single and Double. Here are the details you need to know:  An Integer variable requires 2 bytes and may contain whole values between –32768 and +32767 (about ±30000).  A Long variable (long integer) requires 4 bytes and may contain whole values between –2147483648 and +2147483647 (about ±2109); a Long variable can contain any Integer value.  A Single variable (single precision) requires 4 bytes and may contain values between (about) 1.410–45 and 3.410+38, positive and negative, with a precision of about 7 digits (base 10), e.g. –0.123456710–12. A Single variable can contain any Long value.  A Double variable (double precision) needs 8 bytes and may contain values between (about) 4.910–324 and 1.710+308, positive and negative, with a precision of about 15 digits, e.g. –0.1234567890123451023. A Double variable can contain any Single value. A Variant type is not strictly a numerical type; a variable of this type can contain values of any type, including numerical and string types. The number of bytes it uses depends on which value type is stored. It shows unusual behavior that must be known to the programmer (as an example, try to modify the “Subtractor” exercise by making a sum instead of a subtraction: the +

Variables and Numerical Types

17

symbol does not compute a sum, but places the values side by side! The explanation of this (not so) “strange” behavior is deferred to the chapter where strings are studied, in particular to the Val function described in Section 6.2). Try to avoid this type when possible. Floating point computing is slower than integer computing, and the more bits there are to process, the slower is the computation. Memory size requirements may also be important to consider: if you need a one-million element matrix with integer values between 0 and 100, you can do it with both Integer and Double types, but the memory occupation of that variable would be 2MB if the values are of type Integer, 8 MB if you use Double. The computation is slower in the latter case because there are 4 times as many bits to process and for the lower performance intrinsic of floating point types. In summary, in order to achieve better performance and less memory usage, it is advisable to:  use type Integer when possible;  if it is not sufficient to represent the values you need, then use type Long;  if this is still too limited for your needs or if you work with fractional values, use type Single;  and only if this is still too limited for your range or precision requirements use the 15 digits of a type Double. We also consider Boolean as a numerical type; a variable of this type can contain only two values: True and False. In an arithmetic context, these logical values are evaluated as numerical values –1 and 0, respectively. On the contrary, in a logical context value 0 is considered equivalent to False, any other value to True. We will use Boolean variables later. Here is a beginner’s common mistake: Dim A, B, C As Integer Such a declaration defines only C as an Integer, while A and B are defined as Variant. The right declaration to have A, B, and C as Integers is: Dim A As Integer, B As Integer, C As Integer However, this is not much of an improvement with respect to: Dim A As Integer Dim B As Integer Dim C As Integer Sometimes programmers like to add a comment at the end of variable definitions. In this case the multi-line declaration form is more convenient: Dim A As Integer 'coeff. a of the 2nd degree equat. Dim B As Integer 'coeff. b of the 2nd degree equat. Dim C As Integer 'known term of the 2nd deg. equat.

18

Chapter 3

3.1.1 Numerical Expressions Algebraic calculi between values are called expressions. An expression results in a value that can be stored in a variable, compared to other values, printed, etc. An expression is composed by operators (+, –, *, /, etc.), variables, constant values, functions (Sin, Cos, Tan, etc.), and parentheses. In the example below, the expression to the right of the equal sign is evaluated, and the result is assigned to variable Delta: delta = b ^ 2 – 4 * a * c The following table lists Visual Basic numerical operators. Operation Symbol + Sum – Subtraction * Product / Division \ Integer division Mod Remainder ^ Power raise Remarks: 1) The division / between integer values produces a fractional value (3/2 gives 1.5); this behavior is different from other programming languages. 2) The integer division \ and the remainder (modulus) Mod operators may be applied to fractional values too, but the values are first rounded to the nearest integer values and the result is then truncated to the left integer value (5.4 \ 2.6 is evaluated as 5 \ 3, and the result is 1, not 1.666667). 3) The Mod keyword must be used as a symbol: X = 17 Mod 5 computes the remainder of the division of 17 by 5 and the result 2 is stored in X. 4) The power raise ^ requires a positive base when the exponent is fractional (e.g. 3 ^ 2.2). 3.1.2 Evaluation of Numerical Expressions When an expression is evaluated, intermediate values are temporarily stored in “nameless” variables (the programmer does not need to use them directly, so it is not necessary to identify them). When a computation is completed, the intermediate values (i.e. the nameless variables) are not needed anymore and are deleted (removed from memory). As an example, let us consider the instruction X=A+B*C without taking into account the variables types and referring to the following picture.

Variables and Numerical Types

19

The first operation to be computed is the X = A + B * C product B*C, and its result is stored in a nameless variable (for the sake of explanation, we need to call it in some way and thus we  name it ). Then  is added to A, and the result is stored in another nameless variable (). Finally  is copied to X and the two  intermediate nameless variables are deleted. Which types have the nameless variables? When a computation involves two values (variables or constants) of the same type, the type of the result (i.e. the intermediate nameless variable) is the same as the type of the two operands. If variables named A, B, and C of the previous example are of type Integer, then also  and  are of type Integer (we will discuss about variable X later). When the two values are of different types, the value associated to the smaller type is automatically converted (promoted) to the larger type (remember that a Long variable can contain an Integer value, a Single variable can contain a Long or an Integer value, a Double variable can contain a Single, a Long, or an Integer value). Promotion creates an intermediate variable with the value of the promoted variable and the same type as the larger between the types of the two operands. For example, when an Integer value and a Single value are added, a Single (floating-point) intermediate value is created for the Integer (two’s-complement) variable value; THEN the sum can be calculated. Note that the promoted variable remains unchanged: its type was defined by a Dim statement and cannot be changed; while the temporary variable has a new type, but the same value. The computation is performed using this temporary variable instead of the original one. Let us consider again the previous example, X = AS + BS * CI but including types. The type is indicated by the top-right letter: I stands for Integer, S for Single. See side picture. S The first operation to be performed is: B*C. The two variables have different types (B is of type Single and C of type Integer). Of S the two types, the larger type is Single, therefore a temporary nameless Single variable () is created in order to store the S value of C. The multiplication between B and  (that contains the value of C) can now be

20

Chapter 3

performed. The result value is temporarily stored in a variable () with type Single. The next operation is the addition of  to A, and because their types are the same (Single), no promotion is required. The type of the temporary variable () is Single. Its value is copied into variable X and all the temporary nameless variables are removed. In the example above, let A = 5.2, B = 2.1 and C = 3. The promotion gives  = 3.0, the multiplication 2.1*3.0 gives  = 6.3, and the sum gives  = 11.5. The promotion of a value to a different type is performed at the very moment it is needed; see the example in the following box.  The first intermediate operation is the B*C X = AS + BI * CI product, the two variables are of the same type (Integer), so the result  is a temporarily variable of type Integer. I  In the addition of  (Integer) to A (Single), a preliminary promotion of  is required; resulting in another temporary S variable  of type Single.  The sum of  and A is then computed; the result  is a variable of type Single. S  The variable  is stored in X, and the temporary variables removed. Let us consider now another example: Dim A As Integer, B As Integer, C As Long A = 30000 B = 2 C = A * B Even if C may contain value 60000 (the product result) because its type is Long, the program stops for an error: overflow. This error happens because both A and B have Integer type: the system will try to store their product in a temporary variable of the same type (Integer), but 60000 exceeds the Integer range. It does not matter that C is a variable of type Long, because it is the computation itself that produces an overflow, not the assignment to C (the assignment is not even attempted: the error happens before). How do we solve this problem? Among the many possible solutions we have: 1) Define one of the variables of type Long; in this way, the other variable is promoted to Long and the intermediate variable is of the same type, so there is no overflow. You might define both variables as Long, too.

Variables and Numerical Types

21

2) Explicitly request the Visual Basic interpreter to promote at least one of the variables to type Long; in this way, we have the same situation as in the previous case. This explicitly requested promotion is called a conversion (promotion is automatic, conversion is requested) and it is achieved through a conversion function. This second method allows the programmer not to change the types chosen for the variables and is therefore preferred. 3.1.3 Type Conversion Functions These functions create temporary variables of the requested type, containing the value of the expression indicated between their parentheses. Int(A) converts the value of A to an Integer value (creates a temporary variable of this type) by truncating the fractional part; it returns the integer value to its left-hand side. +3.2  +3 +3.6  +3 –3.2  –4 –4 –3.6 –3.2 –3 0 3 3.2 3.6 4 –3.6  –4 Fix(A) converts the value of A to an Integer value by truncating the fractional part; it returns the integer value towards 0. +3.2  +3 +3.6  +3 –4 –3.6 –3.2 –3 0 3 3.2 3.6 4 –3.2  –3 –3.6  –3 CInt(A) converts the value of A to an Integer value rounding it to the nearest integer value. +3.2  +3 +3.6  +4 –3.2  –3 –4 –3.6 –3.2 –3 0 3 3.2 3.6 4 –3.6  –4 Values like x.5 (positive and negative) are rounded: - to the next integer value, if x is odd; - to the previous integer value, if x is even.  2 CInt(1.5) CInt(2.5)  2 CInt(–1.5)  –2 CInt(–2.5)  –2 CLng(A) converts the value of A into a Long value (same remarks as CInt). CSng(A) converts the value of A into a Single value. CDbl(A) converts the value of A into a Double value.

22

Chapter 3

Here is how to solve the overflow problem we saw before: C = A * CLng(B) or C = CLng(A) * B or C = CLng(A) * CLng(B) Note that the following statement would not fix the problem: C = CLng(A*B) because the computation of (A*B) would again generate an overflow condition, because it would be performed on Integer values using a temporary Integer variable for the result. When the result of an expression is assigned to a variable, a type conversion to that variable type is automatically performed (this happens when passing arguments to functions and subroutines too). The conversion function implicitly used is one among CInt, CLng, CSng, or CDbl. Let us consider the following example: Dim A As Single Dim X As Integer A = 2.342 X = A The last assignment is performed as if it were written as: X = CInt(A) It is worth noting that, differently from other languages, the assignment of a real value to an integer variable does not truncate the fractional part, but rounds it up to the nearest integer (and you have to remember the x.5 behavior already described). If truncation is required, functions Int or Fix must be used. Even though more conversion functions are available, but are outside the scope of this book.

Variables and Numerical Types

23

3.1.4 Intrinsic Functions These functions are provided by the interpreter itself; that is, they are internal and not supplied separately in external software libraries (as it is common in other languages). The intrinsic functions generally accept any numerical type and return a value (a temporary variable) of type Double. Here are some: Function Meaning Sin(A) sine of A Cos(A) cosine of A Tan(A) tangent of A Atn(A) inverse tangent of A Log(A) natural logarithm of A Log10(A) common (decadic) logarithm of A Exp(A) e raised to A Abs(A) absolute value of A Sqr(A) square root of A Sgn(A) sign of A: –1 if negative, 0 if zero, +1 if positive Remarks: 1) Trigonometric functions angles are expressed in radians (1  rad = 180°); 2) The function Sgn returns a value of type Variant. More details on these and other functions may be found in the help guide. 3.1.5 Operators Priority and Associativity An expression may contain several operators, and the result depends on their evaluation order. For example, A+B*C gives a certain result if multiplication is evaluated first, and then the sum; but another value would result if the order is reversed. Clearly, the multiplication is calculated first because the language has been designed to be in accordance with the classical arithmetic rules; technically speaking the product has higher priority over the sum. In the following list, the operators are shown in decreasing priority order:  Parentheses  Functions  Power  Multiplication and division  Integer division  Remainder  Sum and subtraction Higher priority operators are evaluated first, unless parentheses are used to force the evaluation in a different order. For example, if we want to calculate

Chapter 3

24

the sum before the multiplication, we must write (A+B)*C. Redundant parentheses may help understanding complex expressions. The same operators may be used more times in an expression; moreover, some operators have the same priority level (sum and subtraction, multiplication and division). Here are some examples: A–B+C A*B/C A*B*C A–B–C A^B^C In such cases, the associativity rules apply. In Visual Basic the only associativity rule is: when operators have the same priority, they are evaluated from left to right (this is different from other languages, in particular for the power raise). So, the previous expressions are evaluated as if parentheses were used as shown below: (A–B)+C (A*B)/C (A*B)*C (A–B)–C (A^B)^C

3.2

Numerical Constants

Expressions may contain constant values as well. For example, the area of a triangle can be calculated using the expression BASE*HEIGHT/2, where “2” is a numerical constant. Numerical constants are stored in permanent and nonremovable nameless variables, and their types is determined as follows.  An integer constant is a sequence of decimal digits without a decimal point or an exponent. Its type is Integer if the value is within the Integer range; otherwise it is of type Long. Examples of Integer constants are: 1234, –23438. Examples of Long constants are: 123456, –234567.  A floating-point constant is a sequence of decimal digits with a decimal point (even in non-English MS-Windows versions) and/or an exponent (a positive or negative whole value). Its type is Single if the number of digits is small enough not to loose precision; Double otherwise. Examples of Single constants are: –1234.625, 23.0, 34E4 (which means 34104), –23.625E–18 (which means –23.62510–18). Examples of Double constants are: –12345.6789012121, –12.4 (0.4 converted to binary is periodic!), 34E204 (which means 3410204), –23.4E–18 (which means –23.410–18).

Variables and Numerical Types

25

It is possible to request a specific type for a constant by adding a trailing character to the value itself:  example of an Integer constant: 12%  example of a Long constant: 12&  example of a Single constant: 12!  example of a Double constant: 12# So, the expression A*12! is a multiplication of A by a Single constant having value 12 (even if there is no decimal point and no exponent). Here is an example showing when it is useful to define the constant type. Imagine you have to calculate the areas of a million of triangles. Bases and heights are read from a file and stored in variables of type Single. If you use the straightforward formula B*H/2, constant 2 is stored as an Integer; so, each time the division is performed, it is promoted to a Single value, one million times! While, if you use the formula B*H/2!, constant 2 is already of type Single and one million promotions are saved. It is sometimes useful to assign a name to a constant value; here is how to define a Single constant named Pi and a Double constant named hPlank (it is not possible to use an arithmetic expression): Const Pi As Single = 3.141592 Const hPlank As Double = 6.626176E-34 You cannot define a constant using an expression, so it is WRONG to write: Const Pi As Single = 4 * Atn(1) In this case, you would need to use a variable instead. The input of fractional numbers follows the regional settings of your Operating System; in an English MS-Windows, you use a decimal point, while other localizations may require other symbols. On the contrary, Visual Basic code requires decimal points.

Chapter 3

26

3.3

Exercises

1) Write a program that asks the user to enter 4 integer values (Integer or Long), and then calculates and prints their average (the result must have the fractional part). 2) Write a program that asks for a temperature value (of an integer type) expressed in Fahrenheit degrees, and calculates and prints the corresponding values expressed in Celsius and Kelvin degrees (both with fractional part). [C=5/9*(F–32); K=C+273.15]. 3) An object moving with speed v near to light speed c (2.99793ꞏ108 m/s) shortens along the moving direction and gets heavier by a factor  (less than 1). Write a program that asks for the length and the mass 2 v of a still object and calculates their variation at a speed   1    c requested from the user (in km/s). 4) Write a program to calculate the shortest distance between two points on the surface of the Earth, given their geographic coordinates. The program requests the latitude and longitude values (in degrees) of the two points, and displays the distance between them. To compute the distance, use the following formula (remember that North and East coordinates are positive values, South and West negative, and that trigonometric functions use radians):

d  arccos( p1  p2  p3)  r

where: p1 = cos(lat1)*cos(lon1)*cos(lat2)*cos(lon2) p2 = cos(lat1)*sin(lon1)*cos(lat2)*sin(lon2) p3 = sin(lat1)*sin(lat2) lat1 is the latitude in degrees of the first point lon1 is the longitude in degrees of the first point lat2 is the latitude in degrees of the second point lon2 is the longitude in degrees of the second point r is the average Earth radius (6372.795 km or 3441.034 NM, this approximation results in an error of up to about 0.5%) The inverse cosine can be calculated by the following formula:

 x arccos( x )  arctan  2  1 x

     2

Calculate the distance between Turin International Airport (TRN, Italy, 45.02o N, 07.65o E) and Los Angeles International Airport (LAX, USA: 33.94 o N, 118.40o W). [Answer: 9692.702 km or 5233.640 NM]

Keyboard Input and Screen Output

4

27

Keyboard Input and Screen Output

When referring to input/output (I/O) operations, it must be considered from the point of view of the microprocessor. So, in an input operation a value is taken from outside (for example from keyboard) and stored in a variable; while in an output operation a value is sent outside (for example to the video display). This chapter provides further information on the InputBox and MsgBox instructions described earlier. Visual Basic has several other Input/Output instructions, but these two are the most common and simple; we use only these so that we can concentrate on program structure more than on aesthetic issues.

4.1

The MsgBox Instruction

The MsgBox instruction creates a small window to display the value of a variable, the result of an expression, or a portion of text. A more detailed (however still incomplete) syntax is shown below; the parentheses may be omitted, when used they must enclose the prompt only: MsgBox (prompt), buttons, title prompt is what is to be shown, title is the window title, and buttons is used to display other buttons besides the OK button (we will not cover detailed buttons issues). Here are some examples. MsgBox 12  displays number 12 MsgBox 3 * X  displays the result of the expression 3*X. To display a string (a sequence of characters), enclose it in double quotes: MsgBox "Hello" A typical beginner’s error is to forget the double quotes. When a missing double quote MsgBox is executed, an empty box appears. What happened? The Visual Basic interpreter considers Hello as a variable name, being the first time it encounters this word in the program (if it has not been declared by a Dim statement), so it declares it as an implicit variable of type Variant, and this variable is initially empty. Therefore, the MsgBox function shows its content: nothing, resulting in an empty window. In Section 14.1 we will see how to avoid this problem by using directive Option Explicit. To display more elements side by side in the same window, join them to form a single prompt string (because the MsgBox function requires just one prompt).

28

Chapter 4

The elements are joined in a single prompt by the & character (remember to always put a space before and after character &): MsgBox "There are " & X & " values" In this example there are two sequences of characters (strings): the first is composed by characters “There are ”, and the second by “ values”. Suppose that X = 1; then the MsgBox instruction will display the text: There are 10 values Note the spaces after string “are” and before string “values”: these are inside the strings, if we omit them, the result is: There are10values The MsgBox instruction converts into a string the content of the prompt element; numerical expressions are evaluated and the result converted to a string. Character & itself, which joins two strings (the correct term is to concatenate), converts into a string even a numerical value (in the previous example, variable X has a numerical type, but it is converted to the character sequence composed by characters “1” and “0”). Both title and buttons may be omitted, as we did in the “Subtractor” experiment. To specify just the title and omit the buttons, the two commas must be left to indicate that the second option (buttons) is intentionally missing. Again, note the closing parenthesis position with respect to commas: MsgBox "There are " & X & " values",, "Count" The output window is shown on the right; “Count” is the title. To display more lines in a MsgBox, lines must be broken where appropriate by the vbNewLine constant string. When the value of this constant is displayed, a new line is inserted there. To write on three lines the previous prompt we can write: MsgBox "There are" & vbNewLine & X & vbNewLine & "values" Constant string vbNewLine is defined by the system (you do not need to define it); being a string, it must be concatenated to the rest of the text using the & character. The output window is shown on the right.

Keyboard Input and Screen Output

4.2

29

The InputBox Instruction

We already used the InputBox keyboard input function. A more detailed (but still incomplete) syntax is shown below. The parentheses cannot be omitted; again, note the position of the closing parenthesis: variable = InputBox(prompt, title, default) All that has been said about the MsgBox prompt applies to the InputBox prompt too. During the execution of this function, the program stops waiting for a value. When the OK button or the ENTER key is pressed, the value entered using the keyboard is put in a temporary variable of type String (more on this later) and then copied (possibly after using an implicit conversion function like Cint) to variable. title is used to give the window a title, as in the MsgBox (but here title appears as the second element). default is the more common input value expected from the user for this request, so it is already placed in the input field for user convenience: if that is the value you would like to enter just press OK, otherwise change it. Example: X = InputBox("First value", "Value", "0") When this InputBox instruction is executed, the window below is opened on the screen. It is assumed here that the most common answer for this input window would be 0, so the default parameter is set to “0”. The user can type a different value if needed.

Default means that something is missing; in Computer Science, a default value is one that is automatically used when a specific value is not specified. For example, when you print a document, the printer is already set to print just ONE copy of your document, because this is the most usual case. If you need to print more copies, you do not accept this default value and set the one you need. Remember that the input of fractional numbers follows the regional settings of your Operating System; in an English MS-Windows, you use a decimal point, while other localizations may require other symbols.

Chapter 4

30

As the InputBox instruction returns a string, when a number must be read ad assigned to a numerical variable (as in the example) the string is first implicitly interpreted by function Val (see 6.3.6 at page 50) to get the numeric value and this is then converted by one of the conversion functions CInt, CLong, CSng, and CDbl (and again you have to remember the x.5 behavior already described).

4.3

Exercises

1) Write a program that asks for 4 integers numbers and prints them one over the other in the same MsgBox.

Conditional Execution

5

31

Conditional Execution

The programs we have seen so far are composed by a sequence of instructions executed one after the other in the same order in which they are written. In many practical situations, some instructions have to be executed only if certain conditions are verified and other instructions in the other cases. For example, in a generic program where you have to compute the square root of a value, you first must determine if the value is greater than 0, and then compute the square root only in that case. This is called a conditional execution: some instructions will be executed only IF a certain condition is True.

5.1

The If-Then Statement

The main conditional statement is the If-Then statement: If condition Then instructions End If IF the condition is True, THEN the instructions included between the Then clause and the End If clause are executed. On the other hand, if the condition is False, the instructions are not executed. In both cases, the execution flow continues after the End If clause. Note that the Then clause must be the last (rightmost) word of the line where the If clause appears. The block of instructions depending on condition is written shifted on the right (indentation) by some spaces (3 are suggested) so that dependence of a previous statement is visually evident. Here is an example: F T num = InputBox("Enter a number") N>0 If num > 0 Then POS MsgBox("Number is positive") End If MsgBox("END OF PROGRAM") In this example a number is requested to the user; if it is a positive value, then a first MsgBox with the text “Number is positive” is displayed, and then another one is shown with the text “END OF PROGRAM”. If it is a negative or

32

Chapter 5

null value, the MsgBox inside the If block is not executed and only the MsgBox with the text “END OF PROGRAM” is displayed. It is possible to graphically represent the flow of this program by means of a scheme called a flow chart; you find it at the right of the code fragment (the flow chart actually represents just the If statement). The rhombus indicates the condition (the expression used as the condition is written inside); two branches start from it, labeled with T (for True) and with F (for False). The T branch, called the then branch, is followed when condition is True; the F branch, called the else branch, when it is False. Within the then branch, we find the instruction, which is represented in the flow chart inside a parallelogram (a parallelogram is used to specify an I/O operation, a rectangle otherwise). In this example, the else branch does not include operations, and therefore it is just an arrow in the flow chart. If we want the program to print something even in the case where the number is not positive, we can modify it as F T N>0 follows: num = InputBox("Enter a number") POS If num > 0 Then MsgBox "Number is positive" T F N0 End If If num 0 MsgBox "Number is positive" Not Else POS POS MsgBox "Number is not positive" End If MsgBox "END OF PROGRAM" In this example, if the number is positive, the If condition evaluates to True

Conditional Execution

33

and the then branch is executed; so a MsgBox displays the text “Number is positive”. If the number is negative or null, the condition is not True and the execution flow goes through the else branch (the instructions after the Else clause); so, a MsgBox displays “Number is not positive”. In the end, in any case, another MsgBox displays “END OF PROGRAM”. It is a beginner’s common mistake to write a condition also in the Else clause. This is not required because the appropriate condition is implicit. Let us now modify the program so that it displays “Number is null” when the number entered is 0. num = InputBox("Enter a number") F T N>0 If num > 0 Then POS MsgBox "Number is positive" End If F T If num < 0 Then N 0 Then MsgBox "Number is positive" outer If statement Else If num < 0 Then MsgBox "Number is negative" inner If statement Else MsgBox "Number is null" End If End If MsgBox "END OF PROGRAM"

Chapter 5

34

If the number is positive, the then branch of the first (outer) If statement is executed; if it is negative or null, the else branch is followed. In the else branch of the outer If statement, another complete If-Then-Else-End If statement is present to separate the two remaining cases: negative or null value. In this way we have minimized the number of conditions to evaluate and conditional statements to execute. Note that the inner If-Then-Else-End If statement is completely inside a branch of the outer one. The corresponding flow chart is depicted in the following picture. F

F

NUL

N0

T

POS

NEG

The need of a multiple choice is so frequent in programming that Visual Basic provides a further variation of the If statement by introducing the ElseIf clause (there is no space in the name): num = InputBox("Enter a number") If num > 0 Then MsgBox "Number is positive" ElseIf num < 0 Then MsgBox "Number is negative" Else MsgBox "Number is null" End If MsgBox "END OF PROGRAM" Note that there is only one End If clause and all the branches are indented at the same level. The execution flow is a follows: IF Number is positive THEN print “Number is positive”, ELSE IF Number is negative THEN print “Number is negative”, ELSE print “Number is null” because it is the last possible case. The condition of an ElseIf clause is evaluated only if none of the previous If and ElseIf conditions evaluated to True. That is, if a positive number is entered, a MsgBox displays “Number is positive” and every other statement up to the End If clause are skipped. This second form is identical to the previous one with nested If statements, but simpler to write and understand.

Conditional Execution

35

The complete form of an If statement can be summarized as follows: If condition1 Then instructions1 ElseIf condition2 Then instructions2 ... Else instructionse End If

The optional ElseIf clause may be repeated as many times as necessary to consider all the cases; while the optional Else clause must be unique: this is the case that groups all the conditions not expressed by the previous If/ ElseIf conditions. This is called the default case. A scheme with more ElseIf clauses and without an Else clause is correct: if none of the conditions evaluates to True, the whole If-Then-ElseIf-Else-End If statement does not produce any effect (none of the instructionsx blocks is executed), but each conditionx is evaluated and this consumes some CPU time. Note how this code is written:  Keywords If, ElseIf, Else, and End If are at the same distance from the left margin, this evidences the branches.  Keywords If, ElseIf, Else, and End If may be preceded only by spaces.  Keywords Then and Else must be the last word in the lines where they appear; keyword Then must also be in the same line as the corresponding If/ElseIf keyword.  The blocks of code identified by instructionsx may be composed by several lines of code; they are all shifted to the right by the same amount of space to visually emphasize the statement they depend on (indentation). In the general case, the various conditionx may be unrelated. For example, the following program asks for 2 values and:  if the first value is greater than 10, it is printed;  otherwise (the first value is less than or equal to 100), if the second value is less than 100, it is printed;  otherwise (the first value is less than or equal to 10 AND the second is greater than or equal to 100), the product of the first value by the second value is printed.

Chapter 5

36

firstValue = InputBox("Enter first value") secondValue = InputBox("Enter second value") If firstValue > 10 Then MsgBox firstValue ElseIf secondValue > 100 Then MsgBox secondValue Else MsgBox firstValue*secondValue End If

5.2

Relational Expressions

Conditions typically are a comparison between two values; for example, in: If X = 10 Then ... variable X is compared to value 10; the result is True if X contains value 10, False otherwise. More generally, a comparison is made between the results of two mathematical expressions: If X*(Y-Z^2) = Z-T*3.14 Then ... The comparison operators, called relational operators, are: Operator

Symbol = Equal

Different > Greater than >= Greater than or equal to < Less than Pi*radius^2 If isGreater Then ... Variable isGreater will contain value True or False depending on whether area is greater than the circle area or not. In case isGreater were an Integer variable, the values assigned would be –1 and 0: value 0 in a Boolean context is equivalent to False, while any non-null value is equivalent to True, but when produced by Visual Basic, the numeric value of True is –1. As any non-null value is considered equivalent to True, then in a condition like X0 the “0” part may be omitted. E.g. If (X) Then ...

Conditional Execution

5.3

37

Logical Expressions

A condition may be composed by several comparisons; the overall result depends on the result of each of them. For example, the need may arise to have a complex condition considered True if at least one of the elementary comparisons evaluates to True. A different requirement could be that all the elementary comparisons evaluate to True in order to have a True value for the overall expression. More precisely, operators that connect relational expressions are used, these are called logical (or Boolean) operators. 5.3.1 The Or Operator When we want an overall condition to be True when at least one (or more) comparison(s) evaluate to True, we use the Or operator: If age = 65 OR monthDay = 1 Then MsgBox "Free entrance to the Museum!" End If Here, the overall condition is True if Age is less than 12, or Age is greater than 65, or MonthDay is equal to 1. The overall condition is False only if none of the three conditions is True. 5.3.2 The And Operator When we want an overall condition to be True only when all the comparisons evaluate to True, we use the And operator: If year >= 2000 And year 10 Then ... and If Not(X 10 Or Y < 14 And Z = 3 * X * Y) Negated expressions may be simplified by using De Morgan’s Laws, but sometimes the resulting expressions are less clear.

5.4

Operators Precedence

In a condition, expressions are evaluated in this order: arithmetic, relational, and logical. The priority of the logical operators is (in decreasing order): Not, And, Or, and Xor. The following example: If a>10 Or b>10 And c>10 Then ... is evaluated by the interpreter as if there were the parentheses as shown below: If a>10 Or (b>10 And c>10) Then ... Suppose we have a=20, b=0, c=0:  the And operator gives False (both comparisons b>10 and c>10 are False),  but the first relation a>10 is True and it is in Or with the And result (Or is evaluated after the And),  then the overall result is True. Parentheses may be used to force the evaluation in a different order. In the following example, the Or operator is evaluated before the And: If (a>10 Or b>10) And c>10 Then ... In this other example, the Not operator is executed first, followed by the And: If x>0 And Not y value

We have already seen the first case; the second one considers values between value1 and value2 (limits included); and the third one considers all the values greater than value. In the latter case, all the comparison operators can be used. Each value may be a string, a constant, a variable, or an expression: Case "Hello" Case 12*X-23 Case 11.4-Y To 3-Y*Z Case Is > N^(X-Y)

Conditional Execution

41

To associate more values to a single Case branch, list them separated by commas (beware that you cannot put a logical operator here). Examples: Case value1, value2, value3 Case value1 To value2, value3 To value4 Case Is > value1, Is < value2 Case value1, value3 To value4, Is > value5 What happens if ranges overlap? The first Case clause that satisfies the comparison is executed, and the others are skipped, even if they too satisfy the condition. Here is an example: num = InputBox("Enter a number between 0 and 10") Select Case num Case Is > 10, Is < 0 MsgBox "It isn’t between 0 and 10!" Case 2,4,6,8,10,12 MsgBox "Even" Case 5 To 9 MsgBox "It is between 5 and 9" Case 1,3,5,7,9 MsgBox "Odd" End Select If value 12 is entered, the first Case condition matches and the text “It is not between 0 and 10!” is displayed; the second Case is not considered, even if number 12 is explicitly indicated. If value 8 is entered, the first condition is not satisfied; the second one applies and the text “Even” is displayed; the third Case is not considered even if it would apply. For values 5, 7, and 9 the “Odd” text is not displayed because the previous Case applies. A couple of beginner’s frequent mistakes, often found together: Select Case var = expression You cannot write var = because you can only use an expression in the Select Case clause. Note however, that this is syntactically correct (which means that the interpreter does not complain): it is a comparison between var and expression, which produces a True or False value, and this Boolean value is searched among the valuei. Case var = 1 Case var = 2 You cannot write var = because you just have to put the possible results of expression to the right of each Case clause. Note that here, too, the syntax is correct: the resulting match value for expression is a True or False value.

Chapter 5

42

5.6 1) 2) 3) 4) 5)

6)

7)

8)

9) 10)

Exercises Write a program that requests 2 values and prints the greater. Write a program that requests 3 values and prints the greatest. Write a program that requests 3 values and prints them in a decreasing order. Write a program that requests a value and prints “Even” or “Odd” (use Mod). Write a program that requests a value corresponding to a grade and prints “below the pass” if it is less than 18, “just pass” (18), “low” (19-20), “average” (21-23), “good” (24-26), “high” (27-29), “maximum” (30). Function arctan() in exercise 4) of Chapter 3 fails when x=1 because of the division by zero. Correct the problem considering that in this case arctan() should give value π/2. Calculate the distance between points with coordinates 0o N 0o E and 0o N 180o E. [Answer: 20020.726 km or 10810.327 NM] The students of a course have to be distributed in 3 teams called “RED”, “GREEN”, and “BLUE”, according to the registration number (an integer value). The assignment follows this rule: the student with registration number 1 is assigned to team “RED”, 2 to “GREEN”, 3 to “BLUE”, 4 to “RED”, 5 to “GREEN”, and so on. Write a program that asks for the registration number and outputs the assigned team (use Mod, never ever think to list all the registration numbers!). Variation on the previous exercise: the program asks if the student is a foreigner, in this case the assignment scheme must be inverted (“BLUE”, “GREEN”, “RED”). In another InputBox, you can ask the user to enter 1 if it is a foreign student, 0 otherwise. Write a program that asks for the 3 coefficients a, b, and c of a quadratic equation and computes the solutions. If the solutions are not Real, it must display “Non-Real solutions”. Write a program that, given the annual income (an integer value), calculates the amount of the tax to be paid (a real value) according to the following rule:  10% on incomes up to 10 (thousand);  15% on the part exceeding 10 up to 15;  20% on the part exceeding 15 up to 20;  25% on the part exceeding 20 up to 25;  30% on the part exceeding 25 up to 30;  35% on the part exceeding 30.

Conditional Execution

11)

43

Examples An income of 7 is taxed with the 10% of 7 (0.7). An income of 12 is taxed with an amount that is the sum of the 10% of 10 (equal to 1) and the 15% of the exceeding part which is 12–10 (15% of 2, equals to 0.3). An income of 17 is taxed with an amount that is the sum of the 10% of 10 (equal to 1), the 15% of 15–10 (15% of 5, equal to 0.75) and the 20% of 17–15 (20% of 2, equal to 0.4). A year is leap if it is divisible by 4, but not by 100 unless it is divisible by 400. For example, year 1900 was not lap, 1996 was, 2000 was too, and 2002 was not. Write a program that asks for a year and tells if it is a leap year or not.

44

Chapter 5

Strings

6

45

Strings

In Computer Science, a string is a sequence of characters. A character is a graphic sign, e.g. A, $, *, 6; many characters can be typed by just pressing the corresponding key on the keyboard. Inside a computer each character corresponds to a numerical value; the correspondence is defined by the ASCII Code, whose structure is: Section 255 128 127 123 122 97 96 91 90 65 64 58 57 48 47 33 32 31 0

Extended ASCII Code characters Other characters a-z (lowercase letters)

Other characters A-Z (uppercase letters)

Other characters 0-9 (digits)

Other characters Character SPACE Other characters

For example, letter A (uppercase) corresponds to value 65, B to 66, a (lowercase) to 97, b to 98, 0 (zero) to 48 (symbols representing digits are characters too), comma to 44, and so on. The representation of a character occupies a whole byte. The Standard ASCII Code lists 128 correspondences; so 7 bits (27=128) are enough. The eighth bit originates a second 128-correspondence list, which is

Chapter 6

46

called the Extended ASCII Code. Each Operating System is free to set these other correspondences. This means that the Extended ASCII Code is different under Windows, Linux, MacOS, etc. and it is even possible for an Operating System to have more Extended ASCII Code versions (called Code Pages). So, the first half (standard part) of every ASCII Code is always the same for every Operating System, while the second half (extended part) may vary among them. Extended codes are typically used for additional symbols, such as accented letters. The Standard ASCII Code is divided in different sections (see previous picture): uppercase letters, lowercase letters, digits, and “other characters”. Letters are alphabetically ordered, digits are numerically ordered, the “other characters” (punctuation signs, parentheses, etc.) do not have any intrinsic ordering and are just grouped in separate sections. It is important to note that each (uppercase and lowercase) letter and digit section does not contain other (unrelated) characters. Note that SPACE is not a special character, it is character number 32 decimal in the ASCII Code: its graphic sign is blank. You can find the complete Standard ASCII Code in the on-line help (search for Character Set). Usually you do not need to know the correspondence between a character and its ASCII code: in the rare case you need, you may use functions that do it for you. About the Standard ASCII Code, it is enough that you remember this: the SPACE character comes first (its ASCII code is the lowest among the printable characters), followed by (in this order): digits, uppercase letters, and finally lowercase letters. The “other characters” precede, separate, and follow these four sections (considering SPACE as the first one).

6.1

String Variables

Variables of type String may contain at most 231 (about 2109) characters, and are declared using a Dim statement: Dim variable As String Old programs used a $ character at the end of the variable name as in name$. String variables are assigned using the assignment operator: name = "James Bond" A sequence of characters between double quotes is called a constant string and cannot be modified by the program code, while name is a variable and can be modified. The InputBox instruction may be used to enter a string from the keyboard: name = InputBox("What is your name?") A Variant variable is able to store a string.

Strings

6.2

47

String Operators

There is only one operator for strings: the concatenation operator, represented by the ampersand (&) symbol. Its use causes the generation of a temporary string variable composed by all the characters of the first string followed by all characters of the second string. In the following example: A = "Hello" B = "world" C = A & B MsgBox C the MsgBox instruction displays the text “Helloworld”. Concatenation just puts together two strings; if you need some space in between, you must explicitly type it. In this case, you can put a space after the “o” of “Hello”, before the closing double quotes; or before the “w” of “world”, after the opening double quotes. You may also concatenate in the middle another constant string containing a space (there is a space in between): C = A & " " & B For backward compatibility (with old Basic versions), also the + symbol may be used to concatenate two strings (besides to sum two values). The use of the + as a string operator may give trouble though, for example a + between two Variant variables, even if they contain numbers, is seen as a string concatenation (as we saw when we changed the – with a + in the “Subtractor” example in Section 3.1). The concatenation operator & will always convert a value of any type to a string; it is then possible to concatenate a string and a value (see example in Section 4.1). Remember to always insert a space before and after the & operator.

Chapter 6

48

6.3

String Functions

In addition to the concatenation operator, Visual Basic provides several functions to manipulate strings: some of them give a numerical result, others a string result. The most important string functions are described in this section. 6.3.1 Len The Len function counts the number of characters in the string specified as its parameter: A = "White cloud" X = Len(A) Variable X (which must be of a numerical type) is assigned with integer value 11 (string A is composed by 11 characters, space included). 6.3.2 Left The Left function generates a [temporary variable of type] string (called a substring) that contains the first n characters of the given string: A = "White cloud" C = Left(A,9) The 9 leftmost (first) characters of string A are copied to string C, in the same order they appear in A; that is, C contains “White clo” (note that spaces count as characters).

The syntax of function Left is: Left(String from where to copy characters, how many) 6.3.3 Right The Right function generates a string containing the last n characters of the given string: A = "White cloud" C = Right(A,8) The 8 rightmost (last) characters of string A are copied to string C, in the same order they appear in A (Right does not reverse the string!); that is, after the execution of the code above, C will contain “te cloud”.

The syntax of function Right is: Right(String from where to copy characters, how many)

Strings

49

6.3.4 Mid The Mid function generates a string containing n contiguous characters copied from within another string (“mid” stands for “middle”). The syntax of function Mid is: Mid(string, from_position, how_many) As many as how_many characters, starting from the from_position character (1 for the first character, etc.) of the given string are copied. Example: A = "White cloud" C = Mid(A,4,6) Here Mid would extract (copies) 6 characters from A starting from position 4; so C contains “te clo” (space is included). As always, the characters are just copied: A is not altered at all. The number of the extracted characters might be less than how_many if the requested number of characters is not available.

A peculiar use of the Mid function (Left and Right cannot be used in this way) can be useful in the case when we need to substitute a portion of a string with a different text. Using the following code: A = "sausage" Mid(A,3,4) = "rdin" the Mid function will change variable A by substituting 4 characters from character 3 (this identifies substring “usag”) with string “rdin”, so A becomes “sardine”. Right and Left cannot be used in this way, you can use Mid instead. 6.3.5 Instr The Instr function finds the first occurrence of a string within another; its syntax is: Instr(from_position, string_where_to_search, string_to_search) string_to_search is searched within string_where_to_search starting from the character at position from_position (included). It returns a whole value that indicates the first position where string_to_search is found in string_where_to_search. It returns 0 if it is not found. Here are some examples: S = "Beware the dog you see over there" N = Instr(1, S, "the") String “the” is looked for in the string “Beware the dog you see over there” starting from position 1, that is from letter B of “Beware”. Instr here would return 8. Note that the “the” of “there” occurrences will not be considered: Instr stops the search at the first occurrence.

50

Chapter 6

Using values from 2 to 8 for from_position, Instr gives 8 in any case (the result is computed from the first character of string_where_to_search); simply, the search skips the first (from_position – 1) characters. If from_position is 9, the first occurrence is skipped and the result is 29 (the first occurrence found after position 9). The same result if obtained when using from_position values from 9 to 29. For from_position values greater than 29, Instr would not be able to find any occurrence (the previous are skipped) and will therefore give 0 as result. Even in the following example, Instr does not find any occurrence and gives result 0. N = Instr(1, S, "cat") In VBA no function exists to find the second occurrence of a string, but you may get the result by composing more calls to the Instr function: A = "Beware the dog you see over there" B = "the" position = Instr(Instr(1,A,B)+1, A, B) The inner Instr finds the “the” string before “dog”; adding 1 to this result moves on the starting point in order to skip the first “the”, and the outer Instr finds the next (second) occurrence of “the”: the one in “there”. If a second occurrence does not exist, the whole expression gives result 0. 6.3.6 Other String Functions Chr(value) returns a one-character string corresponding to ASCII Code value; e.g. Chr(65) gives an uppercase “A”. Chr(34) may be used to concatenate a double quote character in a string. Asc(string) returns the ASCII Code of the first character of string; e.g. Asc("Ant") gives value 65. Str(value) converts the number value in the sequence of its digits; e.g. Str(123) converts value 123 (two’s complement) to string “ 123” (note the leading space, it would be a minus sign for a negative value). Val(string) returns the value (of the appropriate type) whose string representation (sequence of digits) is specified in string; e.g. Val("123") gives the Integer value 123. Any space and TAB 123") still character preceding the first digit is ignored: Val(" produces value 123; other characters would instead stop the conversion.

Strings

51

E.g. Val("123AB2") produces value 123 again, ignoring the trailing part “AB2”. Val("A2") gives value 0. Consider the following code: Dim A As Integer A = InputBox("value") The program waits for a number; but if something other than a number (e.g. ABC or 123ABC) is entered, the program stops issuing a type mismatch error: this means that the value returned by the InputBox and the type of variable A are not compatible. This is a run-time error: it would happen only while the program is running. Even just pressing the OK button or the ENTER key produces this error, because a nonnumerical value is entered (an empty string). Function Val solves this problem by converting a non-numerical string to value 0. Dim A As Integer A = Val(InputBox("value")) Function Val may also be used to sum two Variant values containing the ASCII representation of two numerical values; this is the way to correct the problem we found when converting the “Subtractor” to an “Adder” (see Section 3.1). Here is a cumulative example of the previous functions: Dim A As String, B As String A = "123" B = "456" MsgBox A + B 'concatenation, better use & MsgBox Val(A) + Val(B) 'sum MsgBox Asc(A) MsgBox Chr(Asc(B)) MsgBox Str(-333) + Str(444) 'concat., better use & The output of the previous program follows (output at left, remarks at right): 123456  string concatenation 579  sum of numerical values corresponding to “123” and “456” 49  ASCII code for character “1” 4  string containing the character corresponding to the ASCII code of the first byte of string B –333 444  concatenation of the two strings gotten from values –333 and 444; note the space before 444: for a negative number, a minus sign will be displayed there.

Chapter 6

52

UCase(string) returns a Variant (to be used as a string) containing string converted to uppercase (characters corresponding to non-lowercase letters are just copied); e.g. string “Hello 123! How are you?” would generate “HELLO 123! HOW ARE YOU?”. string remains unchanged. LCase(string) returns a Variant (to be used as a string) containing string converted to lowercase (characters corresponding to non-uppercase letters are just copied); e.g. string “Hello 123! How are you?” would generate “hello 123! how are you?”. string remains unchanged. Date returns a Variant (to be used as a string) containing the current date; the format used depends on the Operating System settings. Note that there are no parentheses. Time returns a Variant (to be used as a string) containing the current time; the format used depends on the Operating System settings. Note that there are no parentheses.

6.4

String Comparison

Strings are compared by using If statements (with the relational operators used for numerical values) or Select Case statements. For example: If country = "Italy" Then ... All relational operators may be used, but we need to clarify the meaning of some of them (like “greater” or “lower”) when working with string operands. If we consider simple words, it is obvious that, for example, “cat” comes before “dog”: actually, “c” comes alphabetically before “d”. The same is for “dog” and “fish”. Even for Visual Basic “cat” comes before (is “less” or “lower” than) “dog”, but the reason is that the ASCII code of “c” is a number smaller than the ASCII code of “d”. String comparisons are performed by comparing their ASCII codes in corresponding positions. For example, string “Dog” is “lower” than string “cat” because, according to the ASCII Code, uppercase “D” has lower code than lowercase “c” (remember the ASCII Code scheme: the letters in the uppercase section have lower ASCII codes than the letters in the uppercase section). SPACE is a normal character, and its ASCII code has a lower value than any other printable character. Thus, string “ abc” is “lower” then string

Strings

53

“abc” because the first one begins with character SPACE and the second with character “a”. When both strings begin with the same character, the comparison is made on the characters in second position, if they match again the characters in third position are checked, and so on. Pay attention to string comparison when they contain numbers: string “21” is “greater” than string “1234” because comparison is between two strings and, in the ASCII Code, character “2” comes after character “1”. Of course, Val("21") is “lower than” Val("1234"). In summary, the rules for string comparison are the following:  Two strings are compared character by character from left to right, comparing the ASCII codes in corresponding positions (the first with the first, the second with the second, etc.)  If the first characters are equal (uppercase and lowercase letters are different), the two second characters are compared, and so on  If two corresponding characters are different, the relation between them determines the relation between the strings (the “a” of “cat” is less than the “o” of “cow”, thus string “cat” is less than string “cow”)  If all the corresponding characters are the same and the strings have equal length, the two strings are equal  If two strings have different length and the left part of the longer string is equal to the shorter string, the “greater” string is the longer: “bull” is “lower” than both “bulldog” and “bull ” (note the trailing space)

Chapter 6

54

6.5

Exercises

1) Write a program that requests 2 strings and prints the longer (the first one if of equal length). 2) Write a program that requests 2 strings and prints the greater. 3) Write a program that requests 3 strings and prints the greatest. 4) Write a program that requests 3 strings and prints them in decreasing order. 5) Scrivere un programma che determini se il primo carattere della stringa è una lettera maiuscola, una lettera minuscola, una cifra o un altro carattere. 6) Scrivere un programma che determini se il primo carattere e l’ultimo carattere di una stringa sono uguali. 7) Write a program that requests a string and tells if capital letter “A” is found in the first 10 characters. 8) Write a program that requests 2 strings and tells if they are equal (this does not mean that they have the same length!); if they are different, it must print the lower one (this does not mean the smaller!). 9) Write a program that requests 2 strings and tells if the second one is contained at least once in the first one. 10) Write a program that requests 2 strings and tells if the shorter is contained just one time (no more than one time) in the longer one. 11) Write a program that requests a string and tells if it is composed by two equal parts; if its length is an odd number, discard the middle character (try the following strings: “moremore”, “trytry”, “moreXmore”, and “tryXtry” – the last one could be the most problematic). 12) Write a program that requests a string and swaps its two halves; if the length is an odd number, the middle character must maintain its position (for example, a string like this one: “Hello, how are you?” becomes “are you?wHello, ho” (the middle “w” – underlined for clarity – remains in its position, the two considered halves have 9 characters each).

Unconditional Jumps

7

55

Unconditional Jumps

A jump instruction makes the program go (“jump”) to another point of the code and continue execution from there. In modern programming, jumps are almost always avoided because their (ab)use typically results in an intricate programming flow: the program becomes difficult to understand and maintain (review, update, correct, modify). Moreover, research demonstrated that programs could be written without jump statements, provided the programming language offers the required “structured” constructs. Visual Basic provides such structured constructs, but also provides a jump instruction called the GoTo instruction. Thus, the GoTo statement may be completely avoided, but sometimes is still useful for achieving better performance (and clarity). We will see one case where its use is acceptable in the exercises of Chapter 9, but do not use GoTo statements in any other case. Here is the syntax: GoTo label

where label is a character sequence that indicates the line where to jump: label: A label is always written alone in the leftmost portion of a line (no leading spaces, no indentation) and is followed by a colon (note that the colon must not be specified in the use of the label in the GoTo statement). The purpose of a label is just to mark a line of code in order to be able to reference it. So the instruction: GoTo there means “go to the line with label there”, and the execution continues from the line with label there.

56

Chapter 7

Consider the following example: var = InputBox("Enter value") If var = 0 Then GoTo continue End If ... other lines of code continue: MsgBox "End of program" The execution is as follows: 1. instruction InputBox requests a value from the user and stores it in variable var; 2. if var = 0, then instruction GoTo continue makes the execution jump to the line with label continue, skipping the other lines of code portion; otherwise, the other lines of code section is executed; 3. the statements after the label line are executed (in this example, just the MsgBox statement). The line identified with the label may precede (resulting in a backward jump) or follow (resulting in a forward jump) the GoTo line, as long as both are in the same subroutine or function (see Chapter 11). It is very bad programming habit to jump into a block of code from outside (e.g. to jump into an If branch from outside). A program may have many labels (all must be different); and more GoTo statements may jump to the same label. A backward jump may be used to go back and execute a block of lines again, but this (very common and useful) behavior can be obtained using dedicated structured constructs instead; you will learn about them in the next chapter.

Loop Statements

8

57

Loop Statements

Suppose we want to display all the even numbers from 0 to 1000. You could write 501 MsgBox statements: MsgBox 0 MsgBox 2 ... MsgBox 1000 You could use the cut and paste facility of your editor, but it is still obvious this is not the best solution, because it is:  not compact (there are 501 lines of code);  not easily scalable (think about the changes you should do to display even numbers from 0 to 10000);  not easily readable (you have to read 501 lines);  very prone to errors (it is hard to visually determine that the sequence of 501 lines of code is correct). It would be much easier to tell our computer: “execute for 501 times the statement MsgBox I starting with I=0, adding 2 to I each time; stop when you get to 1000”. This version of the program would be more compact, and easier to code, modify, scale, and check. This solution scheme requires a back jump in the code to repeat the MsgBox I instruction; this scheme is called a loop. The ill-famed GoTo statement might be used, but we will avoid it for better and structured constructs. The solution with a GoTo statement could be: I = 0 back: MsgBox I I = I + 2 If I than both B and C MsgBox A ElseIf B>C Then 'see Remark MsgBox B Else MsgBox C End If Remark: when the execution flow reaches this ElseIf, A is surely not the greatest of the three values because it would have been considered (intercepted) by the previous If, so the greatest will be either B or C.

Solution to the Exercises

127

Exercise 3 Dim A As Single Dim B As Single Dim C As Single A = InputBox("Enter value for A") B = InputBox("Enter value for B") C = InputBox("Enter value for C") If A>B And A>C Then If B>C Then MsgBox A & " " & B & " " & C Else MsgBox A & " " & C & " " & B End If ElseIf B>C Then If A>C Then MsgBox B & " " & A & " " & C Else MsgBox B & " " & C & " " & A End If Else If A>B Then MsgBox C & " " & A & " " & B Else MsgBox C & " " & B & " " & A End If End If Exercise 4 Dim num As Integer num = InputBox("Enter value") If num Mod 2 = 0 Then 'or If num/2 = num\2 Then MsgBox num & " is even" Else MsgBox num & " is odd" End If Remark: a value is even if the remainder of the division by 2 gives 0, odd otherwise.

Chapter 17

128 Exercise 5 Dim grade As Integer grade = InputBox("Enter grade") Select Case grade Case Is < 18 MsgBox "Below the pass" Case 18 MsgBox "Pass" Case 19,20 'or: Case Is = "0" And c = 2 Then result = "1 1" If n >= 3 Then For i = 3 To n c = a + b result = result & " " & c a = b b = c Next End If End If MsgBox result Exercise 11 Dim n As Integer Dim NF As Double Dim i As Integer n = InputBox("Factorial of?") NF = 1 For i = n To 2 Step -1 NF = NF * i Next MsgBox n & "Factorial is " & NF

Chapter 17

Solution to the Exercises Exercise 12 Dim x As Double Dim ex As Double Dim i As Integer Dim k As Integer Dim kf As Double Dim n As Integer

145

'value of which to compute the exponential 'value of the computed exponential 'iteration counter of the number of fractions 'k factorial 'required number of fractions

x = InputBox("Number of which to compute the exponential") n = InputBox("How many fractions") ex = 1 'initialize the summation with the first element For k = 1 To n 'compute k! and store it into kf kf = 1 For i = k To 2 Step -1 kf = kf * i Next 'compute and sum the next fraction ex = ex + (x ^ k) / kf Next MsgBox "Computed value of exp(" & x & "): " & ex & _ vbNewLine & _ "Value given by Exp(" & x & "): " & Exp(x) & _ vbNewLine & _ "Their difference: " & ex - Exp(x)

Remark: the code in boldface used to compute k factorial could be substituted by the simpler statement kf = kf * k after having initialized kf to 1 before the external For.

146

Chapter 17

Exercises on Do-Loop loops Exercise 1 Solution using a while-do loop Dim count As Integer 'a counter in needed Dim v As Integer Dim sum As Integer count = 0 sum = 0 v = InputBox("Enter grade") Do While v >= 18 And v = 18 And v max Then max = v ElseIf v < min Then min = v End If v = InputBox("Enter grade") Loop If count 0 Then 'count is 0 when the MsgBox "Maximum = "Minimum = "Average = "Sum = " & End If

first grade is 30

" & max & vbNewLine & _ " & min & vbNewLine & _ " & sum/count & vbNewLine & _ sum

148

Chapter 17

Exercise 3 Dim i As Integer Dim row As String Dim upper As Integer, lower As Integer Dim digit As Integer, others As Integer Dim c As String row = InputBox("Enter a string") Do While row "stop" upper = 0 lower = 0 digit = 0 other = 0 For i = 1 To Len(row) Select Case Mid(row, i, 1) Case "0" To "9" digit = digit + 1 Case "A" To "Z" upper = upper + 1 Case "a" To "z" lower = lower + 1 Case Else others = others + 1 End Select Next MsgBox "Digits: " & digit & vbNewLine & _ "Uppercase letters: " & upper & vbNewLine & _ "Lowercase letters: " & lower & vbNewLine & _ "other characters: " & others row = InputBox("string") Loop Remark: the number of other characters (others) can also be computed as: Len(row) – digit – upper - lower. Exercise 4 Dim a As Long Dim b As Long Dim c As Long Dim n As Long Dim result As String

Solution to the Exercises

149

a = 1 b = 1 n = InputBox("Maximum value") If n > 0 Then result = "1 1" c = a + b Do While c x Then MsgBox "Too high" ElseIf v < x Then MsgBox "Too low" End If Loop Until x = v MsgBox "Found!" Remark: function Int is required because a simple Rnd*100 produces a Single value between 0 and 99.99999 and the assignment to variable x is achieved through a rounding. Therefore, value 100 may come out. Function Int truncates the fractional part, thus the numbers produced are always less than or equal to 99. Even Rnd*99 is not correct because only values between 98.50001 and 98.99999 would give a resulting random value of 99, this would have half the probability to come out with respect to the other values (the first formula gives 99 for all the values between 99.00000 and 99.99999).

Chapter 17

150 Exercise 6 Dim a As Double Dim x As Double Dim x1 As Double Dim result As String

a = InputBox("Value of which to compute the root") If a = 0 Then result = "0" ElseIf a < 0 Then result = "Imaginary results" Else x1 = a Do x = x1 'stores previous approx. value x1 = 0.5 * (x + a / x) 'computes next approx of result Loop While x x1 'while x is changing result = x 'side effect: converts x to string End If MsgBox "Square root of " & a & " is " & result

17.7

Chapter 9 - Arrays and Matrices

Exercise 1 Dim i As Integer Dim n As Integer Dim values() As Integer n = InputBox("How many values will you enter?") ReDim values(1 To n) For i = 1 To n values(i) = InputBox("Enter value " & i) Next For i = n To 1 Step -1 MsgBox "Value number " & i & ": " & values(i) Next

Solution to the Exercises

151

Exercise 2 Dim i As Integer Dim n As Integer Dim values() As Integer Dim result As String result = "" n = InputBox("How many values?") ReDim values(1 To n) For i = 1 To n values(i) = InputBox("Enter value number " & i) Next For i = 1 To n If values(i) Mod 2 = 0 Then result = result & " " & values(i) End If Next For i = n To 1 Step -1 If values(i) Mod 2 = 1 Then result = result & " " & values(i) End If Next MsgBox result Remark: the lines typeset in boldface may be eliminated, thus collapsing the first two For-Next loops in just one and speeding up the program execution.

Other solution Dim i As Integer Dim n As Integer Dim values() As Integer Dim evenResult As String Dim oddResult As String evenResult = "" oddResult = "" n = InputBox("How many values") ReDim values(1 To n)

152

Chapter 17

For i = 1 To n values(i) = InputBox("Enter value number " & i) If values(i) Mod 2 = 0 Then evenResult = evenResult & values(i) & " " Else oddResult = values(i) & " " & oddResult End If Next MsgBox evenResult & oddResult Remark: in this case an array should be avoided because not really needed. Exercise 3 Dim i As Integer Dim n As Integer Dim strings() As String Dim result As String result = "" n = InputBox("How many strings?") ReDim strings(1 To n) For i = 1 To n strings(i) = InputBox("Enter string number " & i) Next For i = 1 To n If i Mod 2 = 0 Then result = result & vbNewLine & strings(i) End If Next For i = 1 To n If i Mod 2 = 1 Then result = result & vbNewLine & strings(i) End If Next MsgBox result Remark: same remark of previous exercise, same variation.

Solution to the Exercises

153

Exercise 4 Dim i As Integer Dim n As Integer Dim a() As Single Dim b() As Single Dim c() As Single Dim result As String result = "" n = InputBox("How many values?") ReDim a(1 To n) ReDim b(1 To n) ReDim c(1 To n) For i = 1 To n a(i) = InputBox("Enter Next For i = 1 To n b(i) = InputBox("Enter Next For i = 1 To n c(i) = a(i) + b(i) Next For i = 1 To n If i Mod 2 = 0 Then result = result & " End If Next For i = 1 To n If i Mod 2 = 1 Then result = result & " End If Next MsgBox result

value number " & i & " for a") value number " & i & " for b")

" & c(i)

" & c(i)

Chapter 17

154

Other solution (with the optimizations seen in the previous exercises) Dim i As Integer Dim n As Integer Dim a() As Single Dim b() As Single Dim c() As Single Dim evenResult As String Dim oddResult As String evenResult = "" oddResult = "" n = InputBox("How many values?") ReDim a(1 To n) ReDim b(1 To n) ReDim c(1 To n) For i = 1 To n a(i) = InputBox("Enter value number " & i & " for a") Next For i = 1 To n b(i) = InputBox("Enter value number " & i & " for b") c(i) = a(i) + b(i) If i Mod 2 = 0 Then evenResult = evenResult & c(i) & " " Else oddResult = oddResult & c(i) & " " End If Next MsgBox evenResult & oddResult Exercise 5 Dim r As Integer Dim c As Integer Dim NR As Integer Dim NC As Integer Dim evenValues As Integer Dim oddValues As Integer Dim MX() As Integer Dim table As String

'row index 'column index 'number of rows 'number of columns 'odd values counter 'even values counter 'the matrix 'used to show MX

Solution to the Exercises

155

Randomize table = "" NR = InputBox("How many rows?") NC = InputBox("How many columns?") ReDim MX(1 To NR, 1 To NC) 'fills the matrix with random values For r = 1 To NR For c = 1 To NC MX(r, c) = Int(Rnd * 100) Next Next 'writes values in table For r = 1 To NR For c = 1 To NC If MX(r, c) < 10 Then 'put spaces before values table = table & " " & MX(r, c) '3 spaces Else table = table & " " & MX(r, c) '2 spaces End If Next table = table & vbNewLine Next 'counts odd values and even values evenValues = 0 oddValues = 0 For r = 1 To NR For c = 1 To NC If MX(r, c) Mod 2 = 0 Then evenValues = evenValues + 1 Else oddValues = oddValues + 1 End If Next Next MsgBox table & _ "Even values: " & evenValues & vbNewLine & _ "Odd values: " & oddValues Remark: here, too, the three double-loops could be collapsed into just one.

156

Chapter 17

Exercise 6 Dim r As Integer, c As Integer Dim NR As Integer, NC As Integer Dim evenValues As Integer Dim MX() As Integer Randomize NR = InputBox("How many rows?") NC = InputBox("How many columns?") ReDim MX(1 To NR, 1 To NC) For r = 1 To NR For c = 1 To NC MX(r, c) = Int(Rnd * 100) Next Next evenValues = 0 For r = 1 To NR For c = 1 To NC If MX(r, c) Mod 2 = 0 Then evenValues = evenValues + 1 If evenValues >= NR * NC / 4 Then GoTo outside End If End If Next Next outside: If evenValues >= NR * NC / 4 Then MsgBox "At least 1/4 of the values are even" Else MsgBox "Less than 1/ 4 of the values are even" End If Remark: a simple = instead of >= is not correct because evenValues may contain only integer values, while NR*NC/4 may give fractional values. For example, 9 and 9 produce 40.5, if the condition were the equality to 40.5, it would never be verified because evenValues would step from 40 to 41, resulting in an infinite loop. The label outside is reached in any case, so the condition tested in the If clause after the label is required to find out if there was a jump to there or not. A jump comes from the GoTo and this means that at least 1/4 of the values are even, otherwise the two For-Next loops have ended normally and this means that less than 1/4 of the values are even.

Solution to the Exercises

157

Exercise 7 Dim n As Integer Dim i As Integer Dim values() As Single Do n = InputBox("How many values?") Loop Until n >= 3 ReDim values(1 To n) For i = 1 To n Values(i) = InputBox("Enter value") Next For i = 1 To n - 2 MsgBox (values(i) + values(i + 1) + values(i + 2)) / 3 Next Exercise 8 Dim n As Integer Dim x As Integer 'moving average with x values Dim i As Integer Dim j As Integer Dim values() As Single Dim sum As Single x = InputBox("Moving average with how many values?") Do n = InputBox("How many values?") Loop Until n >= x ReDim values(1 To n) For i = 1 To n values(i) = InputBox("Enter value number " & i) Next For i = 1 To n - x + 1 'calculates the sum of x values starting from position i sum = 0 For j = i To i + x - 1 sum = sum + values(j) Next MsgBox sum / x Next

158

Chapter 17

Exercise 9 Dim i As Integer Dim j As Integer Dim n As Integer Dim values() As Integer Dim temp As Integer Dim result As String n = InputBox("How many values?") ReDim values(1 To n) For i = 1 To n values(i) = InputBox("Enter value number " & i) Next 'sort values in ascending order For i = 1 To n - 1 For j = i + 1 To n If values(i) > values(j) Then 'exchange values temp = values(i) values(i) = values(j) values(j) = temp End If Next Next result = "" For i = 1 To n result = result & values(i) & " " Next MsgBox result Remark: the method adopted here is similar to a selection sort, but less efficient; the array is analyzed from left to right comparing each element with each of the following. Index i starts from 1 and goes up to N–1; index j starts from i+1 and goes up to N. Index i stops at N–1 because j starts with value i+1: if i = N then the next element would be n+1, which does not exist. While comparing the values two by two, when two elements are found in the wrong order (the left one greater of the right one), they are exchanged.

Solution to the Exercises Exercise 10 Dim result As String Dim RA As Integer 'number of rows of Dim CA As Integer 'number of columns Dim RB As Integer 'number of rows of Dim CB As Integer 'number of columns Dim A() As Double 'first matrix Dim B() As Double 'second matrix Dim C() As Double 'result matrix Dim rx As Integer Dim cx As Integer Dim i As Integer

159

first matrix (A) of first matrix (A) second matrix (B) of second matrix (B)

RA = InputBox("Number of rows of 1st matrix (A)?") CA = InputBox("Number of columns of 1st matrix (A)?") RB = CA 'required for the multiplication MsgBox "The number of rows of 2nd matrix (B) " & _ "is necessarily " & RB CB = InputBox("Number of columns of 2nd matrix (B)") ReDim A(RA, CA) ReDim B(RB, CB) ReDim C(RA, CB) 'fills matrix A For rx = 1 To RA For cx = 1 To CA A(rx, cx) = InputBox("Enter value for " & _ "A(" & rx & "," & cx & ")") Next Next 'fills matrix B For rx = 1 To RB For cx = 1 To CB B(rx, cx) = InputBox("Enter value for " & _ "B(" & rx & "," & cx & ")") Next Next 'C() is automatically initialized with 0es

Chapter 17

160

'computes A*B and stores it in C For rx = 1 To RA For cx = 1 To CB For i = 1 To CA C(rx, cx) = C(rx, cx) + A(rx, i) * B(i, cx) Next Next Next 'show matrix For rx = 1 For cx = result Next result = Next

C

To RA 1 To CB = result & C(rx, cx) & " " result & vbNewLine

MsgBox result

Solution to the Exercises

17.8

Chapter 10 - Files

Exercise 1 Dim count As Integer Dim v As Integer Dim sum As Integer Dim max As Integer Dim min As Integer Dim file As String file = InputBox("File to open?") Open file For Input As #1 If EOF(1) Then 'checks if there is at least 1 row MsgBox "File empty" Close #1 Exit Sub 'or End – breaks the execution of the Sub End If Input #1, v max = v min = v sum = v count = 1 Do While Not EOF(1) Input #1, v count = count + 1 sum = sum + v If v > max Then max = v ElseIf v < min Then min = v End If Loop Close #1 MsgBox "Values number = " & count & vbNewLine & _ "Maximum = " & max & vbNewLine & _ "Minimum = " & min & vbNewLine & _ "Average = " & sum/count & vbNewLine & _ "Sum = " & sum

161

162

Chapter 17

Exercise 2 Dim count As Integer Dim row As String Dim max As String Dim min As String Dim file As String file = InputBox("File to open?") Open file For Input As #1 If EOF(1) Then MsgBox "File empty" Close #1 Exit Sub End If Line Input #1, row max = row min = row count = 1 Do While Not EOF(1) Line Input #1, row count = count + 1 If row > max Then max = row ElseIf row < min Then min = row End If Loop Close #1 MsgBox "Number of rows = " & count & vbNewLine & _ "Lowest row = " & min & vbNewLine & _ "Greatest row = " & max Remark: “greatest” in accordance with ASCII code, not the longest; the same is for “lowest”.

Solution to the Exercises

163

Exercise 3 Dim file As String Dim row As String Dim count As Integer Dim i As Integer Dim strings() As String Dim result As String file = InputBox("File to open?") Open file For Input As #1 count = 0 result = "" Do While Not EOF(1) 'count rows in file Line Input #1, row count = count + 1 Loop Close #1 ReDim strings(1 To count) Open file For Input As #1 For i = 1 To count 'the row number is known Line Input #1, strings(i) Next Close #1 For i = count To 1 Step -1 result = result & strings(i) & vbNewLine Next MsgBox result Remark: first loop is a conditional loop (Do-Loop) because it is unknown how many rows are in the file. Here, rows are just read and discarded: the goal of this loop is just to count how many rows there are in order to dimension the dynamic array strings with the correct size (count). The second loop is a counting loop (For-Next) because the number of required readings is now known (count); another Do-Loop loop would have been still correct. The goal of this second loop is to actually read and process the rows of the file. The third loop goes through the array backwards.

164

Chapter 17

Exercise 4 Dim fileIN As String Dim fileOUT As String Dim row As String Dim count As Integer Dim i As Integer Dim lines() As String fileIN = InputBox("Enter input file") Open fileIN For Input As #1 fileOUT = InputBox("Enter output file") count = 0 Do While Not EOF(1) Line Input #1, row count = count + 1 Loop Close #1 ReDim lines(1 To count) Open fileIN For Input As #1 'to restart from beginning For i = 1 To count Line Input #1, lines(i) Next Close #1 Open fileOUT For Output As #2 For i = count To 1 Step -1 Print #2, lines(i) Next Close #2 MsgBox count & " rows copied"

Solution to the Exercises

165

Exercise 5 Dim i As Integer Dim row As String Dim upper As Integer Dim lower As Integer Dim digit As Integer Dim others As Integer Dim file As String upper = 0 lower = 0 digit = 0 other = 0 file = InputBox("File to open?") Open file For Input As #1 Do While Not EOF(1) Line Input #1, row For i = 1 To Len(row) Select Case Mid(row, i, 1) Case "0" To "9" digit = digit + 1 Case "A" To "Z" upper = upper + 1 Case "a" To "z" lower = lower + 1 Case Else others = others + 1 End Select Next Loop Close #1 MsgBox "Digits: " & digit & vbNewLine & _ "Uppercase letters: " & upper & vbNewLine & _ "Lowercase letters: " & lower & vbNewLine & _ "other characters: " & others

166

Chapter 17

Exercise 6 Dim fileIN As String Dim fileOUT As String Dim n As Integer Dim row As String fileIN = InputBox("Enter input file") Open fileIN For Input As #1 fileOUT = InputBox("Enter output file") Open fileOUT For Output As #2 n = InputBox("Maximum width?") Do While Not EOF(1) Line Input #1, row Do While Len(row) > n Print #2, Left(row, n) row = Right(row, Len(row) - n) Loop Print #2, row Loop Close #1 Close #2

Remark: in a simpler mode, the part of the loop typeset in boldface could be replaced with the following one: For I = 1 To Len(row) Step n Print #2, Mid(row, I, n) Next

Solution to the Exercises

167

Exercise 7 Dim fileIN As String Dim fileOUT As String Dim n As Integer Dim row As String Dim spacePos As Integer Dim i As Integer fileIN = InputBox("Enter input file") Open fileIN For Input As #1 fileOUT = InputBox("Enter output file") Open fileOUT For Output As #2 n = InputBox("Maximum width?") Do While Not EOF(1) Line Input #1, row Do While Len(row) > n 'find last space (if it exists) spacePos = 0 'space position, 0 if not found For i = n+1 To 1 Step –1 'see Remark If Mid(row, i, 1) = " " Then spacePos = i Exit For End If Next If spacePos=0 Or spacePos = n + 1 Then 'not found within the n first characters spacePos = n End If Print #2, Left(row, spacePos) row = Right(row, Len(row) - spacePos) Loop Print #2, row Loop Close #1 Close #2

Remark: there could be a space exactly after character position n, so n+1 here is required to not remove the beginning space.

168

Chapter 17

Exercise 8 Dim key As Integer Dim c As String Dim cc As Integer Dim row As String 'row to encrypt Dim fileIN As String Dim fileOUT As String fileIN = InputBox("Enter input file") Open fileIN For Input As #1 fileOUT = InputBox("Enter output file") Open fileOUT For Output As #2 key = InputBox("Enter key") Do While Not EOF(1) Line Input #1, row For I = 1 To Len(row) c = Mid(row, I, 1) cc = Asc(c) 'ASCII code of the character to encrypt If c >= "A" And c Asc("Z") Then cc = cc - 26 ElseIf cc < Asc("A") Then cc = cc + 26 End If Mid(row, I, 1) = Chr(cc) ElseIf c >= "a" And c Asc("z") Then cc = cc - 26 ElseIf cc < Asc("a") Then cc = cc + 26 End If Mid(row, I, 1) = Chr(cc) 'if it isn’t a letter 'cc is not changed End If Next Print #2, row Loop Close

Solution to the Exercises

169

Other solution Dim key As Integer Dim c As String Dim cc As Integer Dim row As String 'row to encrypt Dim fileIN As String Dim fileOUT As String fileIN = InputBox("Enter input file") Open fileIN For Input As #1 fileOUT = InputBox("Enter output file") Open fileOUT For Output As #2 key = InputBox("Enter key") key = (key + 26) Mod 26 'to have key >= 0 Do While Not EOF(1) Line Input #1, row For I = 1 To Len(row) c = Mid(row, I, 1) If c >= "A" And c = "0" And c = "0" And c v(j) Then temp = v(i) v(i) = v(j) v(j) = temp End If Next Next End Sub

Solution to the Exercises Exercise 10 Calling module (CommandButton1_Click) Dim i As Integer, n As Integer Dim direction As String, result As String Dim array() As Single n = InputBox("Array dimension?") ReDim array(1 To n) For i = 1 To n array(i) = InputBox("Enter value number " & i) Next Do direction = LCase(InputBox("Sorting asc/desc (a/d)?")) Loop Until direction = "a" Or direction = "d" Call sort(array(), order) result = "" For i = 1 To n result = result & array(i) & " " Next MsgBox result

183

184

Chapter 17

Called module Sub sort (v() As Single, ascdesc As String) Dim i As Integer Dim j As Integer Dim L As Integer Dim R As Integer Dim temp As Single L = Lbound(v, 1) R = Ubound(v, 1) For i = L To R - 1 For j = i + 1 To R If v(j) < v(i) Xor ascdesc = "d" Then temp = v(i) v(i) = v(j) v(j) = temp End If Next Next End Sub Remark: the If condition fully expanded would be: (v(j) < v(i) AND ascdesc = "a") OR (v(j) > v(i) AND ascdesc = "d") Assuming A=(v(j)v(i) is not A: the true A is v(j)>=v(i). The >= sign has the drawback to exchange equal values too, when ordering in a decreasing direction, and this is a little less efficient. However, the condition is simpler to write and more efficient to evaluate.

Solution to the Exercises

17.10 Chapter 12 - Compound Data Types Exercise 1 Code Module Type Student regNumber As Long firstName As String lastName As String average As Integer End Type

Calling module (CommandButton1_Click) Dim fileIN As String Dim fileOUT As String Dim numRows As Integer Dim s As String Dim i As Integer Dim students() As Student fileIN = InputBox("Input file to open?") Open fileIN For Input As #1 fileOUT = InputBox("Output file to open?") numRows = 0 Do While Not EOF(1) Line Input #1, s numRows = numRows + 1 Loop Close 1 ReDim students(1 To numRows) As Student Open fileIN For Input As #1 For i = 1 To numRows Input #1, students(i).regNumber Input #1, students(i).firstName Input #1, students(i).lastName Input #1, students(i).average Next Close 1

185

186

Chapter 17

Call sort(students()) Open fileOUT For Output As #2 For i = 1 To numRows Print #2, students(i).regNumber; ","; Print #2, students(i).lastName; ","; Print #2, students(i).firstName; ","; Print #2, students(i).average Next Close 2

Called module Sub sort(A() As Student) Dim i As Integer Dim j As Integer Dim L As Integer 'array dimension Dim temp As Student L = UBound(A, 1) For i = 1 To L - 1 For j = i + 1 To L If A(i).regNumber > A(j).regNumber Then temp = A(i) A(i) = A(j) A(j) = temp End If Next Next End Sub

Solution to the Exercises

17.11 Chapter 16 - More Complex Exercises Exercise 1 Dim i As Integer Dim file As String Dim row As String Dim c As String Dim sentence As String sentence = "" file = InputBox("File to open?") Open file For Input As #1 Do While Not EOF(1) Line Input #1, row For i = 1 To Len(row) c = Mid(row, i, 1) If c >= "A" And c = "A" And c = "A" And cc " 'go until > i = i + 1 'skip space or = attr = getWord(row, i) 'skip attrib and val Loop 'the > char is skipped by the Next instruction

Chapter 17 Case Else: 'other tag row2 = row2 & "" End Select End If 'go out of the tag, continue to analyze the row Next Print #2, row2 Loop Close End Sub

Called module Function getWord(s As String, pos As Integer) As String Dim s2 As String, c As String s2 = "" c = Mid(s, pos, 1) Do While InStr(1, "= >", c) = 0 'None of these 3 char. s2 = s2 & c pos = pos + 1 c = Mid(s, pos, 1) Loop getWord = s2 End Function Remark: the called module returns the string that begins from the pos-th character of s and ends at the first space, “=” or “>” character. Formal parameter pos (and argument i in the calling module because it is passed by reference) is changed to always point to the next character to process.