During this hour you will learn
No application is ever complete. You always can add more features, and many times errors appear long after you think you've removed all of them. Therefore, a program's long-term maintenance is part of the programming process. You can take steps to eliminate some of the maintenance headaches, however. Throughout the previous lessons, this tutorial has offered tips to help you better document your code and reduce maintenance problems.
One of the best ways to reduce maintenance problems is to thoroughly debug and test your application before you distribute the application to your users. This lesson describes some of the debugging tools that Visual Basic supplies as well as some testing procedures that you might want to run your application through before you distribute the application.
Testing is the process by which you run applications through a series of test-case executions. During the testing, you enter random and extreme values in all the user-entry controls to ensure that the application can handle values outside the typical range. Generally, you find bugs during the testing phase. Debugging is a three-part routine: determine problem bugs and their locations, correct the bugs, and-finally-retest the application to ensure that you eliminated the bugs.
Bugs range from mild errors, such as misspellings or text-alignment mistakes, to serious errors, such as what happens when an application terminates the entire Windows session and results in lost data. To your users, a bug is anything that doesn't match expected program results or prevents the application from running.
Programmers face many debugging problems when looking for bugs. You must decide that you've found as many bugs as you can possibly find, and you must test and retest to ensure that the bugs are gone and don't reappear. Careful planning before, during, and after the coding process helps you reduce the time it takes to debug your application.
Develop and test your application from within the Visual Basic development environment. The development environment contains debugging tools that help you track and locate errors. Only after you're satisfied with your test results should you then compile and distribute your application. (Hour 37, "Packaging Your Application," explains how to compile and distribute your application.)
![]()
Windows and the powerful Visual Basic development environment help you locate errors. When you run a Visual Basic application, Visual Basic might find an error during the compilation or preparation for the program's execution, such as a misspelled keyword, and display an error message, such as the one shown in Figure 36.1.
Visual Basic finds syntax errors for you.
If, when you run an application such as the Visual Basic Scheduler, you see such an error message before you see the first form appear on-screen, you probably embedded a syntax error in your code. A syntax error is an error in a programming language's grammar or spelling. Figure 36.1's error is a syntax error.
Notice that Visual Basic not only told you about the error in Figure 36.1 but also located the error inside the Code window. Even if the Code window is closed when you try to run the program, Visual Basic highlights the error. The problem is that Load is misspelled as Loaad. After you fix the syntax error, you then can click the Run toolbar button to start the program from the corrected error!
Syntax Errors at Design Time
If you have the Auto Syntax Chec
Therefore, you can turn off the automatic syntax check. When the option is off, Visual Basic doesn't check for coding errors, such as a missing parenthesis, until you run or compile the program. Either way, Visual Basic locates these kinds of bugs for you, but the automatic syntax check option gives you the choice of when you want Visual Basic to tell you about the code problem.kcheck box marked on the Options dialog box's Editor page, Visual Basic checks for syntax errors as you type program code into the Code window. (ChooseOptions from theTools menu to access this dialog box.) Some programmers, however, like to have more freedom at design time to sprinkle partial statements here and there that they will repair later in the programming process.
More difficult errors appear during the runtime of your application. A syntax error is easy to spot because Visual Basic finds it for you. A runtime error is more difficult to locate and correct. Consider the error shown in Figure 36.2. The error involves program logic. No error message appears, but something is certainly wrong with the application.
Logic errors are more difficult to find.
The logic error requires that you stop the program. (Visual Basic doesn't recognize the error and stop the program as it does with syntax errors.) You then must track down the problem.
If you want to duplicate Figure 36.2's error, change the Visual Basic Scheduler's standard module's General section line that correctly reads Public Const GUTTER_HORZ = 6 to Public Const GUTTER_HORZ = 67. Now that's a bug that would be hard to trace. See how the extra digit throws off the positioning of the entire frame in Figure 36.2.
![]()
You must search through the program code looking for traces where such a runtime logic error might reside and then fix the problem. If the problem involves the form's appearance on-screen, you have to trace all references to that part of the form. Often, but now always, the Object Browser can help you find specific code that goes with an object.
Visual Basic can locate some logic errors if the logic error is a request for Visual Basic to do something impossible. For example, Figure 36.3 shows what happens when a program asks Visual Basic to divide a number by zero. Division by zero isn't defined mathematically, so Visual Basic can't accomplish this calculation even if no syntax errors appear in the calculation.
Some logic errors trigger Visual Basic error messages.
The application runs smoothly without the Code window showing.
However, as soon as Visual Basic realizes that the program is
requesting an impossible task, Visual Basic displays the Code
window and locates the approximate place in the code where the
division by zero occurs. You can click the error dialog box'sHelp
button to get more help on the error message, clickEnd
to terminate the program's execution, or click Debug to
enter Visual Basic debugging mode.
Visual Basic's development environment includes a debugging tool that becomes part of the development environment when you request debugging help. The debug tool lets you do all the following tasks:
You can enter the debugging mode and have access to all the debugger's
features (primarily found on the Debug menu) when you do
any of the following:
One of the easiest breakpoints to set is the run-to-cursor
breakpoint. Suppose that you suspect that the Visual Basic
Scheduler doesn't test for a leap year properly. You can click
the first statement in the standard module's IsLeapYear()
function and select Run To Cursor from the Debug
menu. The program starts up as usual but halts at the breakpoint
and highlights the line.
The program isn't halted permanently. Up to this point, all the
program variables have been initialized, the code has run, and
its effects are available. If output occurred before the cursor's
location (none did in this example of the Visual Basic Scheduler),
you would have seen the output, such as the Form window, appear
on-screen as usual. The program, as indicated by Visual Basic's
title bar, is in its break state reached due to the breakpoint.
The yellow highlight is the line where the cursor rested when
you chose Run To Cursor from the Debug menu.
Here is the procedure where this particular example stops:
Public Function IsLeapYear(iYear As Integer) As Boolean If iYear Mod 4 = 0 Then IsLeapYear = True Else IsLeapYear = False End If End Function
Perhaps the leap year doesn't work because it receives an incorrect year value from whatever procedure passed iYear to the function. Therefore, you can look at the current value of iYear to see whether it contains what you expect.
Looking at a variable's contents has never been easier. As Figure 36.4 shows, assuming that the current year is 1997, all you need to do to see the value of iYear is rest your mouse cursor over the variable.
Visual Basic pops up with the variable's value.
Suppose that the year is not 1997. You've just found that the leap year calculation is okay and you have to search back further in the code to see where iYear got its value. If the variable has a correct value, however, you might want to run the program a little further.
Before going further, display the Debug toolbar. From the View
menu, choose Toolbars and then Debug to display
the Debug toolbar. (As you debug, the toolbar can float, or you
can dock the toolbar to the upper toolbar area.) When you need
to see where the program's execution has been up to a breakpoint,
you can use one of the most useful features-the Call Stack. Click
the toolbar's Call Stack button. As Figure 36.5 shows, the Call
Stack dialog box appears and shows your program's execution, procedure
by procedure, until its current position.
The Call Stack dialog box retraces your program's procedures.
If you see a Call Stack entry labeled [<Non-Basic Code>], execution occurred from another source, such as the GetCursorPos() Windows API call described in Hour 35, "Integrating Code."
![]()
If you want to show one of the Call Stack dialog box's procedures, double-click that entry and Visual Basic takes you to that procedure. From there, you don't just look at code, but at live values as well. Keep in mind that the application is in a breakpoint stage still, so you can view the values of any variable (or named literal) within that previous procedure.
At any breakpoint, you can click the Debug toolbar's Step Into button to execute the next statement in the program. Whatever statement normally executes next (even if that statement is a call to another procedure) executes when you click Step Into.
The Debug toolbar contains three Step-related buttons; Table 36.1 describes how to use them. You might not want to single-step through every statement in an application; the Step buttons give you some options on how you want the program to continue.
Table 36.1 The Possible Step Modes
Step Mode | Description |
Step Into | Executes only the next statement. Even if the statement is in another procedure or a return to a previous procedure, the next statement executes and you're placed at that next statement. Therefore, you can single-step through an entire application by pressing F8 continually. |
Step Over | Executes the next statement unless the next statement is the call to a different procedure. The new procedure executes in its entirety and execution halts at the statement following the procedure call. |
Step Out | Finishes executing the current procedure and then, at the next statement outside the procedure, execution halts again. |
Of course, at any breakpoint, you can click the Start button to continue the execution in its normal manner. If subsequent breakpoints are set, the execution halts at those breakpoints. Otherwise, the program behaves normally as if you'd never stopped it.
![]()
You can terminate debug mode at any time by clicking the Visual Basic Toolbar's End button or by choosing
End from theRun menu.![]()
As your applications execute, you might want to set breakpoints along the way. The breakpoints halt the program's execution so that you can study variables and controls during mid-execution. For example, if you see runtime problems that you want to analyze on the next program run, add a breakpoint by clicking the Debug toolbar's Toggle Breakpoint button at the highlighted statement. You can set multiple breakpoints on additional lines by clicking the Toggle Breakpoint button throughout the code. If you reach a breakpoint (indicated by a red highlight) that you set in a previous session but no longer need, use Toggle Breakpoint again on that line to remove the breakpoint from that location.
You can set breakpoints only for lines that execute. You can't set a breakpoint on lines that declare user data types or contain only remarks.
![]()
At any breakpoint, you can display the Debug window to work outside the program's environment. The Debug window is often called the Immediate window. When you click the Debug toolbar's Immediate window button, the Immediate window opens at the bottom of your Code window if docked, or in a free-floating location if the immediate window isn't docked to the edge of the screen.
You can type any Visual Basic statement in the Immediate window and see the results of that statement's execution immediately. One of the most common Debug window commands used is Print, which prints variable values and control properties. Print sends output to different objects (not just to the printer), including the Immediate window. Figure 36.6 shows the form name printed to show that the values you work with in the Immediate window are live values set by the part of the application that's executed to that breakpoint. Also, you can print the results of any expression. If you need to, you can change variable values during execution. After you do that, the rest of the program works with the new value instead of the one assigned originally in the code; that way, you can see the results of the variable's change.
Use the Immediate window to print values and change results.
Although the interactive nature of Visual Basic's development environment makes such output less important than it used to be in text environments, your program can write directly to the Immediate window by using the Debug object's Print method. Therefore, if your program includes a statement such as
the output goes to the Immediate window, where you can view the output without having to interfere with the normal application's output in the Form window.
![]()
When you click the Locals Window button on the Debug toolbar, Visual Basic displays Figure 36.7's Locals window. The Locals window shows the current value of all variables local to the current procedure (the procedure holding the current breakpoint), as well as global literals and variables.
The Locals window shows all variables local to the current procedure as well as globals.
If you modify a local variable from within the Immediate window, its value changes in the Locals window as well.
![]()
In addition to the variable name and value, the Locals window displays the variable's data type. Click the ellipses button to the right of the Locals window's current procedure name to view a call stack list. When you click one of the call stack procedure names, the Locals window updates to show that procedure's local variables.
As your debugging process continues, you might find that a bug occurs only when a variable has a certain value. Sometimes problems can't be traced to a single statement, so you have to watch a variable or expression throughout an entire procedure. Visual Basic provides the Watch window in which you can enter values for variables or expressions. You can set up the Watch window with values to watch for at design time or runtime by clicking the Watch window Debug toolbar button. You can use either of the following two methods for adding values to the Watch window:
Add values to watch for in the Add Watch window.
When adding a watch expression, the context of the watch tells Visual Basic the scope of the watch (where it should monitor the expression). Visual Basic can watch a single procedure, a form, a module, or the entire project.
The Watch type lets you specify how you want Visual Basic to respond to the watch value. Visual Basic can display the data in the expression as the value changes at runtime, break the execution when the value is reached, or break every time the watched values change. During subsequent execution, Visual Basic updates the Watch window according to your watched values.
Visual Basic includes the Quick Watch window, which lets you add watch values on the fly during any breakpoint. Highlight a variable, expression, or control property, and then click the Quick Watch button on the Debug toolbar. Figure 36.9 shows the Quick Watch window that appears for one of the GetDay() procedure's arguments. You can add this expression to the regular Watch window by clicking
Many programmers find that using Quick Watch during a program's debugging breakpoint is easier to do than trying to collect all the values that you want to watch at design time through the Add Watch dialog box.Add.![]()
At any breakpoint, click Quick Watch to add the highlighted expression to the Watch window.
This lesson described Visual Basic's powerful debugging tools. Learning how to debug an application such as the Visual Basic Scheduler pays dividends when you need to track bugs. Although Visual Basic's debugging tool can't locate logic errors, the debugger makes it easier for you to locate them. You can trace a program's execution, set breakpoints, and retrace a program's execution from whence it came.
One of the most powerful aspects of the debugger is its interactivity with the program during a breakpoint session. When your program reaches a breakpoint, all the values initialized and computed to that point are still live. Therefore, you can view variables to see whether their intermediate results contain the same values you expect. Also, you can change a variable's or control's value in the middle of the program's execution and watch how the rest of the execution reflects on that change.
Hour 37 completes this part of the book. After you debug your application, you're ready to distribute the application to your users. Application distribution is more involved than simply compiling your application. You must consider the installation routine and ensure that users have all the necessary files related to the application.
No questions or exercises exist for this lesson due to the general nature of the material.
![]()