Escolar Documentos
Profissional Documentos
Cultura Documentos
• Menu Bar
• Tool Bar
• Project Explorer
• Properties window
• Form Layout Window
• Toolbox
• Form Designer
• Object Browser
In previous versions of Visual Basic, the IDE was designed as a Single Document Interface (SDI). In a
Single Document Interface, each window is a free-floating window that is contained within a main
window and can move anywhere on the screen as long as Visual Basic is the current application. But,
in Visual Basic 6.0, the IDE is in a Multiple Document Interface (MDI) format. In this format, the
windows associated with the project will stay within a single container known as the parent. Code and
form-based windows will stay within the main container form.
Menu Bar
This Menu Bar displays the commands that are required to build an application. The main menu items
have sub menu items that can be chosen when needed. The toolbars in the menu bar provide quick
access to the commonly used commands and a button in the toolbar is clicked once to carry out the
action represented by it.
Toolbox
The Toolbox contains a set of controls that are used to place on a Form at design time thereby
creating the user interface area. Additional controls can be included in the toolbox by using the
Components menu item on the Project menu. A Toolbox is represented in figure 2 shown below.
Control Description
Pointer Provides a way to move and resize the controls form
Displays icons/bitmaps and metafiles. It displays text or acts as a visual
PictureBox
container for other controls.
TextBox Used to display message and enter text.
Frame Serves as a visual and functional container for controls
CommandButton Used to carry out the specified action when the user chooses it.
CheckBox Displays a True/False or Yes/No option.
OptionButton control which is a part of an option group allows the user
OptionButton
to select only one option even it displays mulitiple choices.
ListBox Displays a list of items from which a user can select one.
Contains a TextBox and a ListBox. This allows the user to select an
ComboBox
ietm from the dropdown ListBox, or to type in a selection in the TextBox.
HScrollBar and These controls allow the user to select a value within the specified
VScrollBar range of values
Timer Executes the timer events at specified intervals of time
DriveListBox Displays the valid disk drives and allows the user to select one of them.
DirListBox Allows the user to select the directories and paths, which are displayed.
FileListBox Displays a set of files from which a user can select the desired one.
Shape Used to add shape (rectangle, square or circle) to a Form
Line Used to draw straight line to the Form
used to display images such as icons, bitmaps and metafiles. But less
Image
capability than the PictureBox
Enables the use to connect to an existing database and display
Data
information from it.
Used to link or embed an object, display and manipulate data from other
OLE
windows based applications.
Label Displays a text that the user cannot modify or interact with.
Project Explorer
Docked on the right side of the screen, just under the tollbar, is the Project Explorer window. The
Project Explorer as shown in in figure servres as a quick reference to the various elements of a
project namely form, classes and modules. All of the object that make up the application are packed in
a project. A simple project will typically contain one form, which is a window that is designed as part of
a program's interface. It is possible to develop any number of forms for use in a program, although a
program may consist of a single form. In addition to forms, the Project Explorer window also lists code
modules and classes.
Properties Window
The Properties Window is docked under the Project Explorer window. The Properties Window
exposes the various characteristics of selected objects. Each and every form in an application is
considered an object. Now, each object in Visual Basic has characteristics such as color and size.
Other characteristics affect not just the appearance of the object but the way it behaves too. All these
characteristics of an object are called its properties. Thus, a form has properties and any controls
placed on it will have propeties too. All of these properties are displayed in the Properties Window.
Object Browser
The Object Browser allows us to browse through the various properties, events and methods that are
made available to us. It is accessed by selecting Object Browser from the View menu or pressing the
key F2. The left column of the Object Browser lists the objects and classes that are available in the
projects that are opened and the controls that have been referenced in them. It is possible for us to
scroll through the list and select the object or class that we wish to inspect. After an object is picked
up from the Classes list, we can see its members (properties, methods and events) in the right
column.
A property is represented by a small icon that has a hand holding a piece of paper. Methods are
denoted by little green blocks, while events are denoted by yellow lightning bolt icon.
Form -frm
Label-lbl
TextBox-txt
CommandButton-cmd
CheckBox -chk
OptionButton -opt
ComboBox -cbo
ListBox-lst
Frame-fme
PictureBox -pic
Image-img
Shape-shp
Line -lin
HScrollBar -hsb
VScrollBar -vsb
Real world objects are loaded with properties. For example, a flower is loaded certain color, shape
and fragrance. Similarly programming objects are loaded with properties. A property is a named
attribute of a programming object. Properties define the characteristics of an object such as Size,
Color etc. or sometimes the way in which it behaves. For example, a TextBox accepts properties such
as Enabled, Font, MultiLine, Text, Visible, Width, etc.
• Enables property allows the TextBox to be enabled or disabled at run time depending on the
condition set to True or False.
• Font property sets a particular font in the TextBox.
• MultiLine property allows the TextBox to accept and display multiple lines at run time.
• Text property of the TextBox control sets a particular text in the control.
• Visible property is used to hide the object at run time.
• Width property sets the TextBox to the desired width at design time.
The properties that are discussed above are design-time properties that can be set at the design tme
by selecting the Properties Window. But certain properties cannot be set at desgn time. For example,
the CurrentX and CurrentY properties of a Form cannot be set at the design time.
A method is an action that can be performed on objects. For example, a cat is an object. Its properties
might include long white hair, blue eyes, 3 pounds weight etc. A complete definition of cat must only
encompass on its looks, but should also include a complete itemization of its activities. Therefore, a
cat's methods might be move, jump, play, breath etc.
• The Refresh method enforces a complete repaint of the control or a Form. For example,
Text1.Refresh refreshes the TextBox.
• The Setfocus method moves the focus on the control. For Example Text1.SetFocus sets the
focus to TextBox control Text1.
Let us consider a TextBox control and a few of its associated events to understand the concept of
event driven programming. The TextBox control supports various events such as Change, Click,
MouseMove and many more that will be listed in the Properties dropdown list in the code window for
the TextBox control. We will look into a few of them as given below.
• The code entered in the Change event fires when there is a change in the contents of
the TextBox
• The Click event fires when the TextBox control is clicked.
• The MouseMove event fires when the mouse is moved over the TextBox
As explained above, several events are associated with different controls and forms, some of the
events being common to most of them and few being specific to each control.
Visual Basic uses building blocks such as Variables, Data Types, Procedures, Functions and Control
Structures in its programming environment. This section concentrates on the programming
fundamentals of Visual Basic with the blocks specified.
Modules
Code in Visual Basic is stored in the form of modules. The three kind of modules are Form Modules,
Standard Modules and Class Modules. A simple application may contain a single Form, and the code
resides in that Form module itself. As the application grows, additional Forms are added and there
may be a common code to be executed in several Forms. To avoid the duplication of code, a separate
module containing a procedure is created that implements the common code. This is a standard
Module.
Class module (.CLS filename extension) are the foundation of the object oriented programming in
Visual Basic. New objects can be created by writing code in class modules. Each module can contain:
Declarations : May include constant, type, variable and DLL procedure declarations.
Procedures : A sub function, or property procedure that contain pieces of code that can be executed
as a unit.
These are the rules to follow when naming elements in VB - variables, constants, controls,
procedures, and so on:
1. Numeric
Double Store large floating value which exceeding the single data type value
store monetary values. It supports 4 digits to the right of decimal point and 15
Currency
digits to the left
2. String
Use to store alphanumeric values. A variable length string can store approximately 4 billion characters
3. Date
Use to store date and time values. A variable declared as date type can store both date and time
values and it can store date values 01/01/0100 up to 12/31/9999
4. Boolean
Boolean data types hold either a true or false value. These are not stored as numeric values and
cannot be used as such. Values are internally stored as -1 (True) and 0 (False) and any non-zero
value is considered as true.
5. Variant
Stores any type of data and is the default Visual Basic data type. In Visual Basic if we declare a
variable without any data type by default the data type is assigned as default.
+ Add 5+5 10
- Substract 10-5 5
/ Divide 25/5 5
* Multiply 5*4 20
Relational Operators
Logical Operators
Operators Description
AND Operation will be true only if both the operands are true
Variables in Visual Basic 6
Variables are the memory locations which are used to store values temporarily. A defined naming
strategy has to be followed while naming a variable. A variable name must begin with an alphabet
letter and should not exceed 255 characters. It must be unique within the same scope. It should not
contain any special character like %, &, !, #, @ or $.
There are many ways of declaring variables in Visual Basic. Depending on where the variables are
declared and how they are declared, we can determine how they can be used by our application. The
different ways of declaring variables in Visual Basic are listed below and elucidated in this section.
• Explicit Declaration
• Using Option Explicit statement
• Scope of Variables
Explicit Declaration
Declaring a variable tells Visual Basic to reserve space in memory. It is not must that a variable should
be declared before using it. Automatically whenever Visual Basic encounters a new variable, it assigns
the default variable type and value. This is called implicit declaration. Though this type of declaration is
easier for the user, to have more control over the variables, it is advisable to declare them explicitly.
The variables are declared with a Dim statement to name the variable and its type. The As type clause
in the Dim statement allows to define the data type or object type of the variable. This is called explicit
declaration.
Syntax
For example,
Intcount = Intcount + 1
This calculation will result in intcount yielding a value of 1 as intcount would have been initialized to
zero. This is because the intcount variable has been mityped as incont in the right hand side of the
second variable. But Visual Basic does not see this as a mistake and considers it to be new variable
and therefore gives a wrong result.
In Visual Basic, to prevent errors of this nature, we can declare a variable by adding the following
statement to the general declaration section of the Form.
Option Explicit
This forces the user to declare all the variables. The Option Explicit statement checks in the module
Procedures in Visual Basic 6
Visual Basic offers different types of procedures to execute small sections of coding in applications.
The various procedures are elucidated in details in this section. Visual Basic programs can be broken
into smaller logical components called Procedures. Procedures are useful for condensing repeated
operations such as the frequently used calculations, text and control manipulation etc. The benefits of
using procedures in programming are:
It is easier to debug a program a program with procedures, which breaks a program into discrete
logical limits.
Procedures used in one program can act as building blocks for other programs with slight
modifications.
Sub Procedures
A sub procedure can be placed in standard, class and form modules. Each time the procedure is
called, the statements between Sub and End Sub are executed. The syntax for a sub procedure is as
follows:
arglist is a list of argument names separated by commas. Each argument acts like a variable in the
procedure. There are two types of Sub Procedures namely general procedures and event procedures.
Event Procedures
An event procedure is a procedure block that contains the control's actual name, an underscore(_),
and the event name. The following syntax represents the event procedure for a Form_Load event.
General Procedures
A general procedure is declared when several event procedures perform the same actions. It is a
good programming practice to write common statements in a separate procedure (general procedure)
and then call them in the event procedure.
• The Code window is opened for the module to which the procedure is to be added.
• The Add Procedure option is chosen from the Tools menu, which opens an Add Procedure
dialog box as shown in the figure given below.
• The name of the procedure is typed in the Name textbox
• Under Type, Sub is selected to create a Sub procedure, Function to create a Function
procedure or Property to create a Property procedure.
• Under Scope, Public is selected to create a procedure that can be invoked outside the
module, or Private to create a procedure that can be invoked only from within the module.
We can also create a new procedure in the current module by typing Sub ProcedureName, Function
ProcedureName, or Property ProcedureName in the Code window. A Function procedure returns a
value and a Sub Procedure does not return a value.
Function Procedures
Functions are like sub procedures, except they return a value to the calling procedure. They are
especially useful for taking one or more pieces of data, called arguments and performing some tasks
with them. Then the functions returns a value that indicates the results of the tasks complete within
the function.
The following function procedure calculates the third side or hypotenuse of a right triangle, where A
and B are the other two sides. It takes two arguments A and B (of data type Double) and finally
returns the results.
The above function procedure is written in the general declarations section of the Code window. A
function can also be written by selecting the Add Procedure dialog box from the Tools menu and by
choosing the required scope and type.
Property Procedures
A property procedure is used to create and manipulate custom properties. It is used to create read
only properties for Forms, Standard modules and Class modules.Visual Basic provides three kind of
property procedures-Property Let procedure that sets the value of a property, Property Get procedure
that returns the value of a property, and Property Set procedure that sets the references to an object.
Control Structures in Visual Basic 6.0
Control Statements are used to control the flow of program's execution. Visual Basic supports control
structures such as if... Then, if...Then ...Else, Select...Case, and Loop structures such as Do
While...Loop, While...Wend, For...Next etc method.
If <condition> Then
statement
End If
Method 1
Method 2
e.g.: Assume you have to find the grade using nested if and display in a text box
e.g.: Assume you have to find the grade using select...case and display in the text box
average = txtAverage.Text
Select Case average
Case 100 To 75
txtGrade.Text ="A"
Case 74 To 65
txtGrade.Text ="B"
Case 64 To 55
txtGrade.Text ="C"
Case 54 To 45
txtGrade.Text ="S"
Case 44 To 0
txtGrade.Text ="F"
Case Else
MsgBox "Invalid average marks"
End Select
Note: In this example I have used a message box function. In later lessons you will learn how to use
message box functions.
The Do While...Loop is used to execute statements until a certain condition is met. The following Do
Loop counts from 1 to 100.
A variable number is initialized to 1 and then the Do While Loop starts. First, the condition is tested; if
condition is True, then the statements are executed. When it gets to the Loop it goes back to the Do
and tests condition again. If condition is False on the first pass, the statements are never executed.
number = 1
While number <=100
number = number + 1
Wend
The programs executes the statements between Do and Loop While structure in any case. Then it
determines whether the counter is less than 501. If so, the program again executes the statements
between Do and Loop While else exits the Loop.
Do Until...Loop Statement
Unlike the Do While...Loop and While...Wend repetition structures, the Do Until... Loop structure
tests a condition for falsity. Statements in the body of a Do Until...Loop are executed repeatedly as
long as the loop-continuation test evaluates to False.
An example for Do Until...Loop statement. The coding is typed inside the click event of the command
button
Numbers between 1 to 1000 will be displayed on the form as soon as you click on the command
button.
Dim x As Integer
For x = 1 To 50
Print x
Next
In order to count the numbers from 1 yo 50 in steps of 2, the following loop can be used
For x = 1 To 50 Step 2
Print x
Next
The above coding will display numbers vertically on the form. In order to display numbers horizontally
the following method can be used.
For x = 1 To 50
Print x & Space$ (2);
Next
To increase the space between the numbers increase the value inside the brackets after the &
Space$.
Following example is a For...Next repetition structure which is with the If condition used.
In the output instead of number 4 you will get the "This is number 4".
A For...Next loop condition can be terminated by an Exit For statement. Consider the following
statement block.
Dim x As Integer
For x = 1 To 10
Print x
If x = 5 Then
Print "The program exited at x=5"
Exit For
End If
Next
The preceding code increments the value of x by 1 until it reaches the condition x = 5. The Exit For
statement is executed and it terminates the For...Next loop. The Following statement block containing
Do...While loop is terminated using Exit Do statement.
Dim x As Integer
Do While x < 10
Print x
x = x + 1
If x = 5 Then
Print "The program is exited at x=5"
Exit Do
End If
Loop
With Text1
.Font.Size = 14
.Font.Bold = True
.ForeColor = vbRed
.Height = 230
.Text = "Hello World"
End With
In the above coding, the object Text1, which is a text box is evaluated only once instead of every
associated property or method. This makes the coding simpler and efficient.
The Individual elements of an array are identified using an index. Arrays have upper and lower
bounds and the elements have to lie within those bounds. Each index number in an array is allocated
individual memory space and therefore users must evade declaring arrays of larger size than
required. We can declare an array of any of the basic data types including variant, user-defined types
and object variables. The individual elements of an array are all of the same data type.
Declaring arrays
Arrays occupy space in memory. The programmer specifies the array type and the number of
elements required by the array so that the compiler may reserve the appropriate amount of memory.
Arrays may be declared as Public (in a code module), module or local. Module arrays are declared in
the general declarations using keyword Dim or Private. Local arrays are declared in a procedure using
Dim or Static. Array must be declared explicitly with keyword "As".
Fixed-size array : The size of array always remains the same-size doesn't change during the
program execution.
Dynamic array : The size of the array can be changed at the run time- size changes during the
program execution.
Fixed-sized Arrays
When an upper bound is specified in the declaration, a Fixed-array is created. The upper limit should
always be within the range of long data type.
Declaring a fixed-array
In the above illustration, numbers is the name of the array, and the number 6 included in the
parentheses is the upper limit of the array. The above declaration creates an array with 6 elements,
with index numbers running from 0 to 5.
If we want to specify the lower limit, then the parentheses should include both the lower and upper
limit along with the To keyword. An example for this is given below.
In the above statement, an array of 10 elements is declared but with indexes running from 1 to 6.
A public array can be declared using the keyword Public instead of Dim as shown below.
Multidimensional Arrays
Arrays can have multiple dimensions. A common use of multidimensional arrays is to represent tables
of values consisting of information arranged in rows and columns. To identify a particular table
element, we must specify two indexes: The first (by convention) identifies the element's row and the
second (by convention) identifies the element's column.
Tables or arrays that require two indexes to identify a particular element are called two dimensional
arrays. Note that multidimensional arrays can have more than two dimensions. Visual Basic supports
at least 60 array dimensions, but most people will need to use more than two or three dimensional-
arrays.
It is also possible to define the lower limits for one or both the dimensions as for fixed size arrays. An
example for this is given here.
An example for three dimensional-array with defined lower limits is given below.
Visual Basic starts indexing the array with 0. Therefore, the preceding array actually holds 101 items.
Most programs don't use static arrays because programmers rarely know at compile time how many
items you need and also because static arrays can't be resized during execution. Both these issues
are solved by dynamic arrays. You declare and create dynamic arrays in two distinct steps. In
general, you declare the array to account for its visibility (for example, at the beginning of a module if
you want to make it visible by all the procedures of the module) using a Dim command with an empty
pair of brackets. Then you create the array when you actually need it, using a ReDim statement:
If you're creating an array that's local to a procedure, you can do everything with a single ReDim
statement:
Sub PrintReport()
' This array is visible only to the procedure.
ReDim Customers(1000) As String
' ...
End Sub
If you don't specify the lower index of an array, Visual Basic assumes it to be 0, unless an Option
Base 1 statement is placed at the beginning of the module. My suggestion is this: Never use an
Option Base statement because it makes code reuse more difficult. (You can't cut and paste routines
without worrying about the current Option Base.) If you want to explicitly use a lower index different
from 0, use this syntax instead:
Dynamic arrays can be re-created at will, each time with a different number of items. When you re-
create a dynamic array, its contents are reset to 0 (or to an empty string) and you lose the data it
contains. If you want to resize an array without losing its contents, use the ReDim Preserve
command:
When you're resizing an array, you can't change the number of its dimensions nor the type of the
values it contains. Moreover, when you're using ReDim Preserve on a multidimensional array, you
can resize only its last dimension:
Finally, you can destroy an array using the Erase statement. If the array is dynamic, Visual Basic
releases the memory allocated for its elements (and you can't read or write them any longer); if the
array is static, its elements are set to 0 or to empty strings.
You can use the LBound and UBound functions to retrieve the lower and upper indices. If the array
has two or more dimensions, you need to pass a second argument to these functions to specify the
dimension you need:
Type MyUDT
StaticArr(100) As Long
DynamicArr() As Long
End Type
...
Dim udt As MyUDT
' You must DIMension the dynamic array before using it.
ReDim udt.DynamicArr(100) As Long
' You don't have to do that with static arrays.
udt.StaticArr(1) = 1234
The memory needed by a static array is allocated within the UDT structure; for example, the StaticArr
array in the preceding code snippet takes exactly 400 bytes. Conversely, a dynamic array in a UDT
takes only 4 bytes, which form a pointer to the memory area where the actual data is stored. Dynamic
arrays are advantageous when each individual UDT variable might host a different number of array
items. As with all dynamic arrays, if you don't dimension a dynamic array within a UDT before
accessing its items, you get an error 9—"Subscript out of range."
You can even create an array of Variant elements on the fly using the Array function and store it in a
Variant variable:
Likewise, you can pass an array to a procedure that expects a Variant parameter and then access the
elements of the array through that parameter:
The most interesting feature of the preceding routine is that it works correctly with any type of numeric
one-dimensional array. It even works with String arrays, but in that case you get the concatenation of
all items, not their sum. This procedure is extremely powerful and reduces the amount of code you
have to write to deal with different kinds of arrays. But you should be aware that accessing array items
through a Variant parameter noticeably slows down the execution. If you need the best performance,
write specific routines that process specific types of arrays.
You can also pass a multidimensional array to a routine that expects a Variant parameter. In this
case, you can still access the array elements through the Variants, but if you don't know at compile
time how many dimensions the array has, your routine has to determine that number before
proceeding. You can get this value using a trial-and-error approach:
Here's a modified ArraySum routine that uses NumberOfDims and works with both one- and two-
dimensional arrays:
Often, if a Variant contains an array, you don't know the basic type of that array in advance. The
VarType function returns the sum of the vbArray constant (decimal 8192), plus the VarType of the
data included in the array. This lets you test that the array passed to a routine is of a given type:
You can also test whether a Variant holds an array using the IsArray function. When a Variant
variable holds an array, the TypeName function appends a pair of empty parentheses to its result:
As I've explained, you can either assign an array to a Variant variable or you can pass an array as a
Variant parameter of a procedure. While the two operations look very similar, they're substantially
different. To execute an assignment, Visual Basic makes a physical copy of the array. As a result, the
Variant variable doesn't point to the original data but to the copy; from this point on, all the
manipulations you do through the Variant variable don't affect the original array. Conversely, if you
call a procedure and pass an array as a Variant parameter, no data is physically copied and the
Variant simply works as an alias of the array. You can reorder array items or modify their values, and
your changes are immediately reflected in the original array
Assigning and returning arrays in Visual Basic 6
Visual Basic 6 adds two important features to arrays. First, you can perform assignments between
arrays. Second, you can write procedures that return arrays. You can assign arrays only of the same
type and only if the target is a dynamic array. (The latter condition is necessary because Visual Basic
might need to resize the target array.)
It's no surprise that native assignment commands are always faster than the corresponding For…Next
loops that copy one item at a time. The actual increment in speed heavily depends on the data type of
the arrays and can vary from 20 percent to 10 times faster. A native assignment between arrays also
works if the source array is held in a Variant. Under Visual Basic 4 and 5, you could store an array in
a Variant, but you couldn't do the opposite—that is, retrieve an array stored in a Variant variable and
store it back in an array of a specific type. This flaw has been fixed in Visual Basic 6:
You often use the capacity to assign arrays to build functions that return arrays. Notice that pair of
brackets at the end of the first line in the following procedure:
The new capability of returning arrays lets you write highly versatile array routines. Visual Basic 6
itself includes a few new string functions—namely Join, Split, and Filter—that rely on it. (You'll find
more about these new string functions in Chapter 5). Here are two examples of what you can do with
this intriguing feature:
' Returns a portion of a Long array
' Note: fails if FIRST or LAST are not valid
Function SubArray(arr() As Long, first As Long, last As Long, _
newFirstIndex As Long) As Long()
Dim i As Long
ReDim result(newFirstIndex To last _ first + newFirstIndex) As Long
For i = first To last
result(newFirstIndex + i - first) = arr(i)
Next
SubArray = result
End Function
Byte arrays are somewhat special because Visual Basic lets you directly assign strings to them. In
this case, Visual Basic performs a direct memory copy of the contents of the string. Because all Visual
Basic 5 and 6 strings are Unicode strings (two bytes per character), the target array is redimensioned
to account for the actual string length in bytes (which you can determine using the LenB function). If
the string contains only characters whose code is in the range 0 through 255 (the case if you work
with Latin alphabets), every other byte in the array will be 0:
Text = b()
This special treatment reserved for Byte arrays is meant to ease the conversion from old Visual Basic
3 applications that use strings to hold binary data, as I explained in "The Byte Data Type" section,
earlier in this chapter. You can exploit this feature to create blindingly fast string routines when you
have to process each individual character in a string. For example, see how quickly you can count all
the spaces in a string:
' NOTE: this function might not work with non-Latin alphabets.
Function CountSpaces(Text As String) As Long
Dim b() As Byte, i As Long
b() = Text
For i = 0 To UBound(b) Step 2
' Consider only even-numbered items.
' Save time and code using the function name as a local variable.
If b(i) = 32 Then CountSpaces = CountSpaces + 1
Next
End Function
The preceding routine is about three times faster than a regular routine, which uses Asc and Mid$
functions to process all the characters in the argument, and even faster if you turn on the Remove
Array Bounds Check compiler optimization. The only drawback of this technique is that it isn't
Unicode-friendly because it considers only the least significant byte in each 2-byte character. If you
plan to convert your application to some language that relies on Unicode—Japanese, for example—
you should stay clear of this optimization technique.
Some of the most common operations you perform on arrays are inserting and deleting items, shifting
all the remaining elements toward higher indices to make room or toward lower indices to fill the
"hole" a deletion has left. You usually do this with a For…Next loop, and you can even write generic
array procedures that work with any type of array (with the usual restrictions about arrays of UDTs
and fixed-length strings that can't be passed to a Variant parameter):
If your application works intensively with arrays, you might find that an approach based on For…Next
loops is too slow. In some cases, you can considerably speed up these operations by using the
RtlMoveMemory API function, which many Visual Basic programmers know under its popular alias
name, CopyMemory.1 This function lets you move a block of bytes from one memory address to
another memory address and works correctly even if the two areas partially overlap. Here's the code
that inserts a new item in an array of Longs:
IMPORTANT NOTE: The prerequisite for using the CopyMemory API function is that data must be
stored in contiguous memory locations, so you absolutely can't use it to insert or remove elements in
String and Object arrays, nor in arrays of UDTs that contain conventional strings, object references, or
dynamic arrays. (Fixed-length strings and static arrays in UDTs are OK, though.)
Note that while you can't use the preceding routines for arrays other than Long arrays, the statements
in the procedure body can be recycled for another data type without any change, thanks to the use of
the LenB function. Therefore, you can derive new array functions that work for other data types by
simply modifying the procedure's name and its parameter list. For example, you can create a new
function that deletes an item in a Double array by editing just the first line of code (shown in boldface):
Sorting is an operation that you often perform on arrays. As you probably know, there are dozens of
different sort algorithms, each one with its strengths and weaknesses. I found that the Shell Sort
algorithm works well in most cases, and I've prepared a generic routine that sorts any one-
dimensional array of a data type compatible with the Variant type, either in ascending or descending
order:
The technique is conceptually simple: Since you can store an array in a Variant variable, you can
build an array of Variants, where each item holds an array. Each subarray—a row of this pseudo-
array—can hold a different number of elements, and you don't need to use more memory than is
strictly necessary.
Here's an example, based on an imaginary PIM (Personal Information Manager) program. In this
program, you need to keep track of a list of appointments for each day of the year. The simplest
solution would be to use an array in which each row corresponds to a day in the year and each
column to a possible appointment. (For the sake of simplicity, let's assume that each appointment's
data can be held in a string.)
Of course, you now have the problem of setting a reasonable value for the MAX_APPOINTMENTS
symbolic constant. It should be high enough to account for all possible appointments in a day but not
too high because you might be wasting a lot of memory without any real reason. Let's see how the
array of arrays technique can help us save memory without posing any artificial limit to your
application:
In this example, I kept the code as simple as possible and used an array of Variant arrays. You could
save even more memory if each row of this array were built using an array of a more specific data
type (String, in this case). Note the special syntax used to address an item in an array of arrays:
Nothing keeps you from extending this concept further, introducing an array of arrays of arrays, and
so on. If you're dealing with arrays in which each row can vary considerably in length, this approach is
going to save you a lot of memory and, in most cases, improve your overall performance too. A key
feature of an array of arrays is that you can process entire rows of your pseudo-array as if they were
single entities. For example, you can swap them, replace them, add and delete them, and so on.
Finally, an important advantage of this technique is that you can add new rows without losing the
current contents of the array. (Remember that you can use ReDim Preserve on regular arrays only to
modify the number of columns, not the number of rows.)
A Type statement is used to define a user-defined type in the General declaration section of a form or
module. User-defined data types can only be private in form while in standard modules can be public
or private. An example for a user defined data type to hold the product details is as given below.
A User-Defined data type can be referenced in an application by using the variable name in the
procedure along with the item name in the Type block. Say, for example if the text property of a
TextBox namely text1 is to be assigned the name of the electronic good, the statement can be written
as given below.
Text1.Text = ElectronicGoods.ProdName
Text1.Text = ElectronicGoods(i).ProdName
User-defined data types can also be passed to procedures to allow many related items as one
argument.
Constants
Constants are named storage locations in memory, the value of which does not change during
program Execution. They remain the same throughout the program execution. When the user wants
to use a value that never changes, a constant can be declared and created. The Const statement is
used to create a constant. Constants can be declared in local, form, module or global scope and can
be public or private as for variables. Constants can be declared as illustrated below.
For example consider a statement that will set the window state of a form to be maximized.
Form1.Windowstate = 2
Form1.WindowState = vbMaximized
Conversion To Function
Boolean Cbool
Byte Cbyte
Currency Ccur
Date Cdate
Decimals Cdec
Double CDbl
Integer Cint
Long CLng
Single CSng
String CStr
Variant Cvar
Error CVErr
A conversion function should always be placed at the right hand side of the calculation statement.
Not only does Visual Basic let you store date and time information in the specific Date data type, it
also provides a lot of date- and time-related functions. These functions are very important in all
business applications and deserve an in-depth look. Date and Time are internally stored as numbers
in Visual Basic. The decimal points represents the time between 0:00:00 and 23:59:59 hours inclusive.
The system's current date and time can be retrieved using the Now, Date and Time functions in Visual
Basic. The Now function retrieves the date and time, while Date function retrieves only date and Time
function retrieves only the time.
To display both the date and time together a message box is displayed use the statement given below.
MsgBox "The current date and time of the system is" & Now
Here & is used as a concatenation operator to concentrate the string and the Now function. Selective
portions of the date and time value can be extracted using the below listed functions.
The calculation and conversion functions related to date and time functions are listed below.
The CausesValidation Property and the Validate
Event - Visual Basic 6 TextBox Control
Visual Basic 6 has finally come up with a solution for most of the validation issues that have afflicted
Visual Basic developers for years. As you'll see in a moment, the Visual Basic 6 approach is simple
and clean; it really astonishes me that it took six language versions to deliver such a lifesaver. The
keys to the new validation features are the Validate event and the CausesValidation property. They
work together as follows: When the input focus leaves a control, Visual Basic checks the
CausesValidation property of the control that is about to receive the focus. If this property is True,
Visual Basic fires the Validate event in the control that's about to lose the focus, thus giving the
programmer a chance to validate its contents and, if necessary, cancel the focus shift.
Let's try a practical example. Imagine that you have five controls on a form: a required field (a
TextBox control, txtRequired, that can't contain an empty string), a numeric field, txtNumeric, that
expects a value in the range 1 through 1000, and three push buttons: OK, Cancel, and Help. (See the
figure below.) You don't want to perform validation if the user presses the Cancel or Help buttons, so
you set their CausesValidation properties to False. The default value for this property is True, so you
don't have to modify it for the other controls. Run the sample program on the companion CD, type
something in the required TextBox, and then move to the second field. Because the second field's
CausesValidation property is True, Visual Basic fires a Validate event in the first TextBox control:
If the Cancel parameter is set to True, Visual Basic cancels the user's action and takes the input focus
back on the txtRequired control: No other GotFocus and LostFocus events are generated. On the
other hand, if you typed something in the required field, the focus will now be on the second field (the
numeric text box). Try clicking on the Help or Cancel buttons: No Validate event will fire this time
because you set the CausesValidation property for each of these controls to False. Instead, click on
the OK button to execute the Validate event of the numeric field, where you can check it for invalid
characters and valid range.
A demonstration program that lets you experiment with the new Visual Basic Validate features
In some circumstances, you might want to programmatically validate the control that has the focus
without waiting for the user to move the input focus. You can do it with the form's ValidateControls
method, which forces the Validate event of the control that has the input focus. Typically, you do it
when the user closes the form:
Checking the UnloadMode parameter is important; otherwise, your application will mistakenly execute
a ValidateControls method when the user clicks on the Cancel button. Note that ValidateControls
returns an error 380 if Cancel was set in the Validate event procedure of the control that had the
focus.
Visual Basic 6's validation scheme has two flaws, though. If your form has a CommandButton whose
Default property is set to True, pressing the Enter key while the input focus is on another control
results in a click on the CommandButton control but doesn't fire a Validate event, even if the
CausesValidation property of the CommandButton control is set to True. The only way to solve this
problem is to invoke the ValidateControls method from within the default CommandButton control's
Click event procedure.
The second flaw is that the Validate event doesn't fire when you're moving the focus from a control
whose CausesValidation property is False, even if the control that receives the focus has its
CausesValidation property set to True.
The new Visual Basic 6 validation mechanism is simple and can be implemented with little effort. But
it isn't the magic answer to all your validation needs. In fact, this technique can only enforce field-level
validation; it does nothing for record-level validation. In other words, it ensures that one particular field
is correct, not that all fields in the form contain valid data. To see what I mean, run the demonstration
program, enter a string in the first field, and press Alt+F4 to close the form. Your code won't raise an
error, even if the second field doesn't contain a valid number! Fortunately, it doesn't take much to
create a generic routine that forces each control on the form to validate itself:
The CausesValidation property and the Validate event are shared by all the intrinsic controls that are
able to get the focus as well as by most external ActiveX controls, even those not specifically written
for Visual Basic. This is possible because they are extender features, provided by the Visual Basic
runtime to all the controls placed on a form's surface.
One Visual Basic operator has great potential when it comes time to validate complex strings but is
neglected by most Visual Basic developers. Let's say you have a product code that consists of two
uppercase characters followed by exactly three digits. You might think that you need some complex
string functions to validate such a string until you try the Like operator, as follows:
Auto-Tabbing Fields
Users aren't usually delighted to spend all their time at the keyboard. Your job as a programmer is to
make their jobs easier, and so you should strive to streamline their everyday work as much as
possible. One way to apply this concept is to provide them with auto-tabbing fields, which are fields
that automatically advance users to the next field in the Tab order as soon as they enter a valid value.
Most often, auto-tabbing fields are those TextBox controls whose MaxLength property has been
assigned a non-null value. Implementing such an auto-tabbing field in Visual Basic is straightforward:
The trick, as you see, is to have your program provide the Tab key on behalf of your user. In some
cases, this simple approach doesn't work—for example, when you paste a long string into the field.
You might want to write code that works around this and other shortcomings. Auto-tabbing is a nice
feature but not vital to the application, so whether you write a workaround or not isn't a real problem in
most cases.
Formatting Text
Many business applications let you enter data in one format and then display it in another. For
example, numeric values can be formatted with thousand separators and a fixed number of decimal
digits. Currency values might have a $ symbol (or whatever your national currency symbol is)
automatically inserted. Phone numbers can be formatted with dashes to split into groups of digits.
Credit-card numbers can be made more readable with embedded spaces. Dates can be shown in
long-date format ("July 22, 2007"). And so on.
The LostFocus event is an ideal occasion to format the contents of a TextBox control as soon as the
input focus leaves it. In most cases, you can perform all your formatting chores using the Format
function. For example, you can add thousand separators to a numeric value in the txtNumber control
using this code:
When the field regains the focus, you'll want to get rid of those thousand separators. You can do it
easily using the CDbl function:
In some cases, however, formatting and unformatting a value isn't that simple. For example, you can
format a Currency value to add parentheses around negative numbers, but there's no built-in Visual
Basic function able to return a string formatted in that way to its original condition. Fear not, because
nothing prevents you from creating your own formatting and unformatting routines. I have built two
general-purpose routines for you to consider.
FilterNumber builds on FilterString to strip down all formatting characters in a number and can also
trim trailing decimal zeros:
The feature I like most in FilterNumber is that it's locale-independent. It works equally well on both
sides of the Atlantic ocean (and on other continents, as well.) Instead of hard-coding the decimal
separator character in the code, the routine determines it on the fly, using the Visual Basic for
Applications (VBA) Format function. Start thinking internationally now, and you won't have a nervous
breakdown when you have to localize your applications in German, French, and Japanese.
The Format function lets you retrieve many locale-dependent characters and
separators.
Format$(0.1, ".") ' Decimal separator
Format$(1, ",") ' Thousand separator
Mid$(Format(#1/1/99#, "short date"), 2, 1) ' Date separator
You can also determine whether the system uses dates in "mm/dd/yy" (U.S.) format or "dd/mm/yy"
(European) format, using this code:
Else
' dd/mm/yyyy format
End If
There's no direct way to determine the currency symbol, but you can derive it by analyzing the result
of this function:
It isn't difficult to write a routine that internally uses the information I've just given you to extract the
currency symbol as well as its default position (before or after the number) and the default number of
decimal digits in currency values. Remember, in some countries the currency symbol is actually a
string of two or more characters.
To illustrate these concepts in action, I've built a simple demonstration program that shows how you
can format numbers, currency values, dates, phone numbers, and credit-card numbers when exiting a
field, and how you can remove that formatting from the result when the input focus reenters the
TextBox control. Follwoing figure shows the formatted results.
Formatting and unformatting the contents of TextBox controls makes for more professional-looking
applications
Private Sub txtNumber_GotFocus()
' Filter out nondigit chars and trailing zeros.
On Error Resume Next
txtNumber.Text = FilterNumber(txtNumber.Text, True)
End Sub
Private Sub txtNumber_LostFocus()
' Format as a number, grouping thousand digits.
On Error Resume Next
txtNumber.Text = Format(CDbl(txtNumber.Text), _
"#,###,###,##0.######")
End Sub
Instead of inserting the code that formats phone numbers and credit-card numbers right in the
LostFocus event procedures, I built two distinct routines, which can be more easily reused in other
applications, as shown in the code below.
Function FormatPhoneNumber(Text As String) As String
Dim tmp As String
If Text <> "" Then
' First get rid of all embedded dashes, if any.
tmp = FilterString(Text, "0123456789")
' Then reinsert them in the correct position.
If Len(tmp) <= 7 Then
FormatPhoneNumber = Format$(tmp, "!@@@-@@@@")
Else
FormatPhoneNumber = Format$(tmp, "!@@@-@@@-@@@@")
End If
End If
End Function
Unfortunately, there isn't any way to create locale-independent routines that can format any phone
number anywhere in the world. But by grouping all your formatting routines in one module, you can
considerably speed up your work if and when it's time to convert your code for another locale
You create multiline TextBox controls by setting the MultiLine property to True and the ScrollBars
property to 2-Vertical or 3-Both. A vertical scroll bar causes the contents of the control to automatically
wrap when a line is too long for the control's width, so this setting is most useful when you're creating
memo fields or simple word processor-like programs. If you have both a vertical and a horizontal scroll
bar, the TextBox control behaves more like a programmer's editor, and longer lines simply extend
beyond the right border. I've never found a decent use for the other settings of the ScrollBars property
(0-None and 1-Horizontal) in a multiline TextBox control. Visual Basic ignores the ScrollBars property
if MultiLine is False.
Both these properties are read-only at run time, which means that you can't alternate between a
regular and a multiline text box, or between a word processor-like multiline field (ScrollBars = 2-
Vertical) and an editorlike field (ScrollBars = 3-Both). To tell the whole truth, Visual Basic's support for
multiline TextBox controls leaves much to be desired. You can do very little with such controls at run
time, except to retrieve and set their Text properties. When you read the contents of a multiline
TextBox control, it's up to you to determine where each line of text starts and ends. You do this with a
loop that searches for carriage return (CR) and line feed (LF) pairs, or even more easily using the new
Split string function:
' Print the lines of text in Text1, labeling them with their line numbers.
Dim lines() As String, i As Integer
lines() = Split(Text1.Text, vbCrLf)
For i = 0 To UBound(lines)
Print (i + 1) & ": " & lines(i)
Next
The support offered by Visual Basic for multiline TextBox controls ends here. The language doesn't
offer any means for learning such vital information as at which point each line of text wraps, which are
the first visible line and the first visible column, which line and column the caret is on, and so on.
Moreover, you have no means of programmatically scrolling through a multiline text box. The
solutions to these problems require Microsoft Windows API programming. In my opinion, however,
Visual Basic should offer these features as built-in properties and methods.
You should account for two minor issues when including
one or more multiline TextBox controls on your forms.
When you enter code in a word processor or an
editor, you expect that the Enter key will add a
newline character (more precisely, a CR-LF character
pair) and that the Tab key will insert a tab character
and move the caret accordingly. Visual Basic
supports these keys, but because both of them have
special meaning to Windows the support is limited:
The Enter key adds a CR-LF pair only if there isn't a
default push button on the form, and the Tab key
inserts a tab character only if there aren't other
controls on the form whose TabStop property is set to
True. In many circumstances, these requirements
can't be met, and some of your users will find your
user interface annoying. If you can't avoid this
problem, at least add a reminder to your users that
they can add new lines using the Ctrl+Enter key
combination and insert tab characters using the
Ctrl+Tab key combination. Another possible approach
is to set the TabStop property to False for all the
controls in the form in the multiline TextBox's
GotFocus event and to restore the original values in
the LostFocus event procedure Label and Frame
Controls in Visual Basic 6 (VB6)
Label and Frame controls have a few features in common, so it makes sense to explain them
together. First they're mostly "decorative" controls that contribute to the user interface but are seldom
used as programmable objects. In other words, you often place them on the form and arrange their
properties as your user interface needs dictate, but you rarely write code to serve their events,
generally, or manipulate their properties at run time.
Label Controls
Most people use Label controls to provide a descriptive caption and possibly an associated hot key for
other controls, such as TextBox, ListBox, and ComboBox, that don't expose the Caption property. In
most cases, you just place a Label control where you need it, set its Caption property to a suitable
string (embedding an ampersand character in front of the hot key you want to assign), and you're
done. Caption is the default property for Label controls. Be careful to set the Label's TabIndex
property so that it's 1 minus the TabIndex property of the companion control.
Other useful properties are BorderStyle(if you want the Label control to appear inside a 3D border)
and Alignment (if you want to align the caption to the right or center it on the control). In most cases,
the alignment depends on how the Label control relates to its companion control: for example, if the
Label control is placed to the left of its companion field, you might want to set its Alignment property to
1-Right Justify. The value 2-Center is especially useful for stand-alone Label controls.
You can insert a literal & character in a Label control's Caption property by doubling it. For example,
to see Research & Development you have to type &Research && Development. Note that if you have
multiple but isolated &s, the one that selects the hot key is the last one and all others are ignored.
This tip applies to all the controls that expose a Caption property. (The & has no special meaning in
forms' Caption properties, however.)
If the caption string is a long one, you might want to set the Label's WordWrap property to True so
that it will extend for multiple lines instead of being truncated by the right border of the control.
Alternatively, you might decide to set the AutoSize property to True and let the control automatically
resize itself to accommodate longer caption strings.
You sometimes need to modify the default value of a Label's BackStyle property. Label controls
usually cover what's already on the form's surface (other lightweight controls, output from graphic
methods, and so on) because their background is considered to be opaque. If you want to show a
character string somewhere on the form but at the same time you don't want to obscure underlying
objects, set the BackStyle property to 0-Transparent.
If you're using the Label control to display data read from elsewhere—for example, a database field or
a text file—you should set its UseMnemonics property to False. In this case, & characters have no
special meaning to the control, and so you indirectly turn off the control's hot key capability. I mention
this property because in older versions of Visual Basic, you had to manually double each & character
to make the ampersand appear in text. I don't think all developers are aware that you can now treat
ampersands like regular characters.
As I said before, you don't usually write code in Label control event procedures. This control exposes
only a subset of the events supported by other controls. For example, because Label controls can
never get the input focus, they don't support GotFocus, LostFocus, or any keyboard-related events. In
practice, you can take advantage only of their mouse events: Click, DblClick, MouseDown,
MouseMove, and MouseUp. If you're using a Label control to display data read from a database, you
might sometimes find it useful to write code in its Change event. A Label control doesn't expose a
specific event that tells programmers when users press its hot keys.
You can do some interesting tricks with Label controls. For example, you can use them to provide
rectangular hot spots for images loaded onto the form. To create that context-sensitive ToolTip, I
loaded the image on the form using the form's Picture property and then I placed a Label control over
the Microsoft BackOffice logo, setting its Caption property to an empty string and the BackStyle
property to 0-Transparent. These properties make the Label invisible, but it correctly shows its ToolTip
when necessary. And because it still receives all mouse events, you can use its Click event to react to
users' actions.
Frame Controls
Frame controls are similar to Label controls in that they can serve as captions for those controls that
don't have their own. Moreover, Frame controls can also (and often do) behave as containers and
host other controls. In most cases, you only need to drop a Frame control on a form and set its
Caption property. If you want to create a borderless frame, you can set its BorderStyle property to 0-
None.
Controls that are contained in the Frame control are said to be child controls. Moving a control at
design time over a Frame control—or over any other container, for that matter—doesn't automatically
make that control a child of the Frame control. After you create a Frame control, you can create a
child control by selecting the child control's icon in the Toolbox and drawing a new instance inside the
Frame's border. Alternatively, to make an existing control a child of a Frame control, you must select
the control, press Ctrl+X to cut it to the Clipboard, select the Frame control, and press Ctrl+V to paste
the control inside the Frame. If you don't follow this procedure and you simply move the control over
the Frame, the two controls remain completely independent of each other, even if the other control
appears in front of the Frame control.
Frame controls, like all container controls, have two interesting features. If you move a Frame control,
all the child controls go with it. If you make a container control disabled or invisible, all its child
controls also become disabled or invisible. You can exploit these features to quickly change the state
of a group of related controls.
When compared to TextBox controls, these controls are really simple. Not only do they expose
relatively few properties, they also support a limited number of events, and you don't usually write
much code to manage them.
You can use two other properties at design time to modify the behavior of a CommandButton control.
You can set the Default property to True if it's the default push button for the form (the button that
receives a click when the user presses the Enter key—usually the OK or Save button). Similarly, you
can set the Cancel property to True if you want to associate the button with the Escape key.
The only relevant CommandButton's run-time property is Value, which sets or returns the state of the
control (True if pressed, False otherwise). Value is also the default property for this type of control. In
most cases, you don't need to query this property because if you're inside a button's Click event you
can be sure that the button is being activated. The Value property is useful only for programmatically
clicking a button:
The CommandButton control supports the usual set of keyboard and mouse events (KeyDown,
KeyPress, KeyUp, MouseDown, MouseMove, MouseUp, but not the DblClick event) and also the
GotFocus and LostFocus events, but you'll rarely have to write code in the corresponding event
procedures.
Preliminary operations for an OptionButton control are similar to those already described for
CheckBox controls. You set an OptionButton control's Caption property to a meaningful string, and if
you want you can change its Alignment property to make the control right aligned. If the control is the
one in its group that's in the selected state, you also set its Valueproperty to True. (The
OptionButton's Value property is a Boolean value because only two states are possible.) Value is the
default property for this control.
At run time, you typically query the control's Value property to learn which button in its group has been
selected. Let's say you have three OptionButton controls, named optWeekly, optMonthly, and
optYearly. You can test which one has been selected by the user as follows:
If optWeekly.Value Then
' User prefers weekly frequency.
ElseIf optMonthly.Value Then
' User prefers monthly frequency.
ElseIf optYearly.Value Then
' User prefers yearly frequency.
End If
Strictly speaking, you can avoid the test for the last OptionButton control in its group because all
choices are supposed to be mutually exclusive. But the approach I just showed you increases the
code's readability.
A group of OptionButton controls is often hosted in a Frame control. This is necessary when there are
other groups of OptionButton controls on the form. As far as Visual Basic is concerned, all the
OptionButton controls on a form's surface belong to the same group of mutually exclusive selections,
even if the controls are placed at the opposite corners of the window. The only way to tell Visual Basic
which controls belong to which group is by gathering them inside a Frame control. Actually, you can
group your controls within any control that can work as a container—PictureBox, for example—but
Frame controls are often the most reasonable choice.
Example
Open a new Standard EXE project and the save the Form as Option.frm and save the project as
Option.vbp.
The following code is entered in the general declarations section of the Form.
The variable is initialized to 0 by default. The change event procedure checks to ascertain the number
system (Octal, Hexadecimal) that is in effect and then reads in the number.
The Val function is used to translate string to a number and can recognize Octal and Hexadecimal
strings. The LTrim function trims the leading blanks in the text. The following code is entered in the
click events of the OptionButton controls.
The follwoing code is entered in the click event of teh Close button.
The Application is run by pressing F5 or clicking on the Run icon in the tool bar. By pressing the Exit
button the program is terminated.
PictureBox and Image Controls in Visual Basic 6
Both PictureBox and Image controls let you display an image, so let's compare them and see when it
makes sense to choose one or the other.
Loading images
Once you place a PictureBox on a form, you might want to load an image in it, which you do by setting
the Picture property in the Properties window. You can load images in many different graphic formats,
including bitmaps (BMP), device independent bitmaps (DIB), metafiles (WMF), enhanced metafiles
(EMF), GIF and JPEG compressed files, and icons (ICO and CUR). You can decide whether a control
should display a border, resetting the BorderStyle to 0-None if necessary. Another property that
comes handy in this phase is AutoSize: Set it to True and let the control automatically resize itself to
fit the assigned image.
You might want to set the Align property of a PictureBox control to something other than the 0-None
value. By doing that, you attach the control to one of the four form borders and have Visual Basic
automatically move and resize the PictureBox control when the form is resized. PictureBox controls
expose a Resize event, so you can trap it if you need to move and resize its child controls too.
You can do more interesting things at run time. To begin with, you can programmatically load any
image in the control using the LoadPicture function:
Picture1.Picture = LoadPicture("c:\windows\setup.bmp")
and you can clear the current image using either one of the following statements:
' These are equivalent.
Picture1.Picture = LoadPicture("")
Set Picture1.Picture = Nothing
The LoadPicture function has been extended in Visual Basic 6 to support icon files containing multiple
icons. The new syntax is the following:
where values in square brackets are optional. If filename is an icon file, you can select a particular
icon using the size or colordepth arguments. Valid sizes are 0-vbLPSmall, 1-vbLPLarge (system icons
whose sizes depend on the video driver), 2-vbLPSmallShell, 3-vbLPLargeShell (shell icons whose
dimensions are affected by the Caption Button property as set in the Appearance tab in the screen's
Properties dialog box), and 4-vbLPCustom (size is determined by x and y). Valid color depths are 0-
vbLPDefault (the icon in the file that best matches current screen settings), 1-vbLPMonochrome, 2-
vbLPVGAColor (16 colors), and 3-vbLPColor (256 colors).
You can copy an image from one PictureBox control to another by assigning the target control's
Picture property:
Picture2.Picture = Picture1.Picture
PictureBox controls are equipped with a very powerful method that enables the programmer to
perform a wide variety of graphic effects, including zooming, scrolling, panning, tiling, flipping, and
many fading effects: This is the PaintPicture method. (This method is also exposed by form objects,
but it's most often used with PictureBox controls.) In a nutshell, this method performs a pixel-by-pixel
copy from a source control to a destination control. The complete syntax of this method is complex
and rather confusing:
The only required arguments are the source PictureBox control's Picture property and the coordinates
inside the destination control where the image must be copied. The destX / destY arguments are
expressed in the ScaleMode of the destination control; by varying them, you can make the image
appear exactly where you want. For example, if the source PictureBox control contains a bitmap 3000
twips wide and 2000 twips tall, you can center this image on the destination control with this
command:
In general, Visual Basic doesn't provide a way to determine the size of a bitmap loaded into a
PictureBox control. But you can derive this information if you set the control's AutoSize property to
True and then read the control's ScaleWidth and ScaleHeight properties. If you don't want to resize a
visible control just to learn the dimensions of a bitmap, you can load it into an invisible control, or you
can use this trick, based on the fact that the Picture property returns an StdPicture object, which in
turn exposes the Height and Width properties:
By the way, in all subsequent code examples I assume that the source PictureBox control's
ScaleWidth and ScaleHeight properties match the actual bitmap's size. By default, the PaintPicture
method copies the entire source bitmap. But you can copy just a portion of it, passing a value for
srcWidth and srcHeight:
If you're copying just a portion of the source image, you probably want to pass a specific value for the
srcX and srcY values as well, which correspond to the coordinates of the top-left corner of the area
that will be copied from the source control:
You can use this method to tile a target PictureBox control (or form) with multiple copies of an image
stored in another control:
Another great feature of the PaintPicture method lets you resize the image while you transfer it, and
you can even specify different zoom-in and zoom-out factors for the x- and y-axes independently. You
just have to pass a value to the destWidth and destHeight arguments: If these values are greater than
the source image's corresponding dimensions, you achieve a zoom-in effect, and if they are less you
get a zoom-out effect. For example, see how you can double the size of the original image:
picDest.PaintPicture picSource.Picture, 0, 0, _
picSource.ScaleWidth * 2, picSource.ScaleHeight * 2
As a special case of the syntax of the PaintPicture method, the source image can even be flipped
along its x-axis, y-axis, or both by passing negative values for these arguments:
As you might expect, you can combine all these effects together, magnifying, reducing, or flipping just
a portion of the source image, and have the result appear in any point of the destination PictureBox
control (or form). You should find no problem in reusing all those routines in your own applications.
As if all these capabilities weren't enough, we haven't covered the last argument of the PaintPicture
method yet. The opcode argument lets you specify which kind of Boolean operation must be
performed on pixel bits as they're transferred from the source image to the destination. The values
you can pass to this argument are the same that you assign to the DrawMode property. The default
value is 13-vbCopyPen, which simply copies the source pixels in the destination control. By playing
with the other settings, you can achieve many interesting graphical effects, including simple
animations.
When you're working with an Image control, you typically load a bitmap into its Picture property either
at design time or at run time using the LoadPicture function. Image controls don't expose the AutoSize
property because by default they resize to display the contained image (as it happens with PictureBox
controls set at AutoSize = True). On the other hand, Image controls support a Stretch property that, if
True, resizes the image (distorting it if necessary) to fit the control. In a sense, the Stretch property
somewhat remedies the lack of the PaintPicture method for this control. In fact, you can zoom in to or
reduce an image by loading it in an Image control and then setting its Stretch property to True to
change its width and height:
Image controls support all the usual mouse events. For this reason, many Visual Basic developers
have used Image controls to simulate graphical buttons and toolbars. Now that Visual Basic natively
supports these controls, you'd probably better use Image controls only for what they were originally
intended.
The Timer, Line, Shape and OLE Controls in
Visual Basic 6 (VB6)
Timer controls let you write interesting programs with just a few lines of code. The typical (and
abused) example is a digital clock. Just to make things a bit more compelling, I added flashing colons:
You must be careful not to write a lot of code in the Timer event procedure because this code will be
executed at every pulse and therefore can easily degrade your application's performance. Just as
important, never execute a DoEvents statement inside a Timer event procedure because you might
cause the procedure to be reentered, especially if the Interval property is set to a small value and
there's a lot of code inside the procedure.
Timer controls are often useful for updating status information on a regular basis. For example, you
might want to display on a status bar a short description of the control that currently has the input
focus. You can achieve that by writing some code in the GotFocus event for all the controls on the
form, but when you have dozens of controls this will require a lot of code (and time). Instead, at
design time load a short description for each control in its Tag property, and then place a Timer
control on the form with an Interval setting of 500. This isn't a time-critical task, so you can use an
even larger value. Finally add two lines of code to the control's Timer event:
In the long run, however, the Embedding term in OLE has lost much of its appeal and importance, and
nowadays programmers are more concerned and thrilled about Automation, a subset of OLE that lets
them control other Windows applications from the outside, manipulating their object hierarchies
through OLE. For this reason, I won't describe the OLE control: It's a rather complex object, and a
thorough description of its many properties, methods, and events (and quirks) would take too much
space.
Using ListBox and ComboBox Controls In Visual
Basic 6
ListBox and ComboBox controls present a set of choices that are displayed vertically in a column. If
the number of items exceed the value that be displayed, scroll bars will automatically appear on the
control. These scroll bars can be scrolled up and down or left to right through the list.
The following Fig lists some of the common ComboBox properties and methods.
Property/Method Description
Properties
By setting this property to True or False user can decide whether user
Enabled
can interact with this control or not
Locked Boolean. Specifies whether user can type or not in the ComboBox
Integer. Specifies the shape of the mouse pointer when over the area
MousePointer
of the ComboBox
Sorted Boolean. Specifies whether the ComboBox's items are sorted or not.
ToolTipIndex String. Specifies what text is displayed as the ComboBox's tool tip
Methods
AddItem Add an item to the ComboBox
Event Procedures
Change Called when text in ComboBox is changed
Design Time : To add items to a list at design time, click on List property in the property box and then
add the items. Press CTRL+ENTER after adding each item as shown below.
Run Time : The AddItem method is used to add items to a list at run time. The AddItem method uses
the following syntax.
Object.AddItemitem, Index
The item argument is a string that represents the text to add to the list
The index argument is an integer that indicates where in the list to add the new item. Not giving the
index is not a problem, because by default the index is assigned.
Following is an example to add item to a combo box. The code is typed in the Form_Load event
Private Sub Form_Load()
Combo1.AddItem 1
Combo1.AddItem 2
Combo1.AddItem 3
Combo1.AddItem 4
Combo1.AddItem 5
Combo1.AddItem 6
End Sub
Object.RemoveItem index
The following code verifies that an item is selected in the list and then removes the selected item from
the list.
Simple combo
Dropdown combo Dropdown list
The Simple Combo box displays an edit area with an attached list box always visible immediately
below the edit area. A simple combo box displays the contents of its list all the time. The user can
select an item from the list or type an item in the edit box portion of the combo box. A scroll bar is
displayed beside the list if there are too many items to be displayed in the list box area.
The Dropdown Combo box first appears as only an edit area with a down arrow button at the right.
The list portion stays hidden until the user clicks the down-arrow button to drop down the list portion.
The user can either select a value from the list or type a value in the edit area.
The Dropdown list combo box turns the combo box into a Dropdown list box. At run time , the control
looks like the Dropdown combo box. The user could click the down arrow to view the list. The
difference between Dropdown combo & Dropdown list combo is that the edit area in the Dropdown list
combo is disabled. The user can only select an item and cannot type anything in the edit area.
Anyway this area displays the selected item.
Example
This example is to Add , Remove, Clear the list of items and finally close the application.
• Open a new Standard EXE project is opened an named the Form as Listbox.frm and save the
project as Listbox.vbp
• Design the application as shown below.
Caption ListBox
Form
Name frmListBox
Text (empty)
TextBox
Name txtName
Caption Enter a name
Label
Name lblName
ListBox Name lstName
End Sub
The click event of the Add button adds the text to the list box that was typed in the Text box. Then the
text box is cleared and the focus is got to the text box. The number of entered values will is increased
according to the number of items added to the listbox.
End If
End Sub
Remove button removes the selected item from the list as soon as you pressed the Remove button.
The number of items is decreased in the listbox and the value is displayed in the label.
The code for the clear button clears the listbox when you press it. And the number of items shown in
the label becomes 0
The ScrollBar is a commonly used control, which enables the user to select a value by positioning it at
the desired location. It represents a set of values. The Min and Max property represents the minimum
and maximum value. The value property of the ScrollBar represents its current value, that may be any
integer between minimum and maximum values assigned.
The HScrollBar and the VScrollBar controls are perfectly identical, apart from their different
orientation. After you place an instance of such a control on a form, you have to worry about only a
few properties: Min and Max represent the valid range of values, SmallChange is the variation in
value you get when clicking on the scroll bar's arrows, and LargeChange is the variation you get when
you click on either side of the scroll bar indicator. The default initial value for those two properties is 1,
but you'll probably have to change LargeChange to a higher value. For example, if you have a scroll
bar that lets you browse a portion of text, SmallChange should be 1 (you scroll one line at a time) and
LargeChange should be set to match the number of visible text lines in the window.
The most important run-time property is Value, which always returns the relative position of the
indicator on the scroll bar. By default, the Min value corresponds to the leftmost or upper end of the
control:
' Move the indicator near the top (or left) arrow.
VScroll1.Value = VScroll1.Min
' Move the indicator near the bottom (or right) arrow.
VScroll1.Value = VScroll1.Max
While this setting is almost always OK for horizontal scroll bars, you might sometimes need to reverse
the behavior of vertical scroll bars so that the zero is near the bottom of your form. This arrangement
is often desirable if you want to use a vertical scroll bar as a sort of slider. You obtain this behavior by
simply inverting the values in the Min and Max properties. (In other words, it's perfectly legal for Min to
be greater than Max.)
There are two key events for scrollbar controls: the Change event fires when you click on the scroll
bar arrows or when you drag the indicator; the Scroll event fires while you drag the indicator. The
reason for these two distinct possibilities is mostly historical. First versions of Visual Basic supported
only the Change event, and when developers realized that it wasn't possible to have continuous
feedback when users dragged the indicator, Microsoft engineers added a new event instead of
extending the Change event. In this way, old applications could be recompiled without unexpected
changes in their behavior. At any rate, this means that you must often trap two distinct events:
The example shown in the following figure uses three VScrollBar controls as sliders to control the
individual RGB (red, green, blue) components of a color. The three scroll bars have their Min property
set to 255 and their Max property set to 0, while their SmallChange is 1 and LargeChange is 16. This
example is also a moderately useful program in itself because you can select a color and then copy its
numeric value to the clipboard and paste it in your application's code as a decimal value, a
hexadecimal value, or an RGB function.
Scrollbar controls can receive the input focus, and in fact they support both the TabIndex and
TabStop properties. If you don't want the user to accidentally move the input focus on a scrollbar
control when he or she presses the Tab key, you must explicitly set its TabStop property to False.
When a scrollbar control has the focus, you can move the indicator using the Left, Right, Up, Down,
PgUp, PgDn, Home, and End keys. For example, you can take advantage of this behavior to create a
read-only TextBox control with a numeric value that can be edited only through a tiny companion
scroll bar. This scroll bar appears to the user as a sort of spin button, as you can see in the figure
below. To make the trick work, you need to write just a few lines of code:
Private Sub Text1_GotFocus()
' Pass the focus to the scroll bar.
VScroll1.SetFocus
End Sub
Private Sub VScroll1_Change()
' Scroll bar controls the text box value.
Text1.Text = VScroll1.Value
End Sub
You don't need external ActiveX controls to create functional spin buttons
Scrollbar controls are even more useful for building scrolling forms, like the one displayed in Figure 3-
15. To be certain, scrolling forms aren't the most ergonomic type of user interface you can offer to
your customers: If you have that many fields in a form, you should consider using a Tab control, child
forms, or some other custom interface. Sometimes, however, you badly need scrollable forms, and in
this situation you are on your own because Visual Basic forms don't support scrolling.
Fortunately, it doesn't take long to convert a regular form into a scrollable one. You need a couple of
scrollbar controls, plus a PictureBox control that you use as the container for all the controls on the
form, and a filler control—a CommandButton, for example—that you place in the bottom-right corner
of the form when it displays the two scroll bars. The secret to creating scrollable forms is that you
don't move all the child controls one by one. Instead, you place all the controls in the PictureBox
control (named picCanvas in the following code), and you move it when the user acts on the scroll
bar:
Sub MoveCanvas()
picCanvas.Move -HScroll1.Value, -VScroll1.Value
End Sub
In other words, to uncover the portion of the form near the right border, you assign a negative value to
the PictureBox's Left property, and to display the portion near the form's bottom border you set its Top
property to a negative value. It's really that simple. You do this by calling the MoveCanvas procedure
from within the scroll bars' Change and Scroll events. Of course, it's critical that you write code in the
Form_Resize event, which makes a scroll bar appear and disappear as the form is resized, and that
you assign consistent values to Max properties of the scrollbar controls:
Working with scrollable forms at design time isn't comfortable. I suggest that you work with a
maximized form and with the PictureBox control sized as large as possible. When you're finished with
the form interface, resize the PictureBox control to the smallest area that contains all the controls, and
then reset the form's WindowState property to 0-Normal.
A control array can be created only at design time, and at the very minimum at least one control must
belong to it. You create a control array following one of these three methods:
• You create a control and then assign a numeric, non-negative value to its Index property; you
have thus created a control array with just one element.
• You create two controls of the same class and assign them an identical Name property.
Visual Basic shows a dialog box warning you that there's already a control with that name and
asks whether you want to create a control array. Click on the Yes button.
• You select a control on the form, press Ctrl+C to copy it to the clipboard, and then press
Ctrl+V to paste a new instance of the control, which has the same Name property as the
original one. Visual Basic shows the warning mentioned in the previous bullet.
Control arrays are one of the most interesting features of the Visual Basic environment, and they add
a lot of flexibility to your programs:
• Controls that belong to the same control array share the same set of event procedures; this
often dramatically reduces the amount of code you have to write to respond to a user's
actions.
• You can dynamically add new elements to a control array at run time; in other words, you can
effectively create new controls that didn't exist at design time.
• Elements of control arrays consume fewer resources than regular controls and tend to
produce smaller executables. Besides, Visual Basic forms can host up to 256 different control
names, but a control array counts as one against this number. In other words, control arrays
let you effectively overcome this limit.
The importance of using control arrays as a means of dynamically creating new controls at run time is
somewhat reduced in Visual Basic 6, which has introduced a new and more powerful capability.
Don't let the term array lead you to think control array is related to VBA arrays; they're completely
different objects. Control arrays can only be one-dimensional. They don't need to be dimensioned:
Each control you add automatically extends the array. The Index property identifies the position of
each control in the control array it belongs to, but it's possible for a control array to have holes in the
index sequence. The lowest possible value for the Index property is 0. You reference a control
belonging to a control array as you would reference a standard array item:
Text1(0).Text = ""
The fact that multiple controls can share the same set of event procedures is often in itself a good
reason to create a control array. For example, say that you want to change the background color of
each of your TextBox controls to yellow when it receives the input focus and restore its background
color to white when the user clicks on another field:
Private Sub Text1_GotFocus(Index As Integer)
Text1(Index).BackColor = vbYellow
End Sub
Private Sub Text1_LostFocus(Index As Integer)
Text1(Index).BackColor = vbWhite
End Sub
Control arrays are especially useful with groups of OptionButton controls because you can remember
which element in the group has been activated by adding one line of code to their shared Click event.
This saves code when the program needs to determine which button is the active one:
Where object is the name of the control to add or delete from the control array. Index % is the value of
the index in the array. The control array to be added must be an element of the existing array created
at design time with an index value of 0. When a new element of a control array is loaded, most of the
property settings are copied from the lowest existing element in the array.
* Open a Standard EXE project and save the Form as Calculator.frm and save the Project as
Calculater.vbp.
Caption Calculator
Form
Name frmCalculator
Caption 1
Index 0
Caption 2
Index 1
CommandButton Caption 3
Name
cmd
Index
2
Caption 4
Index 3
Caption 5
Index 4
Caption 6
Index 5
Caption 7
Index 6
Caption 8
Index 7
Caption 9
Index 8
Caption 0
Index 10
Caption .
Index 11
Caption AC
CommandButton
Name cmdAC
CommandButton Caption +
Name cmdPlus
Caption -
CommandButton
Name cmdMinus
Caption *
CommandButton
Name cmdMultiply
Caption /
CommandButton
Name cmdDivide
Caption +/-
CommandButton
Name cmdNeg
Name txtDisplay
TextBox
Text ( empty )
Caption =
CommandButton
Name cmdEqual
The following code is entered in the cmd_Click( ) (Control Array) event procedure
The following code is entered in the click events of the cmdPlus, cmdMinus, cmdMultiply, cmdDevide
controls respectively.
To print the result on the text box, the following code is entered in the cmdEqual_Click ( ) event
procedure.
Case "+"
Result = Previous + Current
txtDisplay.Text = Result
Case "-"
Result = Previous - Current
txtDisplay.Text = Result
Case "*"
Result = Previous * Current
txtDisplay.Text = Result
Case "/"
Result = Previous / Current
txtDisplay.Text = Result
End Select
Current = Result
End Sub
Save and run the project. On clicking digits of user's choice and an operator button, the output
appears.
Here you're using the LBound and UBound methods exposed by the control array object, which is an
intermediate object used by Visual Basic to gather all the controls in the array. In general, you
shouldn't use this approach to iterate over all the items in the array because if the array has holes in
the Index sequence an error will be raised. A better way to loop over all the items of a control array is
using the For Each statement:
A third method exposed by the control array object, Count, returns the number of elements it contains.
It can be useful on several occasions (for example, when removing all the controls that were added
dynamically at run time):
' This code assumes that txtField(0) is the only control that was
' created at design time (you can't unload it at run time).
Do While txtFields.Count > 1
Unload txtFields(txtFields.UBound)
Loop
There are some limitations, though: All the items in an array of menu controls must be adjacent and
must belong to the same menu level, and their Index properties must be in ascending order (even
though holes in the sequence are allowed). This set of requirements severely hinders your ability to
create new menu items at run time. In fact, you can create new menu items in well-defined positions
of your menu hierarchy—namely, where you put a menu item with a nonzero Index value—but you
can't create new submenus or new top-level menus.
Now that you have a thorough understanding of how
Visual Basic's forms and controls work, you're ready
to dive into the subtleties of the Visual Basic for
Applications (VBA) language
In a nutshell, the DriveListBox control is a combobox-like control that's automatically filled with your
drive's letters and volume labels. The DirListBox is a special list box that displays a directory tree. The
FileListBox control is a special-purpose ListBox control that displays all the files in a given directory,
optionally filtering them based on their names, extensions, and attributes.
These controls often work together on the same form; when the user selects a drive in a DriveListBox,
the DirListBox control is updated to show the directory tree on that drive. When the user selects a
path in the DirListBox control, the FileListBox control is filled with the list of files in that directory.
These actions don't happen automatically, however—you must write code to get the job done.
After you place a DriveListBox and a DirListBox control on a form's surface, you usually don't have to
set any of their properties; in fact, these controls don't expose any special property, not in the
Properties window at least. The FileListBox control, on the other hand, exposes one property that you
can set at design time—the Pattern property. This property indicates which files are to be shown in
the list area: Its default value is *.* (all files), but you can enter whatever specification you need, and
you can also enter multiple specifications using the semicolon as a separator. You can also set this
property at run time, as in the following line of code:
File1.Pattern = "*.txt;*.doc;*.rtf"
Following figure shows three files controls are used in the design of Forms that let users explore the
entire structure of their hard disks.
• DriveListBox : Displays the names of the drives within and connected to the PC. The basic
property of this control is the drive property, which set the drive to be initially selected in the
control or returns the user's selection.
• DirListBox : Displays the folders of current Drive. The basic property of this control is the
Path property, which is the name of the folder whose sub folders are displayed in the control.
• FileListBox : Displays the files of the current folder. The basic property of this control is also
called Path, and it's the path name of the folder whose files are displayed.
The three File controls are not tied to one another. If you place all three of them on a Form, you will
see the names of all the folders under the current folder, and so on. Each time you select a folder in
the DirlistBox by double clicking its name, its sub folders are displayed. Similarly , the FileListBox
control will display the names of all files in the current folder. Selecting a drive in the DriveListBox
control, however this doesn't affect the contents of the DirListBox.
To connect to the File controls, you must assign the appropriate values to the properties. To compel
the DirListBox to display the folders of the selected drive in the DriveListBox, you must make sure that
each time the user selects another drive, the Path property of the DirListBox control matches the
Drive property of the DriveListBox.
After these preliminary steps, you're ready to set in motion the chain of events. When the user selects
a new drive in the DriveListBox control, it fires a Change event and returns the drive letter (and
volume label) in its Drive property. You trap this event and set the DirListBox control's Path property
to point to the root directory of the selected drive:
When the user double-clicks on a directory name, the DirListBox control raises a Change event; you
trap this event to set the FileListBox's Path property accordingly:
Finally, when the user clicks on a file in the FileListBox control, a Click event is fired (as if it were a
regular ListBox control), and you can query its Filename property to learn which file has been
selected. Note how you build the complete path:
Filename = File1.Path
If Right$(Filename, 1) <> "\" Then Filename = Filename & "\"
Filename = Filename & File1.Filename
The DirListBox and FileListBox controls support most of the properties typical of the control they
derive from—the ListBox control—including the ListCount and the ListIndex properties and the Scroll
event. The FileListBox control supports multiple selection; hence you can set its MultiSelect property
in the Properties window and query the SelCount and Selected properties at run time.
The FileListBox control also exposes a few custom Boolean properties, Normal, Archive, Hidden,
ReadOnly, and System, which permit you to decide whether files with these attributes should be
listed. (By default, the control doesn't display hidden and system files.) This control also supports a
couple of custom events, PathChange and PatternChange, that fire when the corresponding property
is changed through code. In most cases, you don't have to worry about them, and I won't provide
examples of their usage.
The problem with the DriveListBox, DirListBox and FileListBox controls is that they're somewhat
outdated and aren't used by most commercial applications any longer. Moreover, these controls are
known to work incorrectly when listing files on network servers and sometimes even on local disk
drives, especially when long file and directory names are used. For this reason, I discourage you from
using them and suggest instead that you use the Common Dialog controls for your FileOpen and
FileSave dialog boxes. But if you need to ask the user for the name of a directory rather than a file,
you're out of luck because—while Windows does include such a system dialog box, named
BrowseForFolders dialog—Visual Basic still doesn't offer a way to display it (unless you do some
advanced API programming). Fortunately, Visual Basic 6 comes with a new control—the
ImageCombo control—that lets you simulate the appearance of the DriveListBox control. It also offers
you a powerful library—the FileSystemObject library—that completely frees you from using these
three controls, if only as hidden controls that you use just for quickly retrieving information on the file
system.
When you place a CheckBox control on a form, all you have to do, usually, is set its Caption property
to a descriptive string. You might sometimes want to move the little check box to the right of its
caption, which you do by setting the Alignment property to 1-Right Justify, but in most cases the
default setting is OK. If you want to display the control in a checked state, you set its Value property to
1-Checked right in the Properties window, and you set a grayed state with 2-Grayed.
The only important event for CheckBox controls is the Click event, which fires when either the user or
the code changes the state of the control. In many cases, you don't need to write code to handle this
event. Instead, you just query the control's Value property when your code needs to process user
choices. You usually write code in a CheckBox control's Click event when it affects the state of other
controls. For example, if the user clears a check box, you might need to disable one or more controls
on the form and reenable them when the user clicks on the check box again. This is how you usually
do it (here I grouped all the relevant controls in one frame named Frame1):
Note that Value is the default property for CheckBox controls, so you can omit it in code. I suggest
that you not do that, however, because it would reduce the readability of your code.
* Open a new Project and save the Form as CheckBox.frm and save the Project as
CheckBox.vbp
Caption CheckBox
Form
Name frmCheckBox
CheckBox Caption Bold
Name chkBold
Caption Italic
CheckBox
Name chkItalic
Caption Underline
CheckBox
Name chkUnderline
Caption Red
OptionButton
Name optRed
Caption Blue
OptionButton
Name optBlue
Caption Green
OptionButton
Name optGreen
Name txtDisplay
TextBox
Text (empty)
Caption Exit
CommandButton
Name cmdExit
To terminate the program following code is typed in the Click() event of the Exit button
Run the program by pressing F5. Check the program by clicking on OptionButtons and CheckBoxes
The main characteristic of a Form is the title bar on which the Form's caption is displayed. On the left
end of the title bar is the Control Menu icon. Clicking this icon opens the Control Menu. Maximize,
Minimize and Close buttons can be found on the right side of the Form. Clicking on these buttons
performs the associated function.
The following figure illustrates the appearance of a Form
• Restore : Restores a maximized Form to the size it was before it was maximized; available
only if the Form has been maximized.
• Move : Lets the user moves the Form around with the mouse
• Size : Lets the user resizes the control with the mouse
• Minimize: Minimizes the Form
• Maximize : Maximizes the Form
• Close : Closes the Form
By default, Visual Basic suggests the name of the first Form created when the project started.
Load FormName
Unload FormName
The FormName variable is the name of the Form to be loaded or unloaded. Unlike the Show method
which cares of both loading and displaying the Form, the load statement doesn't show the Form. You
have to call the Form's Show method to display it on the desktop.
FormName.Show mode
The FormName variable is the Form's name, and the optional argument mode determines whether
the Form will be Modal or not. It can have one of the following syntax :
* 0-Modeless (default)
* 1-Modal
Modeless Forms are the normal Forms. Modeless Forms interact with the user and the user allowed
to switch to any other Form of the application. If you do not specify the optional mode argument, by
default the mode is set to modeless.
The Modal Forms takes the total control of the application where user cannot switch to any other
Forms in the application unless the Form is closed. A modal Form, thus, must have a Close button or
some means to close the Form in order to return to the Form where the Modal Form was loaded.
Hiding Forms
The Hide method is used to hide a Form. The following is the syntax of the Hide Method.
FormName.Hide
To hide a Form from within its own code, the following code can be used.
Me.Hide
You must understand that the Forms that are hidden are not unloaded ; they remains in the memory
and can be displayed instantly with the Show Method. When a Form is hidden, you can still access its
properties and code. For instance, you can change the settings of its Control Properties or call any
Public functions in the Form.
The following is an example illustrates the Show method and Mode statement
The following code is typed in the Click event of the command buttons
Run the application. Clicking on the buttons will display the Forms respectively. But you can see that
in the cmd2_Click( ) event additionally VbModal argument has been added. You can see the
difference after you display the forms by clicking on the command buttons. You can notice that you
cannot switch to any other Forms in the application unless you close the Form3. (Download the
source code)
Me.Hide
Unload Me
Save the project and run the application. Once you click on Hide button you can note that the Form is
invisible but the application is still running. But when you click on Unload button you can see that the
application is terminated.
Visual Basic provides an easy way to create menus with the modal Menu Editor dialog. The below
dialog is displayed when the Menu Editor is selected in the Tool Menu. The Menu Editor command is
grayed unless the form is visible. And also you can display the Menu Editor window by right clicking
on the Form and selecting Menu Editor.
Basically, each menu item has a Caption property (possibly with an embedded & character to create
an access key) and a Name. Each item also exposes three Boolean properties, Enabled, Visible, and
Checked, which you can set both at design time and at run time. At design time, you can assign the
menu item a shortcut key so that your end users don't have to go through the menu system each time
they want to execute a frequent command. (Do you really like pulling down the Edit menu any time
you need to clear some text or copy it to the Clipboard?) The assigned shortcut key can't be queried
at run time, much less modified.
Building a menu is a simple, albeit more tedious, job: You enter the item's Caption and Name, set
other properties (or accept the default values for those properties), and press Enter to move to the
next item. When you want to create a submenu, you press the Right Arrow button (or the Alt+R hot
key). When you want to return to work on top-level menus—those items that appear in the menu bar
when the application runs—you click the Left Arrow button (or press Alt+L). You can move items up
and down in the hierarchy by clicking the corresponding buttons or the hot keys Alt+U and Alt+B,
respectively.
You can create up to five levels of submenus (six including the menu bar), which are too many even
for the most patient user. If you find yourself working with more than three menu levels, think about
trashing your specifications and redesigning your application from the ground up.
You can insert a separator bar using the hypen (-) character for the Caption property. But even these
separator items must be assigned a unique value for the Name property, which is a real nuisance. If
you forget to enter a menu item's Name, the Menu Editor complains when you decide to close it. The
convention used in this book is that all menu names begin with the three letters mnu.
An expanded menu
One of the most annoying defects of the Menu Editor tool is that it doesn't permit you to reuse the
menus you have already written in other applications. It would be great if you could open another
instance of the Visual Basic IDE, copy one or more menu items to the clipboard, and then paste those
menu items in the application under development. You can do that with controls and with pieces of
code, but not with menus! The best thing you can do in Visual Basic is load the FRM file using an
editor such as Notepad, find the portion in the file that corresponds to the menu you're interested in,
load the FRM file you're developing (still in Notepad), and paste the code there. This isn't the easiest
operation, and it's also moderately dangerous: If you paste the menu definition in the wrong place,
you could make your FRM form completely unreadable. Therefore, always remember to make backup
copies of your forms before trying this operation.
Better news is that you can add a finished menu to a form in your application with just a few mouse
clicks. All you have to do is activate the Add-In Manager from the Add-Ins menu, choose the VB 6
Template Manager, and tick the Loaded/Unloaded check box. After you do that, you'll find three new
commands in the Tools menu: Add Code Snippet, Add Menu, and Add Control Set. Visual Basic 6
comes with a few menu templates, as you can see in the following figure, that you might find useful as
a starting point for building your own templates. To create your menu templates, you only have to
create a form with the complete menu and all the related code and then store this form in the
\Templates\Menus directory. (The complete path, typically c:\Program Files\Microsoft Visual
Studio\VB98\Template, can be found in the Environment tab of the Options dialog box on the Tools
menu. The Template Manager was already available with Visual Basic 5, but it had to be installed
manually and relatively few programmers were aware of its existence.
The programmer can create menu control arrays. The Index TextBox specifies the menu's index in
the control array.
The Menu Editor dialog also provides several CheckBoxes to control the appearance of the Menu.
Checked : This is unchecked by default and allows the programmer the option of creating a checked
menu item( a menu item that act as a toggle and displays a check mark when selected. The following
is a Check Menu items.
Enabled : specifies whether a menu is disabled or not. If you see a disabled command in a menu that
means that feature is not available. The Visible checkbox specifies whether the menu is visible or not.
To add commands to the Form's menu bar, enter a caption and a name for each command. As soon
as you start typing the command's caption, it also appears in a new line in the list at the bottom of the
Menu Editor window. To add more commands click Enter and type the Caption and the Name.
Creating Menus
Open a new Project and save the form as menu.frm and save the project as menu.vbp.
Choose Tools ››› Menu Editor and type the menu items as shown below.
Caption Name
File mnuFile
Open mnuOpen
Save mnuSave
Exit mnuExit
Edit mnuEdit
Copy mnuCopy
Cut mnuCut
Paste mnuPaste
Run the application by pressing F5. You can see that you can select a menu. (Download the source
code)
Menu controls expose only one event, Click. As you expect, this event fires when the user clicks on
the menu:
You can manipulate menu items at run time through their Checked, Visible, and Enabled properties.
For example, you can easily implement a menu item that acts as a switch and displays or hides a
status bar:
While menu items can be responsible for their own Checked status, you usually set their Visible and
Enabled properties in another region of the code. You make a menu item invisible or disabled when
you want to make the corresponding command unavailable to the user. You can choose from two
different strategies to achieve this goal: You can set the menu properties as soon as something
happens that affects that menu command, or you can set them one instant before the menu is
dropped down. Let me explain these strategies with two examples.
Let's say that the Save command from the File menu should look disabled if your application has
loaded a read-only file. In this case, the most obvious place in code to set the menu Enabled property
to False is in the procedure that loads the file, as shown in the code below.
This solution makes sense because the menu state doesn't change often. By comparison, the state of
most of the commands in a typical Edit menu (Copy, Cut, Clear, Undo, and so on) depends on
whether any text is currently selected in the active control. In this case, changing the menu state any
time a condition changes (because the user selects or deselects text in the active control, for
example) is a waste of time, and it also requires a lot of code. Therefore, it's preferable to set the state
of those menu commands in the parent menu's Click event just before displaying the menu:
Visual Basic also supports pop-up menus, those context-sensitive menus that most commercial
applications show when you right-click on an user interface object. In Visual Basic, you can display a
pop-up menu by calling the form's PopupMenu method, typically from within the MouseDown event
procedure of the object:
The argument you pass to the PopupMenu method is the name of a menu that you have defined
using the Menu Editor. This might be either a submenu that you can reach using the regular menu
structure or a submenu that's intended to work only as a pop-up menu. In the latter case, you should
create it as a top-level menu in the Menu Editor and then set its Visible attribute to False. If your
program includes many pop-up menus, you might find it convenient to add one invisible top-level entry
and then add all the pop-up menus below it. (In this case, you don't need to make each individual item
invisible.) The complete syntax of the PopupMenu method is quite complex:
The x and y arguments, if specified, make the menu appear in a particular position on the form, rather
than at mouse coordinates. The last optional argument is the name of the menu that's the default item
for the pop-up menu. This item will be displayed in boldface. This argument has only a visual effect; If
you want to offer a default menu item, you must write code in the MouseDown event procedure to trap
double-clicks with the right button.
You can take advantage of the x and y arguments in a PopupMenu method to make your program
more Windows compliant, and show your pop-up menus over the control that has the focus when the
user presses the Application key (the key beside the Windows key on the right side of a typical
extended keyboard, such as the Microsoft Natural Keyboard). But remember that Visual Basic doesn't
define any key-code constant for this key. Here's how you must proceed:
Visual Basic's implementation of pop-up menus has a serious flaw. All Visual Basic TextBox controls
react to right-clicks by showing the standard Edit pop-up menu (with the usual commands, such as
Undo, Copy, Cut, and so on). The problem is that if you invoke a PopupMenu method from within the
TextBox control's MouseDown event, your custom pop-up menu will be displayed only after the
standard one, which is obviously undesirable. You can solve it only by resorting to the unorthodox and
undocumented technique shown below.
The Multiple Document Interface (MDI) was designed to simplify the exchange of information among
documents, all under the same roof. With the main application, you can maintain multiple open
windows, but not multiple copies of the application. Data exchange is easier when you can view and
compare many documents simultaneously.
You almost certainly use Windows applications that can open multiple documents at the same time
and allow the user to switch among them with a mouse-click. Multiple Word is a typical example,
although most people use it in single document mode. Each document is displayed in its own window,
and all document windows have the same behavior. The main Form, or MDI Form, isn't duplicated,
but it acts as a container for all the windows, and it is called the parent window. The windows in which
the individual documents are displayed are called Child windows.
An MDI application must have at least two Form, the parent Form and one or more child Forms. Each
of these Forms has certain properties. There can be many child forms contained within the parent
Form, but there can be only one parent Form.
The parent Form may not contain any controls. While the parent Form is open in design mode, the
icons on the ToolBox are not displayed, but you can't place any controls on the Form. The parent
Form can, and usually has its own menu.
1. Start a new project and then choose Project >>> Add MDI Form to add the parent Form.
2. Set the Form's caption to MDI Window
3. Choose Project >>> Add Form to add a SDI Form.
4. Make this Form as child of MDI Form by setting the MDI Child property of the SDI Form to
True. Set the caption property to MDI Child window.
Visual Basic automatically associates this new Form with the parent Form. This child Form can't exist
outside the parent Form; in the words, it can only be opened within the parent Form.
Parent and Child Menus
MDI Form cannot contain objects other than child Forms, but MDI Forms can have their own menus.
However, because most of the operations of the application have meaning only if there is at least one
child Form open, there's a peculiarity about the MDI Forms. The MDI Form usually has a menu with
two commands to load a new child Form and to quit the application. The child Form can have any
number of commands in its menu, according to the application. When the child Form is loaded, the
child Form's menu replaces the original menu on the MDI Form
* Open a new Project and name the Form as Menu.frm and save the Project as Menu.vbp
At design time double click on MDI Open and add the following code in the click event of the open
menu.
Form1.Show
And so double click on MDI Exit and add the following code in the click event
End
Double click on Child Close and enter the following code in the click event
Unload Me
Before run the application in the project properties set MDI Form as the start-up Form. Save and run
the application. Following output will be displayed.
And as soon as you click MDI Open you can notice that the main menu of the MDI Form is replaced
with the Menu of the Child Form. The reason for this behavior should be obvious. The operation
available through the MDI Form are quite different from the operations of the child window. Moreover,
each child Form shouldn't have it's own menu.
Displays a prompt in a dialog box, waits for the user to input text or click a button, and returns a String
containing the contents of the text box.
Syntax :
• Prompt - String expression displayed as the message in the dialog box. If prompt consists of
more than one line, you can separate the lines using the vbCrLf constant
• Title - String expression displayed in the title bar of the dialog box. If you omit the title, the
application name is displayed in the title bar
• default-text - The default text that appears in the input field where users can use it as his
intended input or he may change to the message he wish to key in.
• x-position and y-position - the position or the coordinate of the input box.
* Open a new project and save the Form as InputBox.frm and save the Project as InputBox.vbp
Name frmInputBox
Label Caption You entered
Name lbl1
Caption ( empty)
Label
Name lbl2
Name cmdOK
Save and run the application. As soon as you click the OK button you will get the following InputBox
Here I have entered "Hello World" in text field. As soon as you click OK the output is shown as shown
below
Syntax :
Prompt : String expressions displayed as the message in the dialog box. If prompt consist of more
than one line, you can separate the lines using the vbrCrLf constant.
Icons + Buttons : Numeric expression that is the sum of values specifying the number and type of
buttons and icon to display.
Title : String expression displayed in the title bar of the dialog box. If you omit title, the application
name is placed in the title bar.
Icons
Buttons
Return Values
vbOk 1 Ok Button
vbNo 7 No Button
* Open a new Project and save the Form as messageboxdemo.frm and save the Project as
messageboxdemo.vbp
Name frmMessageBoxDemo
Label Caption lblName
Name Name
TextBox Name txtName
Text ( empty )
ListBox Name lstName
Name cmdAdd
CommandButton Caption Delete
Name cmdDelete
CommandButton Caption Exit
Name cmdExit
End If
End If
End If
End Sub
Save and run the application. You can notice the different type of message box types are used to
perform an action
Visual Basic responds to various mouse events, which are recognized by most of the controls. The
main events are MouseDown, MouseUp and MouseMove. MouseDown occurs when the user
presses any mouse button and MouseUp occurs when the user releases any mouse button. These
events use the arguments button, Shift, X, Y and they contain information about the mouse's condition
when the button is clicked.
The first argument is an integer called Button. The value of the argument indicates whether the left,
right or middle mouse button was clicked. The second argument in an integer called shift. The value
of this argumnet indicates whether the mouse button was clicked simultaneously with the Shift key,
Ctrl key or Alt key. The third and fourth arguments X and Y are the coordinates of the mouse location
at the time the mouse button was clicked. As the Form_MouseDown( ) is executed automatically
whenever the mouse button is clicked inside the Form's area the X, Y co-ordinates are referenced to
the form.
Positioning a control
MouseDown is the commonly used event and it is combined wiyth the move method to move an
Image control to different locations in a Form. The following application illustrates the movement of
objects responding to move events. it makes use of two OptionButton Controls, two image
controls and a CommandButton. The application is designed in such a way that when an
OptionButton is selected, the corresponding image control is placed anywhere in the form whenever it
is clicked.
Open a new standard EXE project and save the Form as Move.frm and save the project as
Move.vbp Design the Form as shown below.
Name frmMouseDown
Name optCredit
Value True
Name optCash
Image Name imgCredit
Picture c:/credit.jpg
Image Name imgCash
Picture c:/cash.jpg
The follwoing code is entered in the general declarations section of the Form.
Option Explicit
Run the application by keying in F5. You can notice that when the mouse is clicked on the form
somewhere, the selected image moves to that clicked location. This is shown in the below figure.
( Download the source code )
The mouse events can be combined with graphics methods and any number of customized drawing
or paint applications can be created. The following application combines MouseMove and
MouseDown events, and illustrates a drawing program.
Open a new Standard EXE project and save the Form as Draw.frm and save the Project as Draw.vbp.
Name the caption of the as Drawing. Add command button control and name the caption of it as Clear
Enter the following code in the Form_MouseDown ( ) procedure, Form_MouseMove ( ) procedure and
cmdClear_Click ( ) procedures respectively.
Button value 1 indicates that the left mouse button is clicked. The code written in the MouseDown
event changes the CurrentX and CurrentY to the coordinates where the mouse button was just
clicked.
Run the application. You can notice that when the mouse is clicked and moved in the Form a line is
drawn corresponding to the mouse movement. Following figure illustrates the combined action of
MouseDown and MouseMove.
The program uses two graphics related Visual Basic concepts, the Line method and the CurrentX and
CurrentY properties. Line method is preferred to draw a line in a Form. The following statement draws
a line from the coordinates X = 2500, Y = 2000, X = 5000, Y = 5500
The CurrentX and CurrentY properties are not visible in the properties window of the Form because it
cannot be set at the design time. After using the Line method to draw a line in a Form, Visual Basic
automatically assigns the coordinate of the line's end point to the CurrentX and CurrentY properties of
the Form on which the line is drawn.
MouseMove application
Visual Basic does not generate a MouseMove event for every pixel the mouse moves over and a
limited number of mouse messages are generated per second by the operating environment. The
following application illustrates how often the Form_MouseMove ( ) event is executed.
Open a new standard EXE project and save the form as MouseMove.frm and save the Project as
MouseMOve.vbp. Place a CommandButton control and name the caption as Clear and set the
name as cmdClear.
The above procedure simply draws small circles at the mouse's current location using the Circle
method. The parameter x, y represent the centre of the circle, and the second parameter represents
the radius of the circle.
Save the application and run. You can notice that when the mouse is moved inside the Form, circles
are drwan along the path of the mouse movement as shown in below figure. And also you can notice
the circles are widely spaced when the mouse is moved quickly. Each small circle is an indication that
the MouseMove event occured and the Form_MouseMove ( ) procedure was executed.
Error Handling enables programmers to write clearer, more robust, more fault-tolerant programs. Error
handling enables the programmer to attempt to recover (i.e., continue executing) from infrequent fatal
errors rather than letting them occur and suffering the consequences (such as loss of application
data). If an error is severe and recovery is not possible, the program can be exited "gracefully"-all files
can be closed and notification can be given that the program is terminating. The recovery code is
called an error handler.
Error handling is designed for dealing with synchronous errors such as an attempt to divide by 0 (that
occurs as the program executes the divide instruction). Other common examples of synchronous
errors are memory exhaustion, an out-of-bound array index, and arithmetic overflow. Error handling
provides the programmer with a disciplined set of capabilities for dealing with these types of errors.
Error-handling code varies in nature and amount among software systems depending on the
application and whether or not the software is a product for release. Products tend to contain much
more error-handling code than is contained in "casual" software.
Usually, error-handling code is interspersed throughout a program's code. Errors are dealt with the
places in the code where errors are likely to occur. The advantage of this approach is that a
programmer reading the code can see the error handling in the immediate vicinity of the code and
determine if the proper error handling has been implemented.
The problem with the scheme is that code in a sense becomes "polluted" with error handling. It
becomes difficult for a programmer concerned with the application itself to read the code and
determine if the code is working is correctly. Error handling often makes the code more difficult to
understand and maintain.
This lesson explains about error handling and debugging in easy steps with quick examples. For more
in-depth lessons in Error Handling click here
Contents
Error Types
Debugging Strategies
Sequential Files
User-Defined Variables
• No matter how hard we try, errors do creep into our programs. These errors can be grouped into
three categories:
1. Syntax errors
2. Run-time errors
3. Logic errors
• Syntax errors occur when you mistype a command or leave out an expected phrase or argument.
Visual Basic detects these errors as they occur and even provides help in correcting them. You
cannot run a Visual Basic program until all syntax errors have been corrected.
• Run-time errors are usually beyond your program's control. Examples include: when a variable takes
on an unexpected value (divide by zero), when a drive door is left open, or when a file is not found.
Visual Basic allows you to trap such errors and make attempts to correct them.
• Logic errors are the most difficult to find. With logic errors, the program will usually run, but will
produce incorrect or unexpected results. The Visual Basic debugger is an aid in detecting logic errors.
• Design your application carefully. More design time means less debugging time.
• Use comments where applicable to help you remember what you were trying to do.
• Use consistent and meaningful naming conventions for your variables, objects, and
procedures
Yes, this uses the dreaded GoTo statement! Any time a run-time error occurs following this line,
program control is transferred to the line labeled errlabel. Recall a labeled line is simply a line with the
label followed by a colon (:).
• The best way to explain how to use error trapping is to look at an outline of an example procedure
with error trapping.
Sub SubExample()
[Procedure code]
Exit Sub
HandleErrors:
End Sub
Once you have set up the variable declarations, constant definitions, and any other procedure
preliminaries, the On Error statement is executed to enable error trapping. Your normal procedure
code follows this statement. The error handling code goes at the end of the procedure, following the
HandleErrors statement label. This is the code that is executed if an error is encountered anywhere in
the Sub procedure. Note you must exit (with Exit Sub) from the code before reaching the
HandleErrors line to avoid inadvertent execution of the error handling code.
• Since the error handling code is in the same procedure where an error occurs, all variables in that
procedure are available for possible corrective action. If at some time in your procedure, you want to
turn off error trapping, that is done with the following statement:
On Error GoTo 0
• Once a run-time error occurs, we would like to know what the error is and attempt to fix it. This is
done in the error handling code.
• Visual Basic offers help in identifying run-time errors. The Err object returns, in its Number property
(Err.Number), the number associated with the current error condition. (The Err function has other
useful properties that we won’t cover here - consult on-line help for further information.) The Error()
function takes this error number as its argument and returns a string description of the error. Consult
on-line help for Visual Basic run-time error numbers and their descriptions.
• Once an error has been trapped and some action taken, control must be returned to your
application. That control is returned via the Resume statement. There are three options:
Resume Lets you retry the operation that caused the error. That is, control is returned to the line
where the error occurred. This could be dangerous in that, if the error has not been corrected (via
code or by the user), an infinite loop between the error handler and the procedure code may result.
Resume Next Program control is returned to the line immediately following the line where the error
occurred.
Resume label Program control is returned to the line labeled label.
• Be careful with the Resume statement. When executing the error handling portion of the code and
the end of the procedure is encountered before a Resume, an error occurs. Likewise, if a Resume is
encountered outside of the error handling portion of the code, an error occurs
Form1:
BorderStyle - 1-Fixed Single
Caption - Error Generator
Name frmError
Command1:
Caption - Generate Error
Default - True
Name - cmdGenError
Text1:
Name - txtError
Text - [Blank]
HandleErrors:
Select Case MsgBox(Error(Err.Number), vbCritical + vbAbortRetryIgnore,
"Error Number" + Str(Err.Number))
Case vbAbort
Resume ExitLine
Case vbRetry
Resume
Case vbIgnore
Resume Next
End Select
ExitLine:
Exit Sub
End Sub
In this code, we simply generate an error using the number input in the text box. The generic error
handler then displays a message box which you can respond to in one of three ways.
4. Save your application. Try it out using some of these typical error numbers (or use numbers found
with on-line help). Notice how program control changes depending on which button is clicked.
6 Overflow
9 Subscript out of range
11 Division by zero
13 Type mismatch
16 Expression too complex
20 Resume without error
52 Bad file name or number
53 File not found
55 File already open
61 Disk full
70 Permission denied
92 For loop not initialized
• We now consider the search for, and elimination of, logic errors. These are errors that don’t prevent
an application from running, but cause incorrect or unexpected results. Visual Basic provides an
excellent set of debugging tools to aid in this search.
• Debugging a code is an art, not a science. There are no prescribed processes that you can follow to
eliminate all logic errors in your program. The usual approach is to eliminate them as they are
discovered.
• What we’ll do here is present the debugging tools available in the Visual Basic environment (several
of which appear as buttons on the toolbar) and describe their use with an example. You, as the
program designer, should select the debugging approach and tools you feel most comfortable with.
• The interface between your application and the debugging tools is via three different debug
windows: the Immediate Window, the Locals Window, and the Watch Window. These windows can be
accessed from the View menu (the Immediate Window can be accessed by pressing Ctrl+G). Or, they
can be selected from the Debug Toolbar (accessed using the Toolbars option under the View menu):
• All debugging using the debug windows is done when your application is in break mode. You can
enter break mode by setting breakpoints, pressing Ctrl+Break, or the program will go into break mode
if it encounters an untrapped error or a Stop statement.
• Once in break mode, the debug windows and other tools can be used to:
Example - Debugging
1. Unlike other examples, we’ll do this one as a group. It will be used to demonstrate use of the
debugging tools.
2. The example simply has a form with a single command button. The button is used to execute some
code. We won’t be real careful about proper naming conventions and such in this example.
3. The code attached to this button’s Click event is a simple loop that evaluates a function at several
values.
This code begins with an X value of 0 and computes the Y value using the general integer function
Fcn. It then increments X by 1 and repeats the Loop. It continues looping While X is less than or equal
to 20. The function Fcn is computed using:
Admittedly, this code doesn’t do much, especially without any output, but it makes a good example for
looking at debugger use. Set up the application and get ready to try debugging.
Using the Debugging Tools
• There are several debugging tools available for use in Visual Basic. Access to these tools is
provided with both menu options and buttons on the Debug toolbar. These tools include breakpoints,
watch points, calls, step
• The simplest tool is the use of direct prints to the immediate window.
You can print directly to the immediate window while an application is running. Sometimes, this is all
the debugging you may need. A few carefully placed print statements can sometimes clear up all logic
errors, especially in small applications.
• Debug.Print Example:
1. Place the following statement in the Command1_Click procedure after the line calling the
general procedure Fcn:
Debug.Print X; Y
• Breakpoints:
In the above examples, the program ran to completion before we could look at the debug window. In
many applications, we want to stop the application while it is running, examine variables and then
continue running. This can be done with breakpoints.
A breakpoint is a line in the code where you want to stop (temporarily) the execution of the program,
that is force the program into break mode. To set a breakpoint, put the cursor in the line of code you
want to break on. Then, press <F9> or click the Breakpoint button on the toolbar or select Toggle
Breakpoint from the Debug menu. The line will be highlighted.
When you run your program, Visual Basic will stop when it reaches lines with breakpoints and allow
you to use the immediate window to check variables and expressions. To continue program operation
after a breakpoint, press <F5>, click the Run button on the toolbar, or choose Start from the Run
menu.
You can also change variable values using the immediate window. Simply type a valid Basic
expression. This can sometimes be dangerous, though, as it may change program operation
completely.
• Breakpoint Example:
1. Set a breakpoint on the X = X + 1 line in the sample program. Run the program.
2. When the program stops, display the immediate window and type the following line:
Print X;Y
3. The values of these two variables will appear in the debug window. You can use a question
mark (?) as shorthand for the command Print, if you’d like. Restart the application. Print the
new variable values.
4. Try other breakpoints if you have time. Once done, all breakpoints can be cleared by
Ctrl+Shift+<F9> or by choosing Clear All Breakpoints from the Debug menu. Individual
breakpoints can be toggled using <F9> or the Breakpoint button on the toolbar.
The locals window shows the value of any variables within the scope of the current procedure. As
execution switches from procedure to procedure, the contents of this window changes to reflect only
the variables applicable to the current procedure. Repeat the above example and notice the values of
X and Y also appear in the locals window.
• Watch Expressions:
The Add Watch option on the Debug menu allows you to establish watch expressions for your
application. Watch expressions can be variable values or logical expressions you want to view or test.
Values of watch expressions are displayed in the watch window.
In break mode, you can use the Quick Watch button on the toolbar to add watch expressions you
need. Simply put the cursor on the variable or expression you want to add to the watch list and click
the Quick Watch button.
Watch expressions can be edited using the Edit Watch option on the Debug menu.
• Watch Expression Example:
• Call Stack:
Selecting the Call Stack button from the toolbar (or pressing Ctrl+L or selecting Call Stack from the
View menu) will display all active procedures, that is those that have not been exited.
Call Stack helps you unravel situations with nested procedure calls to give you some idea of where
you are in the application.
1. Set a breakpoint on the Fcn = Cint() line in the general function procedure. Run the
application. It will break at this line.
2. Press the Call Stack button. It will indicate you are currently in the Fcn procedure which was
called from the Command1_Click procedure. Clear the breakpoint.
While at a breakpoint, you may execute your program one line at a time by pressing <F8>, choosing
the Step Into option in the Debug menu, or by clicking the Step Into button on the toolbar.
This process is single stepping. It allows you to watch how variables change (in the locals window) or
how your form changes, one step at a time.
You may step through several lines at a time by using Run To Cursor option. With this option, click on
a line below your current point of execution. Then press Ctrl+<F8> (or choose Run To Cursor in the
Debug menu). the program will run through every line up to the cursor location, then stop.
To move through a procedure in this manner, press Shift+<F8>, choose Step Over from the Debug
menu, or press the Step Over button on the toolbar.
While stepping through your program, if you wish to complete the execution of a function you are in,
without stepping through it line-by-line, choose the Step Out option. The function will be completed
and you will be returned to the procedure accessing that function.
To perform this step out, press Ctrl+Shift+<F8>, choose Step Out from the Debug menu, or press the
Step Out button on the toolbar. Try this on the previous example.
Debugging Strategies
• We’ve looked at each debugging tool briefly. Be aware this is a cursory introduction. Use the on-line
help to delve into the details of each tool described. Only through lots of use and practice can you
become a proficient debugger. There are some guidelines to doing a good job, though.
• My first suggestion is: keep it simple. Many times, you only have one or two bad lines of code. And
you, knowing your code best, can usually quickly narrow down the areas with bad lines. Don’t set up
some elaborate debugging procedure if you haven’t tried a simple approach to find your error(s) first.
Many times, just a few intelligently-placed Debug.Print statements or a few examinations of the
immediate and locals windows can solve your problem.
• A tried and true approach to debugging can be called Divide and Conquer. If you’re not sure where
your error is, guess somewhere in the middle of your application code. Set a breakpoint there. If the
error hasn’t shown up by then, you know it’s in the second half of your code. If it has shown up, it’s in
the first half. Repeat this division process until you’ve narrowed your search.
• And, of course, the best debugging strategy is to be careful when you first design and write your
application to minimize searching for errors later
Sequential Files
• In many applications, it is helpful to have the capability to read and write information to a disk file.
This information could be some computed data or perhaps information loaded into a Visual Basic
object.
• Visual Basic supports two primary file formats: sequential and random access. We first look at
sequential files.
• A sequential file is a line-by-line list of data. You can view a sequential file with any text editor. When
using sequential files, you must know the order in which information was written to the file to allow
proper reading of the file.
• Sequential files can handle both text data and variable values. Sequential access is best when
dealing with files that have lines with mixed information of different lengths. I use them to transfer data
between applications
where SeqFileName is the name of the file to open and N is an integer file number. The filename must
be a complete path to the file.
Close N
Once a file is closed, it is saved on the disk under the path and filename used to open the file.
• Information is written to a sequential file one line at a time. Each line of output requires a separate
Basic statement.
• There are two ways to write variables to a sequential file. The first uses the Write statement:
where the variable list has variable names delimited by commas. (If the variable list is omitted, a blank
line is printed to the file.) This statement will write one line of information to the file, that line containing
the variables specified in the variable list. The variables will be delimited by commas and any string
variables will be enclosed in quotes. This is a good format for exporting files to other applications like
Excel.
Example
Dim A As Integer, B As String, C As Single, D As Integer
.
.
Open TestOut For Output As #1
Write #1, A, B, C
Write #1, D
Close 1
After this code runs, the file TestOut will have two lines. The first will have the variables A, B, and C,
delimited by commas, with B (a string variable) in quotes. The second line will simply have the value
of the variable D.
• The second way to write variables to a sequential file is with the Print statement:
This statement will write one line of information to the file, that line containing the variables specified
in the variable list. (If the variable list is omitted, a blank line will be printed.) If the variables in the list
are separated with semicolons (;), they are printed with a single space between them in the file. If
separated by commas (,), they are spaced in wide columns. Be careful using the Print statement with
string variables. The Print statement does not enclose string variables in quotes, hence, when you
read such a variable back in, Visual Basic may have trouble knowing where a string ends and begins.
It’s good practice to ‘tack on’ quotes to string variables when using Print.
Example
After this code runs, the file TestOut will have two lines. The first will have the variables A, B, and C,
delimited by spaces. B will be enclosed by quotes [Chr(34)]. The second line will simply have the
value of the variable D.
• To read variables from a sequential file, we essentially reverse the write procedure. First, open the
file using:
where N is an integer file number and SeqFileName is a complete file path. The file is closed using:
Close N
• The Input statement is used to read in variables from a sequential file. The format is:
The variable names in the list are separated by commas. If no variables are listed, the current line in
the file N is skipped.
• Note variables must be read in exactly the same manner as they were written. So, using our
previous example with the variables A, B, C, and D, the appropriate statements are:
Input #1, A, B, C
Input #1, D
These two lines read the variables A, B, and C from the first line in the file and D from the second line.
It doesn’t matter whether the data was originally written to the file using Write or Print (i.e. commas
are ignored).
Quick Example: Reading Variables from Sequential Files
Note the Debug.Print statements and how you can add some identifiers (in quotes) for
printed information.
3. Run the program. Look in the debug window and note the variable values. Save the
application, if you want to.
4. Rerun the program using Test2.Txt as in the input file. What differences do you see? Do
you see the problem with using Print and string variables? Because of this problem, I almost
always use Write (instead of Print) for saving variable information to files. Edit the
Test2.Txt file (in Notepad), putting quotes around the words Visual Basic. Rerun the
program using this file as input - it should work fine now.
• In many applications, we would like to be able to save text information and retrieve it for later
reference. This information could be a text file created by an application or the contents of a Visual
Basic text box.
where Line is the current line (a text string). This statement should be in a loop that encompasses all
lines of the file. You must know the number of lines in your file, beforehand.
If we want to write the contents of the Text property of a text box named txtExample to a file, we use:
Example
We have a text box named txtExample. We want to save the contents of the Text property of that box
in a file named MyText.ned on the c: drive in the \MyFiles directory. The code to do this is:
This line is usually placed in a Do/Loop structure that is repeated untill all lines of the file are read in.
The EOF() function can be used to detect an end-of-file condition, if you don’t know, a prioiri, how
many lines are in the file.
To place the contents of a file opened with number N into the Text property of a text box named
txtExample we use the Input function:
txtExample.Text = Input(LOF(N), N)
This Input function has two arguments: LOF(N), the length of the file opened as N and N, the file
number.
Example
We have a file named MyText.ned stored on the c: drive in the \MyFiles directory. We want to read
that text file into the text property of a text box named txtExample. The code to do this is:
The text in the file will now be displayed in the text box.
Random Access Files
• Note that to access a particular data item in a sequential file, you need to read in all items in the file
prior to the item of interest. This works acceptably well for small data files of unstructured data, but for
large, structured files, this process is time-consuming and wasteful. Sometimes, we need to access
data in nonsequential ways. Files which allow nonsequential access are random access files.
• To allow nonsequential access to information, a random access file has a very definite structure. A
random access file is made up of a number of records, each record having the same length
(measured in bytes). Hence, by knowing the length of each record, we can easily determine (or the
computer can) where each record begins. The first record in a random access file is Record 1, not 0
as used in Visual Basic arrays. Each record is usually a set of variables, of different types, describing
some item. The structure of a random access file is:
• A good analogy to illustrate the differences between sequential files and random access files are
cassette music tapes and compact discs. To hear a song on a tape (a sequential device), you must go
past all songs prior to your selection. To hear a song on a CD (a random access device), you simply
go directly to the desired selection. One difference here though is we require all of our random access
records to be the same length - not a good choice on CD’s!
• To write and read random access files, we must know the record length in bytes. Some variable
types and their length in bytes are:
So, for every variable that is in a file’s record, we need to add up the individual variable length’s to
obtain the total record length. To ease this task, we introduce the idea of user-defined variables.
User-Defined Variables
• Data used with random access files is most often stored in user-defined variables. These data types
group variables of different types into one assembly with a single, user-defined type associated with
the group. Such types significantly simplify the use of random access files.
• The Visual Basic keyword Type signals the beginning of a user-defined type declaration and the
words End Type signal the end. An example best illustrates establishing a user-defined variable. Say
we want to use a variable that describes people by their name, their city, their height, and their weight.
We would define a variable of Type Person as follows:
Type Person
Name As String
City As String
Height As Integer
Weight As Integer
End Type
These variable declarations go in the same code areas as normal variable declarations, depending on
desired scope. At this point, we have not reserved any storage for the data. We have simply
described to Visual Basic the layout of the data.
• To create variables with this newly defined type, we employ the usual Dim statement. For our
Person example, we would use:
And now, we have three variables, each containing all the components of the variable type Person. To
refer to a single component within a user-defined type, we use the dot-notation:
VarName.Component
Note the similarity to dot-notation we’ve been using to set properties of various Visual Basic tools.
• We look at writing and reading random access files using a user-defined variable. For other variable
types, refer to Visual Basic on-line help. To open a random access file named RanFileName, use:
where N is an available file number and RecordLength is the length of each record. Note you don’t
have to specify an input or output mode. With random access files, as long as they’re open, you can
write or read to them.
Close N
• As mentioned previously, the record length is the sum of the lengths of all variables that make up a
record. A problem arises with String type variables. You don’t know their lengths ahead of time. To
solve this problem, Visual Basic lets you declare fixed lengths for strings. This allows you to determine
record length. If we have a string variable named StrExample we want to limit to 14 characters, we
use the declaration:
Recall each character in a string uses 1 byte, so the length of such a variable is 14 bytes.
• Recall our example user-defined variable type, Person. Let’s revisit it, now with restricted string
lengths:
Type Person
Name As String * 40
City As String * 35
Height As Integer
Weight As Integer
End Type
The record length for this variable type is 79 bytes (40 + 35 +2 + 2). To open a file named PersonData
as File #1, with such records, we would use the statement:
• The Get and Put statements are used to read from and write to random access files, respectively.
These statements read or write one record at a time. The syntax for these statements is simple:
The Get statement reads from the file and stores data in the variable, whereas the Put statement
writes the contents of the specified variable to the file. In each case, you can optionally specifiy the
record number. If you do not specify a record number, the next sequential position is used.
• The variable argument in the Get and Put statements is usually a single user-defined variable. Once
read in, you obtain the component parts of this variable using dot-notation. Prior to writing a user-
defined variable to a random access file, you ‘load’ the component parts using the same dot-notation.
• There’s a lot more to using random access files; we’ve only looked at the basics. Refer to your
Visual Basic documentation and on-line help for further information. In particular, you need to do a
little cute programming when deleting records from a random access file or when ‘resorting’ records
• Note to both write and read sequential and random access files, we need a file name for the Open
statement. To ensure accuracy and completeness, it is suggested that common dialog boxes be used
to get this file name information from the user. I’ll provide you with a couple of code segments that do
just that. Both segments assume you have a common dialog box on your form named cdlFiles, with
the CancelError property set equal to True. With this property True, an error is generated by
Visual Basic when the user presses the Cancel button in the dialog box. By trapping this error, it
allows an elegant exit from the dialog box when canceling the operation is desired.
•The code segment to obtain a file name (MyFileName with default extension Ext) for opening a file to
read is:
A few words on what’s going on here. First, some properties are set such that only files with Ext (a
three letter string variable) extensions are displayed (Filter property), the default extension is Ext
(DefaultExt property), the title bar is set (DialogTitle property), and some Flags are set to insure the
file and path exist (see Appendix II for more common dialog flags).
Error trapping is enabled to trap the Cancel button. Finally, the common dialog box is displayed and
the filename property returns with the desired name. That name is put in the string variable
MyFileName. What you do after obtaining the file name depends on what type of file you are dealing
with. For sequential files, you would open the file, read in the information, and close the file. For
random access files, we just open the file here. Reading and writing to/from the file would be handled
elsewhere in your coding.
•The code segment to retrieve a file name (MyFileName) for writing a file is:
If we want to save the file with the same name we opened it with, we simply close the file. If the name
is different, we must open a file (using a different number) with the new name, write the complete
random access file, then close it. Like I said, it’s trickier.
•We use both of these code segments in the final example where we write and read sequential files
1. We now add the capability to read in and save the contents of the text box in the Note Editor
application from last class. Load that application. Add a common dialog box to your form.
Name it cdlFiles and set the CancelError property to True.
2. Modify the File menu (use the Menu Editor and the Insert button) in your application, such
that Open and Save options are included. The File menu should now read:
File
New
Open
Save
Exit
And for the mnuFileSave_Click procedure, use this code. Much of this can be copied from the
previous procedure.
Each of these procedures is similar. The dialog box is opened and, if a filename is returned,
the file is read/written. If Cancel is pressed, no action is taken. These routines can be used as
templates for file operations in other applications.
4. Save your application. Run it and test the Open and Save functions. Note you have to save a
file before you can open one. Check for proper operation of the Cancel button in the common
dialog box.
5. If you have the time, there is one major improvement that should be made to this application.
Notice that, as written, only the text information is saved, not the formatting (bold, italic,
underline, size). Whenever a file is opened, the text is displayed based on current settings. It
would be nice to save formatting information along with the text. This can be done, but it
involves a fair amount of reprogramming. Suggested steps:
A. Add lines to the mnuFileSave_Click routine that write the text box properties FontBold,
FontItalic, FontUnderline, and FontSize to a separate sequential file. If your text file is named
TxtFile.ned, I would suggest naming the formatting file TxtFile.fmt. Use string functions to put
this name together. That is, chop the ned extension off the text file name and tack on the fmt
extension. You’ll need the Len() and Left() functions.
B. Add lines to the mnuFileOpen_Click routine that read the text box properties FontBold,
FontItalic, FontUnderline, and FontSize from your format sequential file. You’ll need to define
some intermediate variables here because Visual Basic won’t allow you to read properties
directly from a file. You’ll also need logic to set/reset any check marks in the menu structure
to correspond to these input properties.
C. Add lines to the mnuFileNew_Click procedure that, when the user wants a new file, reset
the text box properties FontBold, FontItalic, FontUnderline, and FontSize to their default
values and set/reset the corresponding menu check marks.
D. Try out the modified application. Make sure every new option works as it should.
Actually, there are ‘custom’ tools (we’ll look at custom tools in Class 10) that do what we are
trying to do with this modification, that is save text box contents with formatting information.
Such files are called ‘rich text files’ or rtf files. You may have seen these before when
transferring files from one word processor to another.
6. Another thing you could try: Modify the message box that appears when you try to Exit. Make
it ask if you wish to save your file before exiting - provide Yes, No, Cancel buttons. Program
the code corresponding to each possible response. Use calls to existing procedures, if
possible.
Design and develop an application that allows the user to enter (on a daily basis) some piece of
information that is to be saved for future review and reference. Examples could be stock price, weight,
or high temperature for the day. The input screen should display the current date and an input box for
the desired information. all values should be saved on disk for future retrieval and update. A scroll bar
should be available for reviewing all previously-stored values.
My Solution:
Form:
Properties:
Form frmWeight:
BorderStyle = 1 - Fixed Single
Caption = Weight Program
VScrollBar vsbControl:
Min = 1
Value = 1
TextBox txtWeight:
Alignment = 2 - Center
FontName = MS Sans Serif
FontSize = 13.5
Label lblFile:
BackColor = &H0000FFFF& (White)
BorderStyle = 1 - Fixed Single
Caption = New File
FontName = MS Sans Serif
FontBold = True
FontItalic = True
FontSize = 8.25
Label lblDate:
Alignment = 2 - Center
BackColor = &H00FFFFFF& (White)
BorderStyle = 1 - Fixed Single
FontName = MS Sans Serif
FontSize = 13.5
Label Label2:
Alignment = 2 - Center
Caption = Weight
FontName = MS Sans Serif
FontSize = 13.5
FontBold = True
Label Label1:
Alignment = 2 - Center
Caption = Date
FontName = MS Sans Serif
FontSize = 13.5
FontBold = True
CommonDialog cdlFiles:
CancelError = True
Menu mnuFile:
Caption = &File
Menu mnuFileNew:
Caption = &New
Menu mnuFileOpen:
Caption = &Open
Menu mnuFileSave:
Caption = &Save
Menu mnuLine:
Caption = -
Menu mnuFileExit:
Caption = E&xit
Code:
General Declarations:
Option Explicit
Dim Dates(1000) As Date
Dim Weights(1000) As String
Dim NumWts As Integer
Sub Init()
NumWts = 1: vsbControl.Value = 1: vsbControl.Max = 1
Dates(1) = Format(Now, "mm/dd/yy")
Weights(1) = ""
lblDate.Caption = Dates(1)
txtWeight.Text = Weights(1)
lblFile.Caption = "New File"
End Sub
Under the File menu on nearly every application (that opens files) is a list of the four most recently-
used files (usually right above the Exit option). Modify your information tracker to implement such a
feature. This is not trivial -- there are lots of things to consider.
For example, you’ll need a file to store the last four file names. You need to open that file and initialize
the corresponding menu entries when you run the application -- you need to rewrite that file when you
exit the application. You need logic to re-order file names when a new file is opened or saved. You
need logic to establish new menu items as new files are used. You’ll need additional error-trapping in
the open procedure, in case a file selected from the menu no longer exists. Like I said, a lot to
consider here.
My Solution:
These new menu items immediately precede the existing Exit menu item:
Menu mnuFileRecent:
Caption = [Blank]
Index = 0, 1, 2, 3 (a control array)
Visible = False
Menu mnuFileBar:
Caption = -
Visible = False
General Declarations:
Option Explicit
Dim Dates(1000) As Date
Dim Weights(1000) As String
Dim NumWts As Integer
Dim NFiles As Integer, RFile(3) As String, MenuOpen As Integer, FNmenu As
String
BadOpen:
Select Case MsgBox(Error(Err.Number), vbCritical + vbRetryCancel, "File
Open Error")
Case vbRetry
Resume
Case vbCancel
Resume No_Open
End Select
End Sub
All business applications need to store large volumes of data organized in a format so that information
can be retrieved efficiently and quickly as and when required. With the help of a DBMS (Database
Management System), managing the data becomes easy. A DBMS is a system that manages the
storage and retrieval of data in a database.
Further Microsoft Visual Basic provides tools for creating and accessing a variety of RDBMS
(Relational Database Management System). An RDBMS stores and retrieves information according to
the relationship defined. In a RDBMS, the data is the container of the tables in which all data is stored
in the relationships is formed by data values.
A database is a collection of data that is related one to another to support a common application. For
example Employee details - Name, Address, etc. Each of these collections of data continue a
database.
Contents
Database Structure and Terminology
Data Links
Assigning Tables
Data Manager
Example - Phone Directory - Creating the Database
Database Management
Example - Phone Directory - Managing the Database
• The rows in a database table are used to describe similar items. The rows are referred to as
database records. In general, no two rows in a database table will be alike.
• The columns in a database table provide characteristics of the records. These characteristics are
called database fields. Each field contains one specific piece of information. In defining a database
field, you specify the data type, assign a length, and describe other attributes.
• Here is a simple database example:
In this database table, each record represents a single individual. The fields (descriptors of the
individuals) include an identification number (ID No), Name, Date of Birth, Height, and Weight.
• Most databases use indexes to allow faster access to the information in the database. Indexes are
sorted lists that point to a particular row in a table. In the example just seen, the ID No field could be
used as an index.
• A database using a single table is called a flat database. Most databases are made up of many
tables. When using multiple tables within a database, these tables must have some common fields to
allow cross-referencing of the tables. The referral of one table to another via a common field is called
a relation. Such groupings of tables are called relational databases.
• In our first example, we will use a sample database that comes with Visual Basic. This database
(BIBLIO.MDB) is found in the main Visual Basic directory (try c:\Program Files\Microsoft Visual
Studio\VB98). It is a database of books about computers. Let’s look at its relational structure. The
BIBLIO.MDB database is made up of four tables:
Note each table has two types of information: source data and relational data. Source data is actual
information, such as titles and author names. Relational data are references to data in other tables,
such as Au_ID and PubID. In the Authors, Publishers and Title Author tables, the first column is used
as the table index. In the Titles table, the ISBN value is the index.
• Using the relational data in the four tables, we should be able to obtain a complete description of any
book title in the database. Let’s look at one example:
Here, the book in the Titles table, entitled “Step-by-step dBase IV,” has an ISBN of 0-0280095-2-5
and a PubID of 52. Taking the PubID into the Publishers table, determines the book is published by
McGraw-Hill and also allows us to access all other information concerning the publisher. Using the
ISBN in the Title Author table provides us with the author identification (Au_ID) of 171, which, when
used in the Authors table, tells us the book’s author is Toby Wraye.
• We can form alternate tables from a database’s inherent tables. Such virtual tables, or logical
views, are made using queries of the database. A query is simply a request for information from the
database tables. As an example with the BIBLIO.MDB database, using pre-defined query languages,
we could ‘ask’ the database to form a table of all authors and books published after 1992, or provide
all author names starting with B. We’ll look briefly at queries.
• Keeping track of all the information in a database is handled by a database management system
(DBMS). They are used to create and maintain databases. Examples of commercial DBMS programs
are Microsoft Access, Microsoft FoxPro, Borland Paradox, Borland dBase, and Claris FileMaker. We
can also use Visual Basic to develop a DBMS. Visual Basic shares the same ‘engine’ used by
Microsoft Access, known as the Jet engine. In this class, we will see how to use Visual Basic to
access data, display data, and perform some elementary management operations.
• The ADO (ActiveX Data Object) data control is the primary interface between a Visual Basic
application and a database. It can be used without writing any code at all! Or, it can be a central part
of a complex database management system. This icon may not appear in your Visual Basic toolbox. If
it doesn’t, select Project from the main menu, then click Components. The Components window will
appear. Select Microsoft ADO Data Control, then click OK. The control will be added to your toolbox.
• As mentioned in Review and Preview, previous versions of Visual Basic used another data control.
That control is still included with Visual Basic 6.0 (for backward compatibility) and has as its icon:
Make sure you are not using this data control for the work in this class. This control is suitable for
small databases. You might like to study it on your own.
• The data control (or tool) can access databases created by several other programs besides Visual
Basic (or Microsoft Access). Some other formats supported include Btrieve, dBase, FoxPro, and
Paradox databases.
1. Connect to a database.
4. Pass database fields to other Visual Basic tools, for display or editing. Such tools are bound tools
(controls), or data aware.
LockType Indicates the type of locks placed on records during editing (default setting
makes databases read-only).
RecordSource Determines the table (or virtual table) the data control is attached to.
• As a rule, you need one data control for every database table, or virtual table, you need access to.
One row of a table is accessible to each data control at any one time. This is referred to as the current
record.
• When a data control is placed on a form, it appears with the assigned caption and four arrow
buttons:
The arrows are used to navigate through the table rows (records). As indicated, the buttons can be
used to move to the beginning of the table, the end of the table, or from record to record.
Data Links
• After placing a data control on a form, you set the ConnectionString property. The ADO data
control can connect to a variety of database types. There are three ways to connect to a database:
using a data link, using an ODBC data source, or using a connection string. In this lesson, we will look
only at connection to a Microsoft Access database using a data link. A data link is a file with a UDL
extension that contains information on database type.
• If your database does not have a data link, you need to create one. This process is best illustrated
by example. We will be using the BIBLIO.MDB database in our first example, so these steps show
you how to create its data link:
1. Open Windows Explorer.
2. Open the folder where you will store your data link file.
3. Right-click the right side of Explorer and choose New. From the list of files, select Microsoft
Data Link.
4. Rename the newly created file BIBLIO.UDL
5. Right-click this new UDL file and click Properties.
6. Choose the Provider tab and select Microsoft Jet 3.51 OLE DB Provider (an Access
database).
7. Click the Next button to go to the Connection tab.
8. Click the ellipsis and use the Select Access Database dialog box to choose the
BIBLIO.MDB file which is in the Visual Basic main folder. Click Open.
9. Click Test Connection. Then, click OK (assuming it passed). The UDL file is now created
and can be assigned to ConnectionString, using the steps below.
• If a data link has been created and exists for your database, click the ellipsis that appears next to the
ConnectionString property. Choose Use Data Link File. Then, click Browse and find the file. Click
Open. The data link is now assigned to the property. Click OK.
Assigning Tables
• Once the ADO data control is connected to a database, we need to assign a table to that control. Recall each data con
is attached to a single table, whether it is a table inherent to the database or the virtual table we discussed. Assigning a
table is done via the RecordSource property.
• Tables are assigned by making queries of the database. The language used to make a query is SQL (pronounced
‘sequel,’ meaning structured query language). SQL is an English-like language that has evolved into the most widely us
database query language. You use SQL to formulate a question to ask of the database. The data base ‘answers’ that
question with a new table of records and fields that match your criteria.
• A table is assigned by placing a valid SQL statement in the RecordSource property of a data control. We won’t be
learning any SQL here. There are many texts on the subject - in fact, many of them are in the BIBLIO.MDB database w
been using. Here we simply show you how to use SQL to have the data control ‘point’ to an inherent database table.
• Click on the ellipsis next to RecordSource in the property box. A Property Pages dialog box will appear. In the box
marked Command Text (SQL), type this line:
This will select all fields (the * is a wildcard) from a table named TableName in the database. Click OK.
• Setting the RecordSource property also establishes the Recordset property, which we will see later is a very importa
property.
• In summary, the relationship between the data control and its two primary properties (ConnectionString and
RecordSource) is:
Label - Can be used to provide display-only access to a specified text data field.
Text Box - Can be used to provide read/write access to a specified text data field. Probably, the most widely used data
bound tool.
Combo Box - Can be used to provide read/write access to a text data field.
List Box - Can be used to provide read/write access to a text data field.
.