A Tutorial in Xbasic

IN THIS PAGE

Description

Xbasic is Alpha Anywheres built-in programming language. Out of the box, Alpha Anywhere is a powerful database and application development software package. You can use Alpha Anywhere for lots of different information management needs without doing any programming by using the Alpha Anywhere menus, commands, and Genies.

Genies are sequences of commands that Alpha Anywhere performs to automatically accomplish various tasks. After you answer a series of questions about what you need to do, Alpha Anywhere figures out the best way to accomplish the task and runs it. For example, Alpha Anywhere includes an Import Data Genie that guides you through incorporating existing data from external files into an Alpha Anywhere database. Genies and the Alpha Anywhere commands enable you to do a lot; Programming with Xbasic gives you even more control and options.

However, learning Xbasic will provide you with the tools to do much more with Alpha Anywhere. Mastering Xbasic will open up vast new opportunities for you to create highly customized applications and will allow you to manipulate your data in just the way you want. And the new additions to the Xbasic commands in Version 5 provide you with the power to design and develop applications using the latest Windows techniques, structures, and tools.

Xbasic is a very rich programming language with literally hundreds of commands, so it is not possible to learn everything you can do with Xbasic in this volume. You will get a good grounding in basic programming concepts that you should understand in order to use Xbasic efficiently. You will want to refer to the Alpha Anywhere Xbasic Reference Guide to explore all the different options that Xbasic offers and you should experiment with different Xbasic techniques and commands to really learn by doing. We think programming is creative and fun and we hope you will too.

What is Xbasic?

You should already be familiar with Alpha Anywhere menus, commands, and workspace creation and use. For example, to create a new workspace, select the File > New Workspace command from the Alpha Anywhere Main Menu.

Figure 1
Programming concepts deal with the terminology and definitions that you should understand in order to get the most out of programming. In the next section, well introduce you to variables, storage, commands, functions, expressions, scripts, objects, events, and programmatic flow control. But, relax, Xbasic makes all this stuff powerfully easy!

When you select the Tables/Sets tab and click the New command, Alpha Anywhere presents you with several options for creating a new Table or Set. You can create a New Table or a New Set using the respective commands. You can also create a table or set by using the Genie. If you choose to create a table directly, Alpha Anywhere will immediately display the Table Editor where you can define the name, type, width, and other characteristics of your tables data fields. On the other hand, if you chose the Create using Genie command (see Figure 2), Alpha Anywhere will ask you what kind of table you want to create and it will automatically define a table structure for you (which you can then modify) in the Table Editor.

Figure 2

While Alpha Anywhere offers the ability to create tables from within the IDE (DBF tables), it is recommended that you use a SQL Data Source for web and/or mobile applications.

Code is a name for programming commands. All computers perform tasks according to the instructions that they are told to perform. You create the instructions using a computer language. The language of computer instructions of Alpha Anywhere is called Xbasic. Xbasic is made up of commands (words) that direct the computer to perform certain actions. There are certain rules (syntax) you must follow when you specify the Xbasic commands you want the computer to process. When you create a file or set of Xbasic commands we call that file an Alpha Anywhere script. The name script is related to a movie script. Just as a movie script tells the actors what to say and do, an Alpha Anywhere script contains Xbasic commands that tell the computer what you want it to do.

Once a table is defined, you can use the other choices on the Alpha Anywhere Control Panel (see Figure 3). You can create Forms and Browses to use for viewing, entering, and modifying your data. You can design Reports, Letters, or Labels to use in reviewing, displaying, and printing your data. And you can define an Operation to manipulate, transfer, search, and summarize your data. Finally, you can create Code or programming commands. The code you create is stored in text files that are called scripts. A script (which contains a sequence of Xbasic commands) can be re-used or run. When Alpha Anywhere runs a script, it performs all the Xbasic commands that are in the script.

Figure 3
The Code Library is a repository where you can locate scripts or portions of scripts that are useful across different applications. This allows you to easily re-use scripts without having to recreate them.

A script is a text file containing valid (syntactically correct) Xbasic commands that Alpha Anywhere processes and executes. When you create a new script in the Control Panel Code section, you will give the script a name (i.e., the text file that contains the Xbasic commands is named just like any other file on your computer). Alpha Anywhere scripts are stored and associated with the currently active workspace However, Alpha Anywhere contains a special area called the Code Library that lets you easily share script files among different workspaces. Below, Figure 4 shows the Code tab shows other types of files besides scripts. functions (a special type of script) are listed here as well as Custom menus, toolbars, and graphic image files.

Figure 4

For example, if you open the Control Panel Code tab panel for the "Phone Messages" (or "Learning Xbasic") sample database application, you will see the names of all the scripts created for use in the application. The first script is named Chng Msgs Dsply Order (which stands for Change Messages Display Order) as shown in Figure 4 above. When you ask Alpha Anywhere to perform the commands in a script, you specify the script name.

Some scripts are already named in Alpha Anywhere. There are special scripts in Alpha Anywhere called events. Events are files containing Xbasic commands (you will learn more about events a little later), just like scripts, but they are already named and associated with specific Alpha Anywhere components.

Events are pre-named Alpha Anywhere scripts. You define what Xbasic commands are executed when an event is triggered, but events are already built-in (named) in Alpha Anywhere. Events are part of Alpha Anywhere components. For example, a button control on a form has events. One button control event is named OnPush (which is named for the event that occurs when you push that button). When you first create a control there are no Xbasic commands defined for the OnPush event. You add those commands to control what happens when that button is pushed.

As you have learned, a script is a sequence or listing of Xbasic commands. Xbasic commands perform Alpha Anywhere tasks. For example, here is an Xbasic command:

Form.View(Administration)

If Alpha Anywhere encounters this command in a script, it performs the action this command specifies. The first word in this command is Form which tells Alpha Anywhere you want to do something with a form. Next comes a period and then the word View. View signifies that you want a form to be displayed or viewed on the screen. Finally, in the parentheses, you specify the name of the form that you want displayed. (This name must be enclosed in parentheses.) So, assuming that a form named Administration exists in the current database, Alpha Anywhere will display that form on the screen. If there are more commands in the script, Alpha Anywhere will continue with the next command.

For example, after loading the form Administration you might want to display the last record in the table. This Xbasic command will do that:

Administration.Fetch_Last()

We can use these two commands together in a complete two line Xbasic script.

Form.View(Administration)
Administration.Fetch_Last()

If they are saved in a script named Load Last Person, then whenever we want to display the last person using the Administration form, you can run the script Load Last Person.

You can do the very same things done by the Load Last Person script in Exercise 1 using Alpha Anywheres menus and buttons. Its a simple matter to load the Administration form using the View button on the Control Panel and then pressing the Last button to load the last record as shown in Figure 10.

But heres the interesting part! When you click on the buttons like the Last button, Alpha Anywhere is actually performing the same Xbasic commands that are in the Load Last Person script you examined above. When you press the Last button Alpha Anywhere performs the Xbasic command CURRENT_FORM_NAME.Fetch_Last() (where the actual name or reference to the current form is substituted in the Xbasic command for CURRENT_FORM_NAME ).

In fact, Xbasic is such a powerful language, that most of the Alpha Anywhere menu commands, buttons, and screens are Xbasic commands and scripts themselves. This means that the more Xbasic commands you learn, the more you can customize your applications to look, perform, and execute commands just the way you want them to.

Keep in mind that Alpha Anywhere is running Xbasic behind the scenes when you use the built-in Alpha Anywhere menus and commands. And, as you will see later on, Alpha Anywhere can actually write Xbasic code for you! Action scripting consists of Alpha Anywhere Genies that ask you what you want to accomplish and then create scripts automatically. You can modify the code to tweak it in just the way you want, but you save the time and effort of starting from scratch.

In Figure 11 you can see the choices available to you when you create a new script. In this case, we clicked on the Code Tab in the Control Panel and then clicked the New button.

When you select the New Database command, Alpha Anywhere prompts you for a database name and then brings you to the Control Panel where you can begin to design any of the components for your new database system. Typically, you begin by designing the tables that store the data pertinent to your new database.

Exercise 1 - Opening and running an existing Xbasic script 

  1. Open the "Phone Messages" (or "Learning Xbasic") database. (If the "Learning Xbasic" sample database is not included in your list of sample databases, upgrade to the latest Alpha Anywhere patch.) To open the database, display the Select Database screen, which comes up automatically when you start Alpha Anywhere. If you see the News and Updates screen, switch to the Database and Tasks tab. Click on Sample and Tutorial databases..., select Learning Xbasic, press OK, and you will create a working copy of the sample database in your documents folder.

  2. Display the Form tab in the Control Panel.

  3. Verify that form "Administration" exists in this database as shown in figure 5 below.

    Figure 5
  4. Now display the Code tab to see existing Xbasic scripts for the Contact Manager database.

  5. Find the script named Load Last Person.

  6. Left-click once on the Load Last Person script name as shown in Figure 6.

    Figure 6
  7. Right-click on the mouse to bring up the menu shown in Figure 7.

    Figure 7
    The "bubble help" which appears indicating you can see more command options for working with a script by right-clicking your mouse.
  8. Select the Design command from the list in Figure 7. Selecting the Design command launches the Alpha Anywhere Code Editor shown below in Figure in Figure 8

    • Figure 8
    • In Step 8, you could have clicked the Design button above the tabs of the Control Panel. Or you could have chosen Design from the Script menu. Alpha Anywhere provides multiple options for initiating many commands.

    • About The Code Editor 

      An editor is just like a word processing program. The Alpha Anywhere Code Editor is where you create Xbasic scripts by typing Xbasic commands on each line. The Code Editor can be directly launched in many different ways (see notes to Step 8 in the exercise). The Code Editor also loads automatically when you create scripts for Alpha Anywhere events (more on this later).

      In Step 8, you opened an existing script for design or editing. This script appears on the screen in the editing window. The Code Editor has two tabs.

      The active (foreground) tab shows the script you are currently editing. The name of the script appears in the tab. An asterisk after the name indicates the script has been changed but those changes haven't been saved. When you create a new script, the name will be Untitled_# (where # is a number, 1, 2, etc.). You name a new script when you save it by selecting the Save or Save as commands.

      The other tab in Figure 8 is labeled Interactive. This is a special window where you can type and execute Xbasic commands interactively or at once line by line. Using the Interactive Window allows you to immediately test and see what Xbasic commands do. You will try this out in upcoming exercises.

  9. Right click on the mouse to bring up the menu shown in Figure 8.

  10. Select the Design command.

  11. Click the Run button .

    • The Alpha Anywhere Window Bar shows three running windows. Clicking the buttons allows you to quickly switch windows.

      Running a script means that Alpha Anywhere runs or executes each of the commands in the script line by line. Some commands will loop back and execute certain lines a number of times before proceeding; Other commands might extend over many lines of typed text but are treated when entered correctly as one command. When you click on Run the Administration form loads and the last record is fetched as shown below in Figure 9. The primary index for this table is by last name, so the Fetch command loads the last record by that index.

      Figure 9

      Multi-tasking in Alpha Anywhere

      Alpha Anywhere can run multiple tasks at the same time. In Figure 9, you see the Administration form loaded because you ran (executed) the Xbasic commands in the script that you were viewing in the Code Editor window. The Code Editor is still running and still displays the scripts you are working with. And the Control Panel window is also still running. All three of these active Alpha Anywhere tasks are shown on the Window bar near the bottom of the screen. (The Window bar itself is turned on or off using the View drop-down menu.)

      If you click on any of the three buttons on the window bar, your active window will change. A depressed (figuratively speaking!) button indicates the current active (foreground) window.

  12. Click the Code Editor button on the Window bar to switch back to the Code Editor.

You should see the same screen as shown in Figure 8 except that the Window Bar now includes a button for the Administration form displayed by running the Xbasic commands in this script.

Xbasic is the "Brains" of Alpha Anywhere

The Phone Messages database is in the \Learning Xbasic sub-directory in the Alpha Anywhere program directory. If you followed the standard installation, you should find this database in the \Learning Xbasic under your Alpha Anywhere program directory.

You can do the very same things done by the "Load Last Person" script in Exercise 1 using Alpha Anywhere's menus and buttons. It's a simple matter to load the "Administration" form using the View button on the Control Panel and then pressing the Last button to load the last record as shown in Figure 10.

Figure 10

But here's the interesting part! When you click on the buttons like the Last button, Alpha Anywhere is actually performing the same Xbasic commands that are in the "Load Last Person" script you examined above. When you press the Last button Alpha Anywhere performs the Xbasic command CURRENT_FORM_NAME.Fetch_Last() (where the actual name or reference to the current form is substituted in the Xbasic command for CURRENT_FORM_NAME ).

In fact, Xbasic is such a powerful language, that most of the Alpha Anywhere menu commands, buttons, and screens are Xbasic commands and scripts themselves. This means that the more Xbasic commands you learn, the more you can customize your applications to look, perform, and execute commands just the way you want them to.

Keep in mind that Alpha Anywhere is running Xbasic "behind the scenes" when you use the built-in Alpha Anywhere menus and commands. And, as you'll see later on, Alpha Anywhere can actually write Xbasic code for you! Action scripting are a set of Alpha Anywhere Genies that ask you what you want to accomplish and then create scripts automatically. You can modify the code to tweak it in just the way you want, but you save the time and effort of starting from scratch.

Action Scripting 

Action Scripting is an alternative way to create an Xbasic script without just typing in Xbasic commands. When you create a new script, you can choose to go directly to the Code Editor or use the Action Scripting Editor.

The Action Scripting Editor presents you with Categories and Actions for a myriad of Alpha Anywhere commands. As you select the actions you want performed Alpha Anywhere prompts you for parameters and then automatically creates the Xbasic commands to perform your requested actions.

Once a script has been created using Action Scripting, you can choose to convert the Action Script actions to Xbasic code. Once the code has been converted, you can use the Code Editor to modify the code in any way you wish.

Action Scripting is covered in more detail later in this book and in more depth in the book Introduction to Action Scripting that comes with Alpha Anywhere.

In Figure 11 you can see the choices available to you when you create a new script. In this case, we clicked on the Code tab in the Control Panel and then clicked the New button.

Figure 11

The icon for creating a script using the Xbasic Code Editor is a page of Xbasic code. The icon for creating a script using Action Scripting is a sequence of colored symbols that represent the actions you can automatically specify to run in sequence in your script.

In the listing of scripts and other items in the Code tab of the Control Panel, all scripts are represented by the colored symbols icon whichever way they were originally created.

We will be exploring script creation using both the Xbasic Code Editor and the Action Scripting Genies in exercises to come. But first, lets talk about the other options that appear in the drop-down menu shown in Figure 11, in particular the Interactive window.

  • New Script 

    This icon represents a new script created using the Xbasic Code Editor.

  • New Action Script 

    This icon represents a new script created using the Action Scripting Editor.

  • New Function 

    This icon represents a new function (a special type of script) created using the Xbasic Code Editor (via the "Create New Function" command.)

Learning Xbasic "Interactively"

In Figure 11, you can see that one of the options on the drop-down menu when you select the New code button is the Interactive window. This window is a Code Editor like the one we used in Exercise 1 to open the Load Last Record script. In that exercise, we ran the script with the Run button. When the script ran, Alpha Anywhere performed all the Xbasic commands in the script in sequence (line-by-line) until the script ended. Of course, the script only had two lines of Xbasic code. But, the point is that the whole script is run at one time.

The Interactive window is different. The Interactive window will run each line of code as you enter it. A line of code is entered when you finish typing a single line and then press the Enter key. At that point, Alpha Anywhere checks the code to make sure it is valid. (If you make a spelling mistake or type an Xbasic command incorrectly you will see an error message). If it is valid, Alpha Anywhere executes the line of code right away.

For example, in Exercise 1 we looked at a script whose first line of code was:

Form.View("Administration")

This line of code will immediately open the Administration form when you enter it in the Interactive Window. You will try the Interactive window in the next exercise.

The Interactive window can be opened by:

  1. Choosing Interactive Window from the Control Panel menu bar.

  2. Choosing View > Code Editor from the Control Panel main menu.

  3. Choosing Interactive Window from the menu after pressing the New button while in the Code tab of the Control Panel.

Exercise 2 - Using the Interactive window 

  1. If the Phone Messages database is not still open from Exercise 1, open it now.

  2. Close the Administration form window if it is open.

  3. Open the Interactive window using one of the techniques described in the side bar.

    Figure 12
  4. Now type the following Xbasic command form.view("Administration") into the white text area. But do NOT press Enter yet. While you are typing, you will see Alpha Anywhere's bubble help appear. For now, just ignore the bubble help and type the entire command as shown in Figure 12.

  5. When you have entered the command exactly as above, press the Enter key.

    Alpha Anywhere executes the command and the Administration form displays in View mode. The window you closed in Step 2 is re-opened interactively.

  6. Right-Click on the Administration window tab on the window bar at the bottom of the screen and choose the Close command.

    The form view closes and the Interactive Code Editor is reloaded.

  7. Now locate the Clear Interactive Window button on the Menu Bar (see Figure 13) and press it. The Interactive windows contents are erased.

    Figure 13

    Bubble Help is a fantastic feature of Alpha Anywhere that helps you to complete entering commands by letting you select entries from lists of Xbasic commands and lists of appropriate parameters.

    We will learn more about bubble help below.

  8. Type: 2+3 and press Enter.

    • Nothing seems to have happened. The cursor moved to the next line, but did anything else happen? Actually the answer is yes. Each time you enter an expression, Alpha Anywhere checks to see if it is valid. In this case, you entered a perfectly valid arithmetic expression. And Alpha Anywhere even calculated the answer. However this particular command does not trigger anything to display on the screen When you entered the Form.View("...") command above, Alpha Anywhere did display the form, since that command by definition causes a form to be displayed.

      In order to see the output of this expression, you must precede it with a question mark (?).

    Figure 14
    The Clear Interactive Window button will clear the whole Interactive Window. The other two buttons next to it will clear, respectively, the window above your current line and the window below your current line. The current line is the line where your cursor is blinking.
  9. Type: ? 2+3 and press Enter.

    • Now Alpha Anywhere displays the answer on the next line. In fact, you can use the Interactive Window as a calculator by typing in any expression you like. Just remember to precede it with a question mark to see the answer.

    • Expressions 

      An expression is like an arithmetic formula. It is a sequence of Xbasic commands and operators (like +, -, *, etc.) that is syntactically valid. Syntactically valid means you have spelled everything correctly and included any characters (like a period) that is part of the command so that Alpha Anywhere understands the command you have entered.

      If you type an expression or command that is invalid you will get an error message.

      All standard arithmetic formulas are valid expressions. Alpha Anywhere knows what to do when you ask it to calculate 2 + 3 or ((200 * 320) / 15).

      However, just because a command is syntactically correct does not mean it will work correctly. When you typed the command:

      Form.View("Administration")
    • Alpha Anywhere found a form named Administration and performed the command. If you had typed:

      Form.View("Administrate")
    • Alpha Anywhere would attempt to perform the command because it is syntactically correct. But, since there is no form in the Phone Messages database named Administrate, Alpha Anywhere would show (in the Interactive window) this error message:

      ERROR: Form not found:Administrate
    Figure 15

Programming Concepts

Programming with Xbasic means you must understand the definitions and characteristics of some specific terms and concepts. You have already seen what an Xbasic command is. And you have been introduced to some simple arithmetic expressions, which are valid Xbasic commands themselves.

command 

Another term for an Xbasic command is an instruction. The command instructs Alpha Anywhere on what to do next.

Variable 

A variable is a storage area or location in your computer's memory. You may be familiar with memory locations in most calculators. They are often labeled M1, M2, and M3 and they enable you to store intermediate results that you can then recall and use in further calculations later.

A variable is a location in memory that Alpha Anywhere uses to store and recall data values. Variables are named by you. Consult Declaring a Variable for variable naming rules.

Some valid variable names are:

my_last_contact sum1 interest_paid_on x warranty_in_effect

Different variables can store different types of data. So the variables above may hold these kinds of data. Other variable types are Blob, Time, Pointer (Object Reference), Image, and Function.

An Xbasic variable is like those calculator memory areas. However, there are important differences. In Alpha Anywhere you can define as many variables as you need, within the limits of your computers memory capacity, and you decide on the name of the variables yourself.

In addition, a variable can store different types of information. In a calculator, all the values stored in a memory location are numbers. In Alpha Anywhere, you can create variables to hold character, date, logical, and pointer values, among others, as well.

Variables are similar to fields in a database table. Both of them are storage areas for data. And both of them store data of a certain type. Variables, however, only hold their data while Alpha Anywhere is running. When your application closes, any variable values used in that application are discarded. The variable placeholder is still there, but any values stored in that variable are not. However, you can explicitly use Xbasic commands to save variable data values to a file and restore those values during another session, if necessary.

But variables are primarily used to store data that is used during an applications processing, but do not need to be kept in permanent storage. For example, you may add a variable to a form which is used to search your database. When the form is loaded, your user enters the data they are searching for into the variable. That data is used to locate the appropriate record. When the form is closed, the variable is also closed and any value (the last data searched for) in the variable is discarded.

Exercise 3 - Defining and using variables in the Interactive Window 

  1. Type in the Interactive window:

    my_sum = 2+3
    • When you press Enter, Alpha Anywhere moves the cursor to the next line but nothing prints.

      Instead you created a variable named my_sum that is assigned (or stores) the sum of the right hand side of the expression (2+3). (The right hand side of the expression refers to the part of the line to the right of the equals (=) sign.)

      Alpha Anywhere verifies that the command you typed is valid.

  2. Now type:

    my_sum = 2+3
    ? my_sum
    • When you type ? my_sum and press Enter, Alpha Anywhere displays the value stored in the my_sum variable. This value is 5.

      Figure 16
  3. Now type:

    my_sum = 10 + 15
    ? my_sum
    • Now Alpha Anywhere displays this, Figure 17:

      Figure 17
    • The value stored in the my_sum variable has changed. Now my_sum holds the value 25.

  4. Now type:

    my_sum = my_sum + 100
    • Can you guess what the value stored in my_sum is now? If you think its 125, you are right!

  5. To check, type:

    ? my_sum
    • Alpha Anywhere Xbasic expressions are evaluated from right to left. This means that when Alpha Anywhere evaluates the expression you typed in step 3, the right hand side of the expression is calculated first. At this moment, while the right hand side of the expression is being evaluated, my_sum holds the value you gave it in step 2 (i.e., 25). So Alpha Anywhere adds 25 plus 100. Now Alpha Anywhere proceeds with the rest of the expression which says to assign (store) the value from the right side of the expression to the variable my_sum. So my_sum' s value (25) is replaced with the new value (125). Now the my_sum variable stores the value 125.

      Variables are so-named because the data they hold (store) can change or vary. In this step, you changed the value stored in the variable my_sum from 5 to 25.
    • Can you guess the type of the variable my_sum ?

      A variable's type refers to the kind of data that a variable can store.
    • In Step 1, you assigned a sum to a new variable named my_sum. You assigned a numeric sum (yes, there are other kinds) to my_sum. So, implicitly, you told Alpha Anywhere what kind of data the new variable will store by the type of data that you first put in that variable. This kind of variable definition is called an implicit declaration of a variables type. Alpha Anywhere figures out the variables type from the type of the data you initially put in the variable. There is also a method of explicit ly defining a variables type which we will see below.

      An implicit declaration of a variable's type is done by assigning a value to that variable. Whatever kind of value is assigned becomes that variable's type. An explicit declaration is done with an Xbasic command named DIM which we will see below.
    • Once a variable has been typed (and a variable is always typed either implicitly or explicitly when you create it), then you can only assign future values of the same type to that variable.

  6. If you type this in the Interactive window:

    ? my_sum = "Jay Leno"
    • Alpha Anywhere displays an error message: "Jay Leno not found". You tried to assign a character type value to a variable that can only hold a numeric type value. The types of the value and the variable do not match and Alpha Anywhere reports an error. In addition, the my_sum variable now holds 0. When Alpha Anywhere found that it could not store a character value into my_sum, it cleared any previous value.

      Figure 18

The Xbasic TYPEOF() function provides an easy way to determine the type of a variable.

A function is a special type of Xbasic command. A function calculates or transforms information and returns a value. Typically, a function will take some information in (as parameters), manipulate that information in some way and then return a result or final value.

For example, there is an Xbasic function DMY(date) that returns a formatted date. The formal definition of this function (found in the Xbasic Reference manual) is:

Character String = DMY(Date)

This means you supply DMY with a date value the Date input parameter and it will return a character string. If you type:

? DMY ({08/01/2002})

in the Interactive Window, the DMY function will return (and Alpha Anywhere will display) the value:

01 August 2002
When you type in dates in Xbasic, you enclose the date in curly braces {}, so Alpha Anywhere knows you mean a date value and not a numeric expression.

In the Interactive window type:

? typeof(my_sum)

Alpha Anywhere displays:

="N"

which indicates the type of the my_sum variable is numeric.

It is not possible to change the type of a variable once it has been established. You can however delete the variable from Alpha Anywhere's memory and then use the name again and create a new variable with a different type.

Variable Types

Why is a variables type important? Primarily because Alpha Anywhere has to know what kind of information you are referring to when you use a variable.

For example, suppose you have an application in which you ask someone to enter the date a bill comes due. And you want to display on a form the number of days remaining from todays date until that due date. You can create a variable, lets call it due_Date, on the form and define it as a date variable. Now Alpha Anywhere knows that the information your user will enter in this variable must be a valid date.

Also, since due_Date is a date value, you can create an expression like this:

due_Date = date()

to calculate the number of days between todays date (the date the application is run) and the due_Date. In this expression, an Xbasic function named DATE() returns a date value of todays (the present) date. (So on December 31, 2002, date will return {12/31/2002}.) When a minus sign is used with two date values, Alpha Anywhere knows to calculate the number of days between those two dates. And Alpha Anywhere knows due_Date holds a date value because you defined it that way.

Exercise 4: Using a date variable in an expression (with an Xbasic function) 

  1. Type the following in the Interactive Window: (Be sure to use the curly braces).

    due_Date = {08-24-04}
    This defines due_Date as a date type variable and assigns it the value of August 24, 2004.
  2. Now type:

    ? due_Date
    Alpha Anywhere displays the date value currently stored in due_Date.
  3. Next type:

    ? Typeof(due_Date)
    Alpha Anywhere displays the type of the due_Date variable as D (signifying date type).
  4. Next type:

    ? date()
    On the date this was written, date() returned {10/06/2003}, so you see that the date() function returns a value of type date.
  5. Finally, type:

    ? due_Date - date()

When this was written, Alpha Anywhere calculated and displayed that 323 days remained between October 6, 2003 and the due date of August 24, 2004. Figure 19 shows the sequence of commands and resulting output. Picture

Figure 19

Naming Variables 

When you choose names for a variable, it is a good idea to pick a name that identifies its type and what information the variable will store. So, if you need a variable to count the number of matches in a search request, you might choose a name like: items_Found.

Some programmers make it a practice to include a letter signifying the variables type at the beginning. So they might name the variable above as: n_items_Found.

To signify that n_items_Found holds a numeric value. Some people will capitalize every word in a variable name, others like to leave the first word uncapitalized and only capitalize the rest. It makes sense to pick a system that will help you quickly remember what a variable is for when you read your program at a later time.

Explicit Declaration of Variables

Up to now, all the variables you have worked with have been declared implicitly. You created variables in the Interactive Window by simply specifying a valid variable name and then assigning it a data value. The type of the data you assigned to the variable determined its type.

DIM 

There is an Xbasic command that can be used to define a variable and to specify its type. The command is DIM. When you use DIM, you define a variables name and the type of data it can hold.

DIM comes from the word dimension. When you define a variable, it is referred to as dimming or dimensioning the variable. When you DIM a variable you are setting its dimensions.

For example, the following lines of Xbasic define four different variables. Defining the variables with the DIM command tells Alpha Anywhere to setup storage locations with the names and to expect those variables to store data of the type specified.

DIM first_Name as C
DIM age as N
DIM date_of_birth as D
DIM married as L

Once a variable has been defined with the DIM command, it is available for use in subsequent Xbasic commands. So after issuing the commands above, you could then have two commands like this:

date_of_birth = {11/21/1974}
age = int((date()- date_of_birth)/365.25)

How the Expressions are Evaluated 

int((date()- date_of_birth)/365.25)

Alpha Anywhere evaluates (calculates) this expression as follows. It uses these two rules.

  1. Evaluate sub expressions (parts of the expression enclosed in parentheses) from the innermost set outward

  2. 2. Evaluate the expression from right to left.

First Alpha Anywhere evaluates the sub-expression:

(date()- date_of_birth)

Alpha Anywhere substitutes the appropriate date (the current date is returned by the date() function and whatever data is stored in the date_of_birth variable. This is the number of days that have passed since the birth date. Lets say date() returns {06/15/2002} and the date_of_birth variable is equal to {11/21/1974}

Then the sub-expression equals

({06/15/2002} - {11/21/1974}) or 10068

Now the expression is

int(10068/365.25)

Applying the parentheses rule, Alpha Anywhere calculates 100068 divided by 365.25, which equals 27.564682

Finally, the expression is now:

int(27.564682)

The int() Xbasic function takes a numeric value and returns the integer portion (dropping any decimal value). So the final result of the expression is:

27

This value is assigned to the age variable.

You do not have to use DIM to define variables as we have already seen. In fact, you can also use DIM to name a new variable without specifying its data type. The data type is determined only after you assign data to that variable. So you could type the following two commands:

DIM age
age = "Eighteen"

The DIM command tells Alpha Anywhere to set aside storage for a variable named age. But only after the second command is processed does Alpha Anywhere know to treat age as a character data type variable.

Once a variable has been assigned a value or dimmed, it can only store data of that type. If you want to change the type of data that a variable can hold, you can use the REDIM command to redefine it.

If any data is stored in the variable before you REDIM it, that data will be discarded

Exercise 5 - Dimensioning and using variables 

Using DIM to define a variable is also known as Declaring a variable. Declaring variables with DIM at the beginning of a code file is good programming practice. It makes your variables and their types explicitly known and readily apparent for someone reading your code later.

  1. Declare the following variable using the DIM command.

    DIM birthday as D
  2. Use the typeof() function to check the data type of the variable birthday.

    ? typeof(birthday)
    • Alpha Anywhere displays D indicating a type of date.

  3. Assign your birthday to the variable birthday (enter your own birthday or use this date).

    birthday = {11/21/1974}
  4. Now type:

    ? Int((date()- birthday)/365.25)
    • Alpha Anywhere displays your age.

  5. Now type the following:

    birthday = "Twenty-seven"
    • Inside a script, Alpha Anywhere would display an error. In this environment, it sets the value of birthday to NULL.

      ? birthday = { / / }

Type conversion 

Sometimes you may want to get data of one type out of a variable and store it in a variable that holds data of a different type. For example, suppose you have a variable defined as a character variable storing a products weight.

product_Weight = 42 ' lbs

You want to multiply the weight in pounds by $ .75 per pound to calculate a shipping price.

You can use a type conversion function to get the numeric information from the product_Weight variable and store it in a numeric variable. The function that converts from a character string value to a numeric value is called VAL(). When VAL() is used on a character value, it looks for any numbers occurring at the beginning of the string, drops remaining characters, and then converts the number string (the number stored as Characters) to a numeric value. So

VAL(product_Weight)

returns the numeric value 42.

If you had a numeric variable named ship_Cost you could write this expression:

ship_Cost = VAL(product_Weight) * .75

to store a numeric shipping cost in the ship_Cost variable.

Objects, Properties, and Methods

This topic explains, with a detailed example, objects, properties, and methods. If you are comfortable with these terms, you can skip this section.

Objects 

An object is simply a definition.

When you refer to a particular object in Alpha Anywhere, you are defining that particular object as belonging to a category of objects that have similar characteristics that you can edit and that react to actions that you can create and control.

You can specify the appearance or display of an object by manipulating its characteristics and you can determine how an object reacts to user input by writing Xbasic scripts that control what happens when an object does something or is accessed by a user.

For example, you can think of a car as an object. You may own two cars which have similar properties and actions, but, of course, behave differently according to what those properties and actions are.

Lets say your two cars are:

  • Car1: Ford Focus
  • Car2: Masserati

Now, both of these are objects are particular objects of a certain type. They are cars. Since they are both cars you know, by definition, that they share certain characteristics.

For example, a few of their shared characteristics are:

  • name
  • color
  • gas_Accepted
  • top Speed
  • current_Speed
  • passenger_Capacity

Characteristics of objects are referred to as properties. The properties of your two car objects have values appropriate to their own characteristics. Some property values are shown below for the two cars.

Object Type: Car 

Objects 1 and 2 are both objects of type car and they both have the same collection of properties (as would all objects that are defined as Cars), though its the values of those properties that distinguish one object of the same type from another.

Objects of the same type also share actions or methods. These are things the objects do, rather than what the objects are.

In this example, all cars (or, in other words, all objects of type car) perform certain actions. These are:

Action (Method) Name
What happens
accelerate(pressure)

Speed up when the gas pedal is pushed up until top speed. Also, display the current speed on the dashboard.

brake(pressure)

Slow down when the brake pedal is pushed.

turn(direction, degree)

Turn the wheels according to the direction and degree indicated by the steering wheel.

Beep(pressure)

Make a noise when the horn is pressed.

monitor_Tank()

(Ford Focus) Flash a dashboard warning light when the gas tank is less than 2 gallons full. (Masserati) Flash a dashboard warning light when the gas tank is less than 10 gallons full.

As you can see, what happens for each action is sometimes determined by an input from the driver. The car objects acceleration action is affected by the drivers pressure on the gas pedal. This action also determines what value is stored in the current_Speed property. (I.e., methods can set the values of properties of objects). And the accelerate method uses the top_Speed property setting to limit how fast the car can go.

Other actions happen automatically without any driver input. The dashboard flashes when the gas drops below a certain level without any input from the driver as the monitor_Tank() action is continually performed for a car object. Make note of this - both car objects have the same methods. One, named monitor_Tank(), however, does a slightly different action relevant to its particular object. In fact, in Alpha Anywhere the names of the methods for an object are already determined. But we can control what actually happens when that method performs its action.

In other words, objects that are built-in to Alpha Anywhere (like a form or table) have a predetermined set of methods, but you can control what actually happens when those methods are run using Xbasic.

In summary, a car object is fully defined by these properties and methods:

Objects - Learning Xbasic

So far you have learned about Xbasic variables and been introduced to using functions and expressions in Xbasic commands. Another important concept for understanding how to write Xbasic commands is an object.

All the parts of your applications written in Alpha Anywhere are objects or distinct entities. An object is a part of Alpha Anywhere that has properties (or characteristics) and methods (or scripts that do something to or with an object).

For example, tables, databases, forms, browses, reports, scripts, and even the Alpha Anywhere program itself are all objects.

You may have noticed that properties of an object are like variables. They are storage locations that hold variable data values. They are, in fact, variables that belong to and describe a specific object. In the same way, methods are like scripts. Methods are pre-named scripts that execute certain actions.

Alpha Anywhere Forms and Browses are some of the objects that you will use in Alpha Anywhere. So they have properties and methods like any other object. Setting the properties and defining the Xbasic commands that are executed by the methods are the primary means of creating a custom application in Alpha Anywhere. Now, you will look a little closer at an Alpha Anywhere object a form. You will look at the properties and methods used to build the first form of the Phone Messages application that is included in the sample databases with Alpha Anywhere. The initial form when the Phone Messages application is started is the Sign In form shown in Figure 20.

Figure 20

When the Please Login button is clicked on the Sign In form, another window appears with a prompt to enter a user ID and password as shown in Figure 21:

Figure 21

The "Please Login" window shown in Figure 21 is not a form object, but a window created by an Xbasic Xdialog command.

Xdialog is a set of Xbasic commands that you can use to create pop-up windows to interact with users by displaying data or prompting users for information.

The Xdialog component of the Xbasic language is covered in detail in the Learning Xdialog book that is part of the Alpha Anywhere documentation set.

After a successful login, the form then appears as shown in Figure 22. You can see in comparing Figures 20 and 22 that the information that appears on the form changes depending on the users interaction with the form. And the pop-up window in Figure 21 appears only after the Please Login button on the form in Figure 20 is clicked.

Figure 22

All of the changes and sequence of actions that occur as this form changes are happening because either the properties of the form object are being changed or methods of the form object are being invoked (run).

In fact, many of the changes to the form shown in Figure 20 and Figure 22 are the result of changes to the properties and methods of sub-objects on the form object.

  • Sub-Objects 

    A sub-object is an object that is part of another object. An object, by definition, always has a collection of properties and methods that determine the characteristics and capabilities of that object.

    If you read the previous sidebar that used a car as an example of an object, you can think of an engine as an example of a sub-object that is part of a car object. The engine is an object itself (as are all sub-objects) and has its own properties and methods.

    For example, an engine might have a property named cylinders. And it might have a method named "Increase RPM (revolutions per minute)." Now an engine object can exist on its own. It does not have to be part of a car to have its own properties and methods. (Of course, you can't do much with an auto engine that's not in a car.) But, an engine object can also become part of a car object definition. When we define a car object by defining its properties and methods, we can also define sub-objects that are part of that car object. So our car object specification can be expanded to include a sub-object of type Engine as shown below. A partial Engine object specification is also shown.

  • An engine object exists within the car object. A method of a parent object may invoke a method of a sub-object (or child object). For example, car.accelerate(50) causes the engine.increase RPM(1000) method to execute.

Another term for a sub-object is child object. And, as you might expect, an object that includes or incorporates child objects is sometimes referred to as a parent object.

The Sign In form in Figures 20 and 22 is an object. It is a form object. (also referred to as an object of type form). All form objects have, by definition, the same set of properties and methods.

The way you set the characteristics of a particular forms properties and methods determines that forms appearance and functionality. This form also has numerous sub-objects. In fact, all the elements or controls that you place on a form using the Alpha Anywhere Form Design commands toolbox are objects. For example, the Sign In form in Figure 22 has a design element that is a bitmap (graphic) object. The picture of the friendly smiling message taker is a sub-object of the form itself. All of the buttons, text elements, variables and frames used in this form (the forms controls) are objects themselves (and thus sub-objects of the form). And each of these objects has its own properties and methods.

Object Events - Learning Xbasic

An event is a special type of object property that does not contain a value but actually is an Xbasic script. The Xbasic code in an event script is run when different types of events occur in the course of an object being used. Events are pre-defined for Alpha Anywhere objects. That is, there are a fixed set of events defined for a particular object type. However, you control what happens when that event occurs through the Xbasic commands that you define in an event script.

To return to our car analogy, a car object might have the following events:

  • Turning On The Ignition
  • Turning Off the Ignition
  • Hitting Another Car (hope this event never happens!)

When any of these events occur, the car performs certain actions. When you Turn on the Ignition, the car might perform all of these tasks:

Start the engine
If the engine wont start, light up a dashboard light.
Check the miles driven.
If the miles driven is over 100,000 then
    Check the service engine switch.
    If the service engine switch has been set (meaning the engine has been serviced)  then
        Do nothing.
    else if the service engine switch has not been set then
        Light up a Check Engine light on the dashboard
Check all the fluid levels
If a fluid level is too low then
    light up a warning light on the dashboard

All of these five steps are executed when the Turn on the ignition event occurs. When you buy a car, all the events that the car reacts to and what happens when each event occurs is already built-in to your car by the car company. With objects in Alpha Anywhere, there is a big difference. Even though the events are pre-defined for a given object, you control what happens when a particular event occurs by telling Alpha Anywhere what Xbasic commands to execute for that event.

For example, when Alpha Anywhere displays a form object, it checks to see if any events that a form object can react to (e.g., a key press or fetching a data record) have occurred. Every object has a list of events that it can react to. But you determine what happens when that event occurs. An event is a pre-named like a form property, but what happens when that event occurs is up to you. In order for an event to cause something to happen, a script of Xbasic code must be written for that event.

For example, every form has an OnActivate event (or property ) associated with its object definition. A form is activated after it is opened when it receives focus. (Focus means that the form is currently the primary object that Alpha Anywhere is dealing with.) So when a form has focus, keyboard input is directed to that form (or to a sub-object of that form). When a form object is activated, Alpha Anywhere checks the OnActivate event. If Xbasic code has been written for the OnActivate event for that form, Alpha Anywhere runs that code. If no code has been written for that particular forms OnActivate event, then Alpha Anywhere moves on without doing anything extra even though an OnActivate event has occurred.

In the next section and exercise, you will examine the Sign In form's properties and events in more detail.

Exercise 6 - Examining a form object's properties, events and sub-objects 

  1. Open the Phone Messages database.

  2. Open the Sign In form in Design mode.

  3. From the Form menu, select Form Properties as shown in Figure 23 below.

    Figure 23
  4. Click the Backdrop tab and then click on the dropdown list for the Color: property.

    • Remember, there are multiple ways to navigate around Alpha Anywhere. You can also open the Form Properties window by:

      • right-clicking on the form object and selecting Properties... from the menu or

      • you can select the Object menu and then Properties or

      • you can click on the Properties button on the toolbar or

      • you can press the F12 key

    Figure 24
  5. Change the Color property to something other than "Rose".

  6. Click on the OK button in the Form Properties window. The background color of the form should change to the color you selected.

  7. Reopen the Form Properties window and change the background color back to "Rose".

  8. Click OK to close the Form Properties window.

  9. Now select Events from the Form menu. A list of all the events for this object type (form) appears as shown in Figure 25. Figure 25:

    Figure 25

    Two of the events for this form are displayed in bold and with a checkmark next to their name. Event names are displayed like this when Xbasic code has been created for that event.

    The OnInit event code (which you will see later in this exercise) is executed when the form is initially loaded.

    The OnActivate event code is executed when the form get focus.

    Any other events for this form would not result in any special actions since no Xbasic code has been defined for those events.

    All Alpha Anywhere form layout objects that you create have this same set of available events for you to customize actions for.

  10. Move your cursor onto the OnActivate event and select it (left-click the mouse). The Code Editor loads and displays the script that was defined for the OnActivate event as shown in Figure 26 below:

    • Figure 26
    • Code Editor 

      The Code Editor knows what kind of Xbasic script you are creating automatically, whether it is a standard script, an event script or a function.

      Note the toolbar for the Code Editor allows you to select the type of script, object and object events from drop-down lists, and the tab for the script in the editor displays the object event reference:

      :Sign_In.OnActivate
    • You will learn more about object references (or addresses) later in this book.

    • This is a very simple Xbasic script. There is only one Xbasic command:

      :Sign_In.maximize()
    • This command (you will learn more about the syntax of this command later) causes the Sign In form to be maximized in the Alpha Anywhere window when the Sign In form is activated.

  11. Close the Code Editor window (click the in the top right corner). The Sign In form in Design mode is displayed as in Figure 27.

    Compare Figure 27 to Figures 20 and 22. You should notice that some of the sub-objects that are clearly part of the Sign In form in Design mode (in Figure 27) are not displayed on the form in View mode in Figure 20 and others are not displayed on the form in View mode as in Figure 22.

    • Figure 27
    • In fact, one sub-object is not displayed in either Figure 20 or 22. (This sub-object is the field control that holds the variable user_id ). The display of these sub-objects is controlled by the hide property of each object. When the hide property is checked (or True) for a particular object, that object is not displayed. By changing the hide property value between checked and cleared (or True and False) using Xbasic, you can control which sub-objects are visible on a form.

    • There are two objects on the Sign In form that overlap. One object is a text control and the other is a button control. Each of these objects has a property (hide) that controls when each object is visible on the form.

      When the form is initially loaded (as in figure 20) the button object, Please Login, is visible and the text control. Welcome, Username, is not shown (because its hide property is set to True).

      After a successful logon (as shown in figure 22), the buttons hide property has been set to True and the text controls hide property has changed to False.

      So even though both these objects are present (i.e., they are sub-objects) on the Sign In form, whether or not they display when the form is in View mode is controlled by their object properties.

Different Types of Objects in Alpha Anywhere

If you have explored an Alpha Anywhere object of type form, you will have seen that a form object has certain properties, methods, and events that characterize the behavior of a particular instance of a form. For example, with a 'Sign In' form, when you change the value of the Sign In form's background color property, the appearance of the Sign In object changes. Alpha Anywhere forms have events that can be defined with Xbasic scripts. When an event happens, Alpha Anywhere performs the Xbasic commands in that event's script.

Keep in mind that Alpha Anywhere includes many different types of objects. All of these objects are components of Alpha Anywhere. Objects include: data tables, forms, browses, controls, the Alpha Anywhere program itself, the Code Editor, the Control Panel, etc. All of these objects have properties and methods.

Some types of objects respond to events if you write an Xbasic script for those events. System objects are objects that are always present in Alpha Anywhere, whether you are using the software interactively or with a pre-built application. In fact, many of the objects listed above are system objects; for example the Control Panel, Status Bar, Form, Browse, Set, and Table objects, as well as the Alpha Anywhere program itself.

Objects that you create instances of (i.e implementations of that object's type) are based on the Table, Set, Operations, or any of the various Layout objects. For example, if you create a new workspace and define a new table named 'clients', Alpha Anywhere will then create a table type object named 'clients' with the same available characteristics (properties and methods) as the system Table object. Likewise, when a 'Sign In' form is created for an application, that object is based on the system form layout object. The technical term for creating your own object from an object type is called instantiating that object. The 'Sign In' form layout object is an instantiation of the form layout object type. You can create tables and sets, browses, forms, reports, labels, and letters and operation type objects in Alpha Anywhere. Alpha Anywhere also instantiates certain system objects itself, but you cannot create additional objects of that type yourself. (For example, you cannot create additional Control Panel objects). But you can manipulate the Control Panel system object through its properties and methods. In sum,

  • System Object 

    A system object is an object that is built-in to Alpha Anywhere. You can't create new objects that have the same characteristics as system objects.

    But system objects (which allow you to control the behavior of the Alpha Anywhere program) can be referenced and controlled (for example opened and closed through Xbasic scripts.

    For example, in exercise 6, the Code Editor that you opened to view the Xbasic commands of the OnActivate event is a system object. There is only one "instance" of an Alpha Anywhere system object. The Code Editor is the instantiation (or instance) of the Code Editor system object.

  • Instance 

    An instance of an object is an occurrence or implementation of that object type. A Rolls-Royce Cloud is an instance of a car object. The Sign In form is an instance of a form layout object.

  • Class 

    A specific object type is also known as a class or category of objects. So a particular form layout object can be spoken about as belonging to the form layout class of objects.

Most of the objects that you will use in Xbasic scripts will be layout and table objects (or simply layouts and tables). In order to change an object's property or invoke an object method in an Alpha Anywhere Xbasic script you must know how to reference that object using object addressing.

Object Addresses - Learning Xbasic

Object addresses are basically object names. You can refer to an object in an Xbasic script by using the object name. Earlier in this book, you saw that when you use a command from the Alpha Anywhere menus, Alpha Anywhere is in fact executing Xbasic commands to carry out your request. So if you open the Phone Messages database, and highlight the Sign In form in the Form tab of the Control Panel, and then click Form > View from the Main Menu, the Sign In form will load. When you click on Form, View, Alpha Anywhere executes these three Xbasic commands:

Form.View("Sign In@e:\program files\a5v5\learning Xbasic\message_tr.dbf")
:Sign_In.resynch()
:Sign_In.activate()

These commands, in turn, invoke the View method of the Form layout system object (with a form layout name as the parameter) and then the instance of the Sign In form object. The diagram below explains the components of the first and third command lines. The first command line breaks down as follows:

Some general rules for object addressing can be learned from these examples.

  • System objects are referenced by their own names; for example: "ControlPanel", "Form", "CodeEditor".

  • Other objects are referenced by their given names (with spaces replaced by underscores); for example: "Sign_in", "Monthly_Aging_Report", "QuickBrowse".

  • Objects names are followed by a period which, in turn, is followed by the property or method which you are referencing.

  • A colon (:) is used in front of an object name to unambiguously refer to an object that may be a sub-object of another object. (More about this below).

In this next exercise you will use the Alpha Anywhere Form, View commands and see in the script recorder the behind the scenes Xbasic commands that Alpha Anywhere generates.

Exercise 7 - Using the Script Recorder to see Alpha Anywhere Xbasic commands 

  1. Open the Phone Messages database.

  2. Click on the Form tab of the Control Panel.

  3. Highlight (click once on) the Sign In form. (Do not double click or the form will open. If it does, simply click on the in the top right corner of the window to close the form).

  4. From the Main Menu, select View, then Script Recorder Window as shown in Figure 28:

    Figure 28
  5. Now check the Record Script check box in the Script Recorder w indow. Alpha Anywhere will now record your menu selections as Xbasic script commands.

    Figure 29
  6. Now click on Window, then Control Panel. The Control Panel displays. The Sign In form layout name should still be highlighted on the Forms tab.

  7. Select Form, then View. The Sign In form appears.

  8. Now click the Please Login button. A pop-up logon window appears. Click the Cancel button.

  9. Click the Exit button on the form. (Do not click the X in the top right or Alpha Anywhere will close!)

  10. Click Window, then Script Recorder. You will see the following commands in the script recorder window.

    :Sign_In.resynch()
    :Sign_In.resynch()
    :Sign_In.activate()
    :Sign_In:BUTTON1.activate()
    :Sign_In:BUTTON3.activate()
    :Script_Recorder.activate()
    • You should recognize some of the references to objects and methods that are shown above. Note the fourth line. In this line the BUTTON1 object (a button control) is a sub-object (or child object) of the Sign_In form object. A colon separates the BUTTON1 object and the Sign_In object. The : makes the reference to an object explicit.

      References to sub-objects can also be relative. A relative reference (without a preceding :) causes Alpha Anywhere to search for that object in the current container. A container is simply an object that can contain other objects. (The Alpha Anywhere program itself is the topmost container any window objects you reference are in the top container).

      Referring to a sub-object with a relative reference makes it easier to change your code later on or use a sub-object, such as a control, among different forms without having to change the Xbasic object references in any scripts associated with that control.

  11. Click on the Close Recorder button in the Script Recorder toolbar to close it.

    • Explicit and relative references to sub-objects 

      Objects that contain other objects are also referred to as containers. When you identify a sub-object in an Xbasic script, Alpha Anywhere assumes that reference is to an object in the current container. This means that you do not have to specify the container name if you are referring to a sub-object within the same container.

      For example, consider a form object named Elapsed Seconds that has a button (a control named BUTTON1). When pushed, BUTTON1 resets a counter of elapsed seconds and displays the seconds in another control on the same form (a field control named FIELD1).

      The OnPush event script for BUTTON1 has an Xbasic command:

      field1.refresh()
    • This command, which runs the refresh method for the field control object, FIELD1, is referencing the FIELD1 control from the BUTTON1 control. Both FIELD1 and BUTTON1 are controls on the same form. They are both in the same container form layout object - Elapsed_Seconds.

      The Xbasic command above could have been written:

      :Elapsed_Seconds:field1.refresh()
    • However the :Elapsed_Seconds is not necessary since the current container is :Elapsed_Seconds. If you leave off :Elapsed_Seconds, you must leave off the : (colon) in front of FIELD1. If you start an object reference with a :, Alpha Anywhere looks for the object starting at the top level (Alpha Anywhere itself) and not in the current container.

Object Aliases

An explicit object reference includes the name of a parent object or the name of the object itself. If you use Xbasic code to invoke object methods with an explicit reference, then that code is limited to use with the named object. Alpha Anywhere provides object aliases to use in object references that make code transferable across objects without having to edit the code.

Some of these aliases are:

Alias
Description
this

The current object itself

parent

The container of the current object

parentform

Used in controls scripts to refer to the form that contains the controls

In the next exercise, you will examine a form with three controls and see how the form and control event scripts refer to each other using object references. You will also see how to use the ;Object Explorer; to let Alpha Anywhere automatically build object addresses for you as you edit a layout windows scripts.

  • Object Explorer 

    The Object Explorer is a tool available for use when you are editing a layout window object. The Object Explorer is launched from the View menu in a layout editor. The Object Explorer shows, for a give layout window object, all the sub-objects of that window (including the window itself) and a listing of all the characteristics of those objects. So you can see all the properties, events, and methods that exist for an object.

    Via the Object Explorer, you can edit the properties, see all the available methods, and invoke the Code Editor to create or edit event scripts. You can also highlight any object, property, event, or method and have the Object Explorer show you the correct absolute or relative reference to that object item.

    The Object Explorer window lets you identify, explore, modify, and reference objects that are part of open layout windows. So the Object Explorer can be used with Forms, Browses, Letters, Labels, etc. The Object Explorer has two main regions. In the Object Name all the objects that are part of the current open layout are listed in a tree layout (Sub or child objects, if any, are listed below each parent). The Property region lists all the properties for an object selected in the Object name region.

Exercise 8 - Examining Object Addresses Using the Object Explorer 

  1. Open the Phone Messages database.

  2. Display the Form tab of the Control Panel.

  3. Double-click on the Count Seconds form.

  4. Press Start and Stop a few times.

    This form works as follows. The form property, Timer interval in seconds is set to 1. This means that the OnTimer event executes every second while the form is running. The OnTimer event script increases the elpsdsecs variable by 1 each time it executes (which is every second according to the timer interval property setting). Button1 (Start) resets the elpsdsecs to 0, changes the Field1 control background color and refreshes the elpsdsecs variable value which is displayed by the Field1 control . Button2 (Stop) stops updating the field1 control and resets its background color. Lets look at the Xbasic scripts for these controls.

  5. Press the Design button on the toolbar to switch into Form Design mode.

  6. Select the View menu and select Object Explorer (near the bottom of the menu).

    The Object Explorer window opens.

    Figure 30
  7. Select the "Button1" object in the Object Name region of the Object Explorer.

    The Object Explorer shows all the objects for a given layout.

    • The properties for the highlighted object name appear in the Property region.

      You can see the properties for Button1 and compare them to the appearance of Button1 on the form. For example, the text property has a value of "Start", which is the label that appears on Button1. The alignment of the text is also aligned vertically and horizontally according to the "Center" setting for both the Align and Vertical_align properties. These properties were set when the Button1 button control object was created on the form. You are using the Object Explorer tool to 'explore' the characteristics of an existing object.

    • Let us look at the OnPush event script invoked when Button1 is pushed.

    Figure 31
  8. Right-click on Button1, the Start button (in the design mode window for the Count Seconds form, not in the Object Explorer !).

  9. Select Events, then OnPush. Alpha Anywhere loads the OnPush event script in the Code Editor.

    • This script resets the elpsdsecs variable to zero. Then it changes the fill color for the field1 text control object. Finally it sets the started variable to .T. or True. This variable is, in turn, checked in the OnTimer event script of the Count Seconds layout. The OnTimer event script executes every second (according to the property setting described in Step 4) and refreshes the display of seconds when the variable started is True.

      A single quote mark (') at the beginning of a line indicates that line is a comment.

    Figure 32
  10. Click the small , at the top-right corner of the Code Editor, to close it.

  11. Place your cursor on the background of the Count Seconds form and right-click.

  12. Select Events, then select the OnTimer event. The OnTimer event script is displayed in the Code Editor.

    if started then
        elpsdsecs = elpsdsecs + 1
        topparent:Field1.refresh()
    end if
    • This script checks to see if the variable started is True. If it is, then the variable elpsdsecs is increased by 1 and the new value is now stored in elpsdsecs. Next, the script refreshes the Field1 text control (which displays the variable elpsdsecs ).

      If started is False, then the OnTimer script does nothing.

  13. Click the left mouse button once anywhere in the line of the OnTimer event script that reads:

    Field1.refresh()
  14. Right-click the mouse and select Comment/Un-comment code, then select Comment out. This turns the Field1.refresh() line into a comment.

  15. From the main window menu, select View, then select Object Explorer. The Object Explorer is displayed.

  16. Select "Field1" in the Object Name region.

  17. Click the Copy to Clipboard button (at the bottom of the window).

  18. Select Object name - relative. This copies a relative object name reference to the clipboard. Now you can paste that object name reference directly into the script in place of the line you just commented out.

    Figure 33
    After you copy this object reference to the clipboard it becomes available for you to easily paste it into the script you are editing in the Code Editor as you will do in Step 20.
  19. Click on the end of commented out line:

    'topparent:Field.refresh()
    • and press Enter. You should have a blinking insertion point on the blank line after the commented out line and before the line that reads end if.

  20. Right-click the mouse and select Paste. Then press Tab once. The relative reference to the Field1 object is pasted into the script. (Alpha Anywhere automatically uses alias object references in relative reference addresses. So topparent:Field1 is equivalent to Field1.)

  21. Now position the cursor after Field1 and type:

    • .refresh()
    • to complete this command line.

  22. Click on the Save icon to save this event script and the changes you made.

  23. Close all the open windows.

Aliases 

Aliases are substitute names for Alpha Anywhere objects that allow you to use the object references as relative references instead of absolute references. The available aliases are:

  • this
  • parent
  • parentform
  • topparent

In this exercise, you use the Object Explorer to select the relative reference to the object Field1. This reference is relative to the object script you are working with which is the OnTimer event of the form object. When the OnTimer event script processes the line,

topparent:Field1.refresh()

Alpha Anywhere finds the Field1 object by starting at the top parent object (the Count_Seconds form object) and looking within the form for Field1. Since the top parent object is the form that contains the Field1 object the line,

Field1.refresh()

works just as well (and this is the original line you saw when you first opened the OnTimer event script). Using aliases is a clearer method to refer to objects and Alpha Anywhere will always include aliases in object references copied from Object Explorer.

Object Events Revisited

Earlier we looked at a list of a form's object's events while designing the Sign In form (see Figure 25). Events are associated with objects and different objects have different types of events. However, all objects of the same type have the same set of events. That means that all form objects have the same events.

An event is something that happens to an Alpha Anywhere object. In the previous exercise you saw that the Count Seconds form used the OnTimer event. When the timer interval property is set to a value greater than zero (say 1 second) Alpha Anywhere checks the OnTimer event whenever that interval passes (in this case every second) when the form is launched. Whatever Xbasic code has been defined for the OnTimer event is run. The OnTimer event is processed whenever the timer interval is active and it changes. Other form events are processed when the form is first opened, when the underlying record the form is synchronized with changes, and when you try to save or abandon changes to a form record.

Figure 34

The full list of an object's available events can be accessed in Design mode by right-clicking on the object and choosing events. The figure on the left shows the full list of events that can be programmed for the Count Seconds form.

There are numerous paths available in Alpha Anywhere to enable you to edit Xbasic scripts for an objects events. You can select the Event you wish to edit from the drop-down menu shown in Figure 34. Or you can go directly to the Code Editor, select New > Script (using Xbasic editor) and then select Layout Events.

Layout Events will not be an available option in the Code Editor unless you already have a layout open in design mode.

Then you can select the appropriate layout (if you have more than one layout open in design mode) and view all the objects in that layout that have events. Figure 35 below shows the Layout Events for the Count Seconds layout and the Count_Seconds form object itself in the Code Editor.

Figure 35

Once the Object has been selected, the appropriate events for that object are available from the Select Events button as shown below in figure 36.

Figure 36

And once youve selected an event, that event is loaded into the Xbasic Code Editor as shown below. This figure shows the result of selecting the OnTimer event.

Figure 37

The Count_Seconds layout contains seven objects. The form itself, two button control objects, two field control objects and two text control objects. Each of these objects has events. You can see the available events for each object using the same techniques as were just described for the form object above. However, Alpha Anywhere has a shortcut tool that enables you to quickly see and edit events directly while editing an object. This tool is the Pop-up Editor.

This list of events for the Count Seconds form above matches the available events you saw in Figure 25 for the Sign In form.

The available events are the same because both Count Seconds and Sign In are instances of the form layout object. All objects of the same type have the same set of available events.

Exercise 9 - Using the Pop-up Editor to view/edit Object Events 

  1. Open the Phone Messages database.

  2. Display the Form tab of the Control Panel.

  3. Open the Count Seconds form in Design mode.

  4. Click once on the Field1 object. (That is the square with the word elpsdsecs printed across it).

    You will use the Object Explorer to quickly select the appropriate object property value for use in this event's script.

  5. From the View menu, select Object Explorer. The Object Explorer window opens.

  6. Click Current Object.

  7. In the Property box, expand the "Font" node by clicking the + plus sign.

  8. Select the "Color" property. In step 14, when you click on the Copy to Clipboard button, you will see a list of object and property references listed.

  9. Press the Copy to Clipboard button and select Property name relative. You will use the Object Explorer to quickly select the appropriate object property value for use in this event's script.

  10. Close the Object Explorer with the Close button.

  11. Press the F11 key. (Alternatively, you can load the Pop-up Editor by selecting Object > Pop-up Event Editor.) The Pop-up Editor window opens. None of the events have been defined for this object yet. Events that have been defined are shown in bold.

    You can see all the available events for Field1.

    Compare these events to those you saw previously for the Count_Seconds form object in Figure 36. Now, instead of looking at a form layout objects events, you are looking at the events for a field control object.

    The OnFlyover event is triggered when you move the cursor over an object on a layout that you are viewing. You are working on Xbasic commands that will run when you move the cursor over any part of the field1 object when the Count Seconds form is displayed. Likewise, the OnFlyoverLeave event triggers when you move the cursor off an object. You will create code for both the OnFlyover and OnFlyoverLeave events in this lesson.

  12. Select the "OnFlyover" event.

  13. Select the Xbasic Editor as the script creation method. A script editor window loads in the right region of the window.

  14. Click in the script box. The event editor is shown in Figure 38 below.

    The insertion point should be blinking in the script box. Now you can type Xbasic commands as you would for any Xbasic script. Since this is an Event script that you are creating, this script will run when the OnFlyover event is triggered for this object.

    From Exercise 8, you know that this form displays an elapsed count of seconds when you press the Start button. The seconds are displayed in bright green. You are going to insert Xbasic code in this script to change the seconds display color to blue whenever you move the cursor over the Field1 object.

    Figure 38
  15. Right-click in the script box and chose Paste. You should see the code in the script editor box as in figure 39.

    Figure 39
  16. Move the cursor to the end of the line and type the following:

    • = "blue"
    • The complete line of code should read:

      topparent:Field1.Font.Color = "blue"
  17. Highlight the entire line and then right-click and select Copy.

  18. Press the Save button to save this event script.

  19. Click on the "OnFlyoverLeave" event in the Select region at the left.

  20. Right-click in the script box and select Paste.

  21. Change the text "blue" to "bright green".

  22. Press the Save button to save this event script.

  23. Press the Close button to close the Pop-up Editor window.

  24. Press the Form View button on the layout design toolbar.

  25. Press the Start button.

  26. While the form is running (and the elapsed seconds are displaying), move the cursor (using your mouse) on and off the Field1 object square.

    As you move the cursor over (as the cursor flies over) the Field1 object, the seconds display changes to blue. When you move the cursor outside the Field1 object, the display changes back to bright green.

  27. Press the Design Mode button to switch back to layout design.

  28. Select View > Code Explorer. This will load the Code Explorer window.

    The next two steps will remove the Flyover events and set the state of the form back to where it was before you began this exercise. If you do not want to do this, skip to Step 33.

  29. Press the Clear All Flyover Events button on the Code Explorer.

  30. Select Yes to confirm the deletion of these events.

    The code in the Field1.OnFlyover and Field1.OnFlyoverLeave events is cleared. The events are automatically removed from the box listing objects with existing events in the Code Explorer window.

  31. Press Close to close the Code Explorer.

  32. Close all other windows.

Review of object aliases 

If you remember the discussion on alias object references, you'll understand that Alpha Anywhere will look for this object (and its property) by starting with the top parent object of this Event. This OnFlyover event is part of the Field1 field object. The top parent of this event is the layout object that it is a part of. So Alpha Anywhere will start at the Count Seconds object (indicated by topparent ), then look for the Field1 object (indicated by :Field1 ), then look at the Font property (indicated by .Font ) and finally, the "Color" sub-property (indicated by .Color ).

The full alias reference from the top parent form is not necessary here. You can achieve the same thing by using the following code:

This.Font.Color = "blue"

Alpha Anywhere will interpret the alias This to refer to the object that this event is attached to (or Field1 ).

After you have saved some code for an event, Alpha Anywhere displays the event name in bold. Alpha Anywhere ignores events without code when those events are encountered during the course of an Alpha Anywhere program executing.

The Code Explorer provides a quick way to see and edit all objects that have events defined in a particular layout. Within the Code Explorer, you can filter and view the same event types across all objects.

The Code Explorer allows you to examine an events Xbasic commands in the right region, but you cannot edit code in that window. You must click on Edit Code and launch the Code Editor to alter an events code. You can, however, use the Clear All Flyover Events to quickly delete any code in the OnFlyover or OnFlyoverLeave events.

Xbasic Manipulation of Objects

You have now learned how to program object events. In Exercise 9, you used one line of Xbasic code in each of two event scripts to change the appearance of an object (the Field1 control) that is part of the Count Seconds form.

There are basically three things you can manipulate with Xbasic commands:

  • Variables

  • Tables

  • Objects

Xbasic can be used to create, change, display, update and destroy the three Alpha Anywhere components listed above. But, Alpha Anywhere is primarily a database application development tool and, in fact, all layouts (the means by which you display windows (data)) must be associated with a table or set as its data source. Later on, you will be introduced to some Xbasic scripts that primarily manipulate tables and the data contained in them. Right now, though, you will look more closely at how you can use Xbasic to manipulate objects found on layouts.

In order to understand the examples you will read about in coming exercises, you will need to understand a little about the Phone Messages sample application and what it is designed to do.

In order to understand the examples you will read about in coming exercises, you will need to understand a little about the Phone Messages sample application and what it is designed to do.

The Phone Messages application allows the recording and retrieval of phone messages for a population of users. The users of this application can be either takers or receivers of messages (so anyone in the office can take a message for anyone else). User data is stored in the table named message_tr (where "tr" stands for takers or receivers).

Some users are designated as administrators. Administrators can do all the things that regular users can do, but they also have access to the portion of the program that enables user administration. The user administration form can be used to add, change or delete user information.

The Phone Message application begins when you launch the Sign In form. The Sign In form asks you to enter a user ID and password to gain access. As you can see from the message_tr table structure on the right, each user has a field named Tr_Administrator that indicates whether or not that user is an administrator. After you sign in, you will see one of two different menu choices depending on whether or not the id you signed in with is an administrator. Figures 42 and 43 show the way the form displays different data depending on the type of user who is logged in.

In the next exercise, you will view the event scripts that check the values of variables and then dynamically change the form display (the form object and sub objects) depending on those values.

In the next exercise, you will view the event scripts that check the values of variables and then dynamically change the form display (the form object and sub objects) depending on those values.

Figure 41

You are looking at a portion of the same form in each of the two figures at the right. The form appears to expand the radio control choices depending on whether the logged in user is an administrator or not.

What is actually happening is that two different radio controls were placed on the Sign In form (Radio1 and Radio2). Radio1 has two choices. Radio2 has three choices.

Both radio controls are hidden when the form is initialized. After user logon, a logical form variable is_admin is set and Alpha Anywhere unhides the appropriate radio control. Another form variable (this one of type character) named user_type is set by either radio control.

After you have selected what you want to do from the radio control, the user_type variable setting is used by the OnPush event of the Next button to determine what form Alpha Anywhere displays next.

The radio1 control sets the user_type variable to either receiver or taker. The radio2 control sees the user_type variable to receiver, taker or administrator.

In the next exercise, you will see how Xbasic commands executed in different object events set these variable values and object properties to direct the flow of the application in the appropriate way (i.e., to display the correct choices for an administrator or non-administrator user.

Figure 42

The radio control has two choices after you log in with a non-administrator ID. The user ID used to logon here is Michael Ahn.

Figure 43

The radio control has three choices after you log in with an administrator ID. The user ID used to logon here is Ricky Manes

Exercise 10 - Following program flow through Xbasic commands and events 

  1. View the Sign In form.

  2. Click the Please Login button.

  3. Choose the user: "Ricky Manes". This is an administrator ID.

    Figure 44
  4. Enter the password: "password".

  5. Click OK to logon and continue. Alpha Anywhere displays the following screen:

    • Figure 45
    • The "See your messages" option is selected in the radio control.

  6. Click Next to see Ricky's messages. You can click on any of the buttons on the left side of the window to see various messages for Ricky.

  7. Close the form by clicking the Exit button. You are returned to the Sign In form.

  8. Select "Take messages" and then click Next. You will see the message entry form.

  9. Take a message if you wish and then close the window with the Exit button. You are returned to the Sign In form.

  10. Select "Manage Users" and then click Next. The Administration form loads.

  11. Scroll through the users. Add a user if you like. If you want the user to be an Administrator, select the Administrator? field.

  12. Close the Administration form. Now that you have seen how this application works, you are going to enter design mode for the Sign In form and see how the different choices you made for what to do next in the radio control on the form layout are presented and processed by Alpha Anywhere.

  13. Press the Exit button to close the application. You are in the Control Panel window.

    • The Sign_In object (the form layout object) has an OnInit event defined. OnInit executes when the form is first initialized.

      The Button1 object (Please Login) has an OnPush event defined. This control is displayed when the form is first loaded. This OnPush event loads the Xdialog box where you enter a user id and password and then (after a successful logon) it hides the Button1 control. This event also sets the value of the user_name, user_id and is_admin variables.

      Then, depending on the value of is_admin, it unhides the appropriate radio control, Radio1 or Radio2. On this form, Radio2 (which has three choices) is displayed. (Note: Radio1 and Radio2 are aligned so that Radio2 lines up with and sits behind Radio1 in design mode). The Radio2 control then sets the value of the user_type variable.

      The Button2 object (Next) has an OnPush event defined. This button checks the value of the user_type variable (set by the Radio1 or Radio2 control) and then loads the next appropriate form (either Take Message, Review Messages or Administration ).

  14. Enter design mode for the Sign In form.

  15. Open the Code Explorer.

  16. Press the Variables button on the toolbar to display the form's variables. Now you will examine parts of some of these event scripts to see how Xbasic commands manipulate the objects and variables of this form.

    Figure 46
  17. In the Code Explorer, select the "BUTTON1.OnPush" event. The code for this event is shown in the code box on the right. To get a bigger view of the code without scrolling you need to view it in the Code Editor.

    The Sign_In.OnInit event prepares the data records to be date relevant whenever the application is run and you can examine the code if you like. In the remainder of this exercise, you will review the code for the Button1 and Button2 OnPush events.
  18. Press the Edit Code button. This event's code is loaded in the Code Editor.

    • Figure 47
    • Variables used in this script are DIMmed at the beginning. DIMming a variable means Alpha Anywhere knows what type of data you want to store in that variable and can catch errors and enables Alpha Anywhere to use computer memory more efficiently.

      DIM varC_result as C
      DIM goodtogo as L
      DIM user_password as C
      DIM stored_password as C
    • Some of the variables dimmed above and some global variables that were defined on the Sign In form are assigned values. The variable goodtogo indicates if a valid password was entered. Before the Please Login window is loaded goodtogo is False.

      goodtogo = .F.
      user_name = ""
      user_password = ""
      user_id = ""
    • This is a special Xbasic Xdialog command. The varC_result variable is set to the value returned by a dialog box that is opened by the ui_dlg_box command. A dialog box is a pop-up window where you can prompt for data entry or just display information. A dialog box asks for user input (perhaps just clicking OK to continue).

      varC_result = ui_dlg_box("Please Login",<< {position=remember=ploginbox} {region} {ysize=2} {xmargin=4,2} {font=Arial,11}
      .
      .
      .
    • Figure 48
    • The Xdialog box command continues line by line until the closing parentheses. This Xdialog box command includes code to process selections and therefore the closing command is %code%. You can learn more about Xdialog boxes later in this book or you can learn a lot more about Xdialog boxes in the book Learning Xdialog.

      .
      .
      .
          end select
      end if
      %code%)
    • This Xdialog box command prompts for the entry of the user id and password. If a valid password is entered, the variable goodtogo is set to .T. The is_admin variable is also set in this Xdialog box. Both of these variables will be checked in the next part of this script.

      If goodtogo is True (which means a valid password was entered) then all the Xbasic commands between the IF goodtogo THEN statement and the END IF statement at the bottom are executed. These statements are the ones that affect the objects(controls) on the Sign_In form.

      IF goodtogo THEN
          topparent:Text2.Text = "Welcome, "+word(user_name,1)
          topparent:Text2.Object.Visible = .T.
          topparent:Button1.Object.Visible = .F.
          topparent:Text3.Object.Visible = .T.
          IF is_admin = .T. THEN
              topparent:Radio2.Object.Visible = .T.
              topparent:Radio2.Object.Enabled = .T.
          ELSE
              topparent:Radio1.Object.Visible = .T.
              topparent:Radio1.Object.Enabled = .T.
          END IF
          topparent:Button2.Object.Visible = .T.
      END IF
    • The first two commands after the IF ... THEN statement change the text property and visible property of the Text2 object. (The user_name variable was loaded with the name of the logged in user in the Xdialog command above.) Button1, the Please Login control is hidden (the visible property is set to False) and the Text3 object (What do you want to do?) is also made visible.

      The next sequence of commands tests the value of the is_admin variable. If is_admin is True, then the Radio2 control is made visible and enabled (given focus). This is the radio control with the three options for admin users. Otherwise, the Radio1 control is made visible and enabled. This is the radio control with the two options for regular users. Finally, Button2 (the Next button) is made visible.

      If goodtogo is False, then a valid password was not entered in the Xdialog command above, and all these commands are not processed. So, Button1 ( Please Login ) is still visible and Text2, Text3, Button2, Radio1 and Radio2 are still hidden. If an incorrect password is entered the user is returned to the same Please Login form as she started with.

  19. Close the Code Editor and the Code Explorer.

  20. Close the Sign In form. The Control Panel should be displayed on your screen.

  21. Click the Interactive Window button on the toolbar.

  22. Click the Maximize button in the upper right corner of the window.

  23. Put the cursor on the window bar of the Code Editor and drag the Code Editor window to the bottom right of the screen as shown below in figure 49.

    Figure 49
  24. Now type the following command in the Interactive window.

    • For
    • Figure 50
    • Press Enter, and Alpha Anywhere fills in the rest of the Xbasic command Form.

      As you type the letters, "For", Alpha Anywhere pops up a command completion help window. Alpha Anywhere displays all the relevant Xbasic commands that begin with "For". You can keep typing or you can press Enter and Alpha Anywhere will auto complete (fill-in) the rest of the command from the top of the Pop-up Help window.
  25. Type "vi" and then Enter and Alpha Anywhere fills in the View Xbasic method (for a form object).

    Figure 51
    The view() method gets filled in with parentheses which hold parameters for this method. The first parameter accepted by the view() method is a character string of the layout name for the form you wish to view. (The other parameters are indicated in square brackets and are optional.) You can keep typing (with the insertion point between the parentheses) the form layout name in directly or you can use the bubble help auto-lookup feature. The parameter is highlighted in black and the help message says "Press control-down key or click right click to select name of layout".
  26. Put the cursor over the black highlighted parameter and click the right mouse button. A list of Form layouts will pop-up.

  27. Highlight and click on the "Sign In" form layout name. Alpha Anywhere fills in the Sign In layout name string as the layout parameter.

    Figure 52
  28. Click at the end of the command line to turn off the bubble help as shown below.

  29. Press Enter. Alpha Anywhere loads the Sign In form. The form is maximized.

  30. Click on the Code Editor button on the Window Bar. Focus switches to the Code Editor window. Note that the Sign In form window is still running as shown on the Window Bar. Now you will type some Xbasic commands in the Interactive window and then view the changes on the Sign In form.

    • You can use auto-complete and have Alpha Anywhere fill in the parts of the command you want automatically, but if you use auto-complete with the layout name Sign_In, be aware that Alpha Anywhere will fill in

      :Sign_In.

      in Step 31. You are going to reference an object ( button1 ) on the Sign In form, so you need to replace the . (period) with a : (colon). Alpha Anywhere has no way of knowing that you want to reference a sub-object rather than a property or method, so it fills in a period which is generally a more common usage.

  31. On a new line in the Interactive window, type:

    :Sign_in:button1.object.visible = .F.
  32. Press Enter, then click on the Sign_In button on the Window Bar. On the Sign In form, button1 (Please Login) is no longer visible.

  33. Switch back to the Code Editor and on new lines type:

    • user_id = "John"
      :Sign_In:text2.text = "Welcome" + user_id
      :Sign_In:text2.object.visible = .T.
    • These Xbasic commands change the text property of the Text2 text control and then makes that control visible. Switch back to the Sign In window to see the form now. Portions of the two windows are shown in Figures 53 and 54 below.

      The changes you accomplished interactively for the Sign In form display are the same changes that you saw earlier when the OnPush event script for Button1 is executed. when you caused the OnPush event to trigger by pushing button1 (the Please Login control).

      • This command

        :Sign_in:button1.object.visible = .F.
      • is identical to the command

        topparent:button1.object.visible = .F.
      • that you saw in the Button1.OnPush event script where topparent is an alias for :Sign_In.

  34. Close all windows.

    Figure 53
    Figure 54

Watching Script Execution with the Debugger

In Exercise 10, you saw how Xbasic code in the object events determine what is shown on the form and what options are available to the user. When you signed in as an administrator in the Its For You application, the Radio2 control was enabled for you to select from three choices: See your messages, Take messages and Manage Users.

To proceed in the application, you press the Next button. The Next button's OnPush event is shown at the right in figure 55.

Figure 55

The script checks the value of the is_admin variable (which was set in the event script of the Please Login button). The next_screen variable is set to the value of the choice made in either the Radio2 or Radio1 control. If is_admin is True, the Radio2 control is the active control (see Exercise 10) and next_screen is set accordingly.

if is_admin
    next_screen = radio2.text
else
    next_screen = radio1.text
end if

The SELECT command includes a number of CASE statements. If the expression for a case command evaluates to TRUE, the command(s) that follow are run, otherwise the next CASE statement is evaluated. So if the variable next_screen is set to receiver in the IF statement above, the SELECT command processes this command:

script_play_local(Open Review Msg Form)

Debugger 

A debugger is tool that helps you to catch errors and validate that commands are doing what you intended when you write a program. Because they help you eliminate bugs from your program, these kind of tools are called debuggers.

The Debugger is a separate window that you can open from the Alpha Anywhere View menu or dynamically at any point in a script by using the Xbasic debug() command.

In Exercise 10, you looked at the script for the OnPush event of Button1 and now you have reviewed the script for the OnPush event of Button2 for the Sign In form by viewing the commands in the Code Editor. When you are creating scripts like these, Alpha Anywhere provides a mechanism to see each line of Xbasic code as it is processed and to examine the values that variables take on as the code runs. This feature is the Xbasic debugger and in the following exercise, you will turn on the debugger with an Xbasic command in the Button2 script and then watch interactively as Alpha Anywhere processes the rest of the scripts Xbasic commands.

Exercise 11 - Watching a script execute through the Xbasic debugger 

  1. Open the Sign In form in Design mode.

  2. Right-Click on the Next button.

  3. Select Events and then OnPush. The :Sign_In:BUTTON2.OnPush event code will load in the Code Editor.

  4. Enter the following as the first line of the script:

    • debug(1)
    • This command will turn on the debugger when this script executes.

  5. Enter the following as the last line of the script:

    • debug(0)
    • This command will turn off the Debugger when the script ends.

      • The Debugger has a menu and two main sections:

        code view and watches

      • The code view shows the Xbasic code of the script that is currently loaded in the debugger. This is the script that Alpha Anywhere is currently processing. The pointer symbol shows which line of the script will execute next.

      • pointer symbol 

        The watches section allows you to type in variable names (or expressions) in the Examples column. As the script executes, the Debugger will show how the values of the variables you are watching change in the Value column.

        As you watch a script execute in a debugger, there are three main commands that you can use to watch line-by-line which command gets executed. These three commands are accessible through the Debug menu or the toolbar. On the toolbar these are the three buttons that control the progression through the scripts Xbasic commands:

      • The button in the middle is the Trace into line of Xbasic button and is the one you will use most often. The button on the left is the Step over line of Xbasic. The button on the right is the Skip over current line.

        Pressing Trace into line of Xbasic directs Alpha Anywhere to process the line the pointed to by the pointer symbol.

        When you press Step over line of Xbasic, Alpha Anywhere will process the line pointed to by the pointer symbol but if that line invokes another script, that scripts Xbasic commands will not be shown in the Debugger. (This means if the Xbasic command were play_script_local(Script 2), then Script 2 would execute but you would not see all of Script 2's lines of code as you would if you has used the Trace into line of Xbasic command.)

        Finally, if you press Skip over current line, then the line pointed to by the pointer is not executed and the next Xbasic command is processed. (This means if the Xbasic command were play_script_local(Script 2), then Script 2 does not execute and the next line after this one is the next one processed by Alpha Anywhere.)

  6. Save the script and close the Code Editor.

  7. Run the Its For You application by viewing the Sign In form. Login in as user "Ricky Manes" with password "password".

  8. When you have reached the What do you want to do? form display, leave the radio control selection on See your messages and click the Next button.

    When you press the Next button, Alpha Anywhere runs the OnPush event script. At the start of this exercise, you entered the command debug(1) as the first line of this script and this command causes the debugger window to open. The pointer symbol is showing the next command that will execute is DIM next_screen as C.

    When you are in the Debugger, you have to tell Alpha Anywhere how to proceed. You have a number of options. You can direct Alpha Anywhere to execute the line it is pointing to and then pause again. You can highlight a line further down in the script and tell Alpha Anywhere to execute all the commands from the current pointer until the line you highlighted and then pause again. Or you can skip over lines or turn off the debugger and proceed normally. You can also, at any time Alpha Anywhere has paused and is waiting for your direction, type variables names in the Watches section to see what values they take on as the script executes.

    • Figure 56
    • This is the Code View section of the debugger where you see each line of the script Alpha Anywhere is currently executing.

    • This is the Watches section of the debugger where you can type in variable names or expressions and watch as their values change as the script runs.

  9. In the first row of the Example column of the Watches section, type:

    • next_screen
    • and press Tab twice. The cursor will move to the second row of the Watches section.

  10. Type:

    • is_admin
    • and press Tab twice again. The cursor will move to the third row of the Watches section. The Value column for the next_screen variable row shows ???. (This variable has no value assigned to it yet.) The Value column next to the is_admin variable shows .T. or True. This variable is a global variable and is assigned a value of True by the :Sign_In:button1.OnPush event when you log in as user Ricky Manes who is an administrator.

  11. Press the Trace into line of Xbasic button once. Alpha Anywhere just executed the line, DIM next_screen as C and has now paused at the next Xbasic command. (Note the full Xbasic command that begins on this line with the IF statement and extends for five lines until the END IF statement). DIMming a variable does not affect a variables value so nothing has changed in the Watches section.

  12. Press the Trace into line of Xbasic button once. This command begins with IF is_admin THEN so if the value of is_admin is True, then the following line of Xbasic code will be executed. In fact, you can see in the Watches section that is_admin is True, so the Debugger has moved to the next line of code (though it has not executed it yet).

  13. Press the Trace into line of Xbasic button once. This line of code sets the variable next_screen to a value of whatever is stored in radio2.text. Radio2 is a control on the Sign_In form. In Step 8, you left the Radio2 control set to "See Your Messages" and the text (value) of that control is therefore "receiver". (You can verify this by examining the choices list for the Radio2 control on the Sign_In form.) If you look down at the Watches section, the value of next_screen is now displayed by the debugger and indeed it is set to receiver.

    The pointer symbol has advanced to the next line of the script. Alpha Anywhere is still processing the IF...THEN...ELSE...END IF command. But since the test value of the IF statement already evaluated to True then Alpha Anywhere should skip the commands after the ELSE statement. So if you press Trace into line of Xbasic the pointer symbol should move past the commands following else (since they will not be executed) and to the next Xbasic command.

  14. Press the Trace into line of Xbasic button once. The pointer symbol moves to the SELECT command.

  15. Press the Trace into line of Xbasic button once. The pointer symbol moves to the CASE statement. This checks to see if next_screen is set to a value of taker. (Its not, since you can see the value in the Watches windows, so what do you think will happen when you trace into this line of Xbasic?)

  16. Press the Trace into line of Xbasic button once. You are right! Alpha Anywhere skips the command after the CASE statement, because it did not evaluate to True. The Debugger pointer symbol is positioned at the next CASE statement.

  17. Press the Trace into line of Xbasic button once. This CASE statement does evaluate to True and Alpha Anywhere is ready to process the command following this CASE statement. However, this command will play a whole different script than the one you are viewing in the Debugger. If you Trace into line of Xbasic here, the debugger will load the Open Review Msg Form script into the Debugger and you will have the option of tracing through that script. You will next ask Alpha Anywhere to, indeed, run this command and execute the Open Review Msg Form script, but not to load that script into the Debugger.

    Only press the Trace into line of Xbasic ONCE in each of these exercise steps. At step 17, be especially sure to press this button ONCE or else another script will load into the Debugger. (If you would like to see this happen, you can load the next script and process its commands.) If you mistakenly start another script in the debugger, press the F5 (Go) key to execute all the commands in the script and you will return to the calling script in the Debugger.
  18. Press the Step over line of Xbasic button once. The Open Review Msg Form script executes and the Review Messages form loads. You are still in the OnPush event script for Button2 and the Debugger is ready to execute the next command.

  19. Press the Trace into line of Xbasic button once. This CASE statement evaluates to False so the next line is skipped.

  20. Press the Trace into line of Xbasic button once. The SELECT command has finished.

    One other button on the Debugger toolbar that you should know about is the Go button:

    This button (or the F5 key) can be used at anytime while you are using a script to process all the remaining commands in that script without pausing on each line. (If the current script invokes a second script, the debugger will pause at the first line of the second script.) Of course, you can then press Go again to process all of the second scripts commands without pausing.

  21. Press the Trace into line of Xbasic button once. The command debug(0) closes the debugger. You watched the whole script execute line by line in the debugger so you dont need it anymore and this command closes the debugger window and returns you to your application.

  22. Close the application (not Alpha Anywhere). Use the Exit buttons on the application's forms.

  23. Go to Design mode for the Sign In form.

  24. Edit the button2.OnPush event script and remove or comment out the two debug lines you added at the beginning of this lesson.

  25. Close all windows.

Variable Scoping

In Exercise 11, you saw how variables were used to hold values that determined the course of the application. For example, when you log in with a user name for an administrative user, the is_admin variable is set to True and this variable is used to determine which radio control on the Sign_In form you see next. (The is_admin variable is set in the event script of Button1 named Please sign in). Other variables set in Button1 s OnPush event script are user_id and user_name.

All three of these variables are set in Button1s OnPush event, but they are used later in the application by other scripts. You just saw Button2 s OnPush event script check the value of is_admin in Exercise 11. So a variable defined in one place in Alpha Anywhere can be accessed (i.e., you can set or get its current value) in another place. However, variables are not automatically visible (i.e., accessible) in every other part of Alpha Anywhere once they have been defined. Where a variable is accessible is called the variables scope. There are five different types of scope in Alpha Anywhere. A variables scope level is how Alpha Anywhere determines if a variable is available for use if it is defined in script A in script B.

Variables can be defined in four places in Alpha Anywhere. You can create variables associated with:

  • a database

  • a table

  • a layout

  • any Xbasic script

Variables defined in the Code Editor using the Define Global Variables button are available whenever the database they are created in is opened and are global variables available to all layouts and scripts until that database is closed (or the variable itself is destroyed in a script). Variables defined in the table editor are also global variables and are instantiated when that table is opened.

Variables instantiated in a layout can be session, layout or global variables and are created when that layout is opened.

Finally, variables created in an Xbasic script can be global, shared or local. Global variables, once instantiated, are available to any component of Alpha Anywhere while the same database is open. Shared variables are instantiated in one script and available to any scripts run from that original script. Local variables (which is the default when a script variable is created with just the DIM command and no qualifier) are only available in the script in which they are instantiated and are not visible in child scripts.

  • The six levels of variable scope are:

    • GLOBAL

    • SESSION

    • LAYOUT

    • SHARED

    • LOCAL

    • ADMIN

  • GLOBAL 

    GLOBAL variables exist throughout an Alpha Anywhere application session from the time they are created (or instantiated). A global variable defined in Fourth Form will not be available until the form Fourth Form is loaded in a particular Alpha Anywhere session, but it will stay in existence and be available to all other scripts and layouts from that point on until you close Alpha Anywhere.

  • SESSION and LAYOUT variables 

    SESSION and LAYOUT variables are defined in layouts. SESSION variables exist from the time the layout they are defined in is loaded and are available to any scripts or object events run from that layout.

    (LAYOUT variables are a special case beyond the scope of this book.)

    In a script, when you define a variable with a DIM statement you can add GLOBAL or SHARED after the DIM command. GLOBAL makes it a GLOBAL variable. SHARED makes the variable available to any scripts that are called (run) from the current script (and subsequent scripts). If you do not use either of these two options, the variable is a local variable and only visible in the current script.

Exercise 12 - How a variables scope affects its visibility 

  1. Open the Code Editor.

  2. Open the Interactive window.

  3. Select View > Global Variables.

  4. Click on the tab Initialized at Startup. You will see the following window. In this figure, you can see that the Phone Messages database has three global variables defined. One of them, varC_global_test has an initial value of "I am a global variable".

    • Figure 57
    • You should define any Global variables you wish to use in the Code Editor using the View > Global Variables menu selection. ( Note : This menu selection is available when you are editing a script or using the Interactive Window.)

      The Global Variables window has two tabs, Variable List and Initialized at Startup. You can add global variables on either tab, but if you want a global variable to persist (i.e., be stored and available the next time you open the current database) then define it using the Initialized at Startup tab. Global variables that you add through the Variable List tab will be discarded when the database is closed.

    • Why Do Variables Need to be Scoped? 

      This question could be rephrased as why isn't every variable a global variable?

      The simplest answer is that every time you create a variable, Alpha Anywhere uses up computer memory to store the variable name and value. Especially, if you are using variable arrays, too many global variables can have an adverse impact on your applications performance (this would depend on the amount of memory and capacity of the computer in use).

      In advanced programming, it makes sense to limit the scope of variables to only the objects (I.e., scripts, layouts) that need to make use of them. This is good programming style and also helps others reading your code later to understand how a variable is being used. (It also lets you use the same variable name in different scripts to track different values. This can be a useful tool in advanced programming.)

  5. Close the Global Variables window.

    Global variables can be defined in other parts of your application besides the Initialized at Startup tab of the Global Variables window. As they are instantiated you can monitor all global variables from the Variables List tab of the Global Variables window.
  6. Switch to the Control Panel and choose design mode for the VariablesScope form.

  7. Select Form > Variables and the Variable Definition window appears. In this window you can see two variables have been defined. varC_layout is a layout variable with a value of "I'm a layout variable". varC_session is a session variable with a value of "I'm a session variable".

  8. Close the Variable Definition window.

  9. Switch to View mode for the VariablesScope form. The form appears below:

    • Figure 58
    • All three of the variables whose definitions you observed in Steps 1 to 7 of this lesson are displayed on this form. So varC_global_test is available to this form (as you would expect) since it was instantiated as a global variable when the Phone Messages database was opened. Likewise, varC_layout and varC_session display with the values they are instantiated with when this form opens.

      The two buttons on this form both have OnPush events defined that both do basically the same thing. Pushing either button will display a message box showing the three variables and their variables. The difference in the events is crucial for understanding a variables scope.

      • The Xbasic command ui_msg_box() displays a message box with a title and the contents of a character string and an OK button to continue. The character strings displayed in the ui_msg_box() commands in this exercise are: line 1

        varC_global: + varC_global_test
      • line 2

        varC_session: + varC_session
      • line 3

        varC_layout: + varC_layout
    • Button1' s OnPush event code is this:

      ui_msg_box("BUTTON1 OnPush Event - popup 1","varC_global: "+varC_global_test)
      ui_msg_box("BUTTON2 OnPush Event - popup 2","varC_session: "+varC_session)
      ui_msg_box("BUTTON3 OnPush Event - popup 3","varC_layout: "+varC_layout)
  10. Press button1 and you will see the following:

    The varC_global variable is displayed by the first command line in the OnPush event.
  11. Press OK.

    The varC_session variable in displayed from the OnPush event.
  12. Press OK.

    The varC_layout variable in displayed from the OnPush event.
  13. Press OK. The code for the OnPush event script of Button2 is different from that of Button1. Instead of executing the ui_msg_box command you saw above, this script plays a saved Xbasic script. The code is:

    • script_play("FormScopeTest")
      The Xbasic command script_play() loads and runs the script named as the command's parameter.
    • The content of the Xbasic script, FormScopeTest, is:

      ui_msg_box("FormScopeTest script - popup 1","varC_global: "+varC_global_test)
      ui_msg_box("FormScopeTest script - popup 2","varC_session: "+varC_session)
      ui_msg_box("FormScopeTest script - popup 3","varC_layout: "+varC_layout)
    • This is the same exact code (except for the message box's title parameters) as you saw in Step 8 for the :Button1.OnPush event. But now, there is another layer involved. The :Button2.OnPush event plays a script and that script code runs separately from the layout of the VariablesScope form. You can think of the :Button1.OnPush event script as running within the layout and the FormScopeTest script running outside the layout (though still within the layout session. So what do you think will happen to the layout variable and the session variable when the Xbasic commands of the FormScopeTest script tries to access each of them?

      Whenever a layout is opened (viewed), Alpha Anywhere begins a new "session". Layout objects and their event scripts can access "layout" variables. Scripts launched through an object that is part of a particular layout are part of that script's session and have access to the layout's session variables.
  14. Press Button2.

    The varC_global variable is displayed from the OnPush event.
  15. Press OK.

    The varC_session variable is displayed from the OnPush event.
  16. Press OK.

  17. This time an error message is displayed. The varC_layout variable was not found. Click the Break button until you can click the X button on the Debugger menu, then close the Debugger.

    In Step 12, the variable defined as a session variable was found and displayed. But the FormScopeTest script that is running does not have access to the layout variables of the VariablesScope form.

  18. Switch to design mode for the VariablesScope form.

  19. Right-click on BUTTON2 and select Events > Pop-up Editor. In the script edit window change the command to:

    script_play_local("FormScopeTest")
    The script_play_local() command gives the "called" script (i.e., the script being played by this command) access to any variables available in the "calling" script (i.e., the script that has this command in it). In this exercise, the calling script is the :Button2.OnPush event script and the called script is FormScopeTest.
  20. Click Save, then Close.

  21. Switch back to view mode for the form.

  22. Click on BUTTON2.

  23. Click through the three message boxes. When you change the command in Step 16 from script_play() to script_play_local() you tell Alpha Anywhere to give the script access to the layout variables of the layout this script was launched from. Since the script was played from the OnPush event of a child object of the VariablesScope form layout, this script now has access to the VariablesScope layout variables. The third message box command now has access to the layout variable and displays without an error.

    A SHARED variable that is DIMmed in a calling script is available in a called script that is run with the script_play() command. GLOBAL variables are, of course, available to any subsequently run scripts once they are instantiated in a script. Variables intantiated with a regular DIM command (without the SESSION or GLOBAL qualifier are "local" variables only visible in the script they are created. However, if you play a subsequent script with the script_play_local() command, then local variables are visible in the called script also.
  24. Close the VariablesScope form.

  25. Open the Interactive window.

  26. Type:

    ? not_a_variable
    • Alpha Anywhere responds with "ERROR: not_a_variable not found".

  27. Type:

    ? is_admin
    • Alpha Anywhere returns .T. or .F. (depending on whether you previously logged in as an administrative user of the Its For You application during this Alpha Anywhere session).

  28. Select File > New > Script using Xbasic editor.

  29. Enter the following lines in this new script:

    • DIM varN_smallnumber as N
      DIM SHARED varN_bignumber as N
      varN_smallnumber = 2
      varN_bignumber = 8888
       ui_msg_box("Momma script", STR(varN_smallnumber,4,0))
       ui_msg_box("Momma script", STR(varN_bignumber,4,0))
    • While you are typing in the Xbasic commands in Step 28, be sure to take advantage of Alpha Anywhere's bubble help and command auto-completion. as you type a command, as soon as the next command that you want appears at the top of the bubble list, just press Enter and the rest of that command word will be filled in for you.

      For example, as you type: "DIM S" as shown here, Alpha Anywhere's bubble help shows the word "SHARED".

    • Press Enter and the full word will be filled in automatically for you. Alpha Anywhere will also show object and variable names that have been instantiated (in addition to commands) in bubble help and will auto-complete typing in their names as well.

  30. Press Save and give the script the name "momma".

  31. Select Code > Run. The script displays two message boxes in turn and the two variables you created are displayed.

  32. Select File > New > Script using Xbasic editor.

  33. Enter the following lines in this new script:

    DIM varN_diff as N
    varN_diff = varN_bignumber - varN_smallnumber
    ui_msg_box("child of momma", STR(varN_diff,4,0))
    The type conversion function STR() is necessary in the ui_msg_box() command in Step 28 because the second parameter of the ui_msg_box() command must be a string and the variable used here is of type numeric.
  34. Press Save and give the script the name "child of momma". Your screen should look like this:

    Figure 59
  35. The child of momma script tab is still the active tab. Press the Run button. The following error message box appears:

    • Alpha Anywhere reports that varN_smallnumber cannot be found. If you look back at the momma script shown in step 26, you can see that varN_bignumber was DIMmed as SHARED. And since you ran the momma script, this variable is available to any other scripts youre running while in the Code Editor.

  36. Click the Break button until you can click the X button on the Debugger menu, then close the Debugger.

  37. Click on the momma script tab. Change the first line to:

    • DIM SHARED varN_smallnumber as N
    • Add this line at the end:

      script_play("child of momma")
  38. Save the script.

  39. Choose File > Close Code Editor. You are at the Control Panel.

  40. Click on the Code tab.

  41. Double-click on the momma script to run it. The two message box commands in the momma script appear followed by the message box in the child of momma script. Since the two variables varN_smallnumber and varN_bignumber are both DIMmed as SHARED in the momma script, they are both available to the child of momma script.

    The type conversion function STR() is necessary in the ui_msg_box() command in Step 28 because the second parameter of the ui_msg_box() command must be a string and the variable used here is of type numeric.
  42. Open the momma script to edit it. Add the following line at the end:

    • ui_msg_box("Momma script", STR(varN_diff,4,0))
    • Run the script. What happened? Save the script.

  43. Now edit the child of momma script and make the variable varN_diff SHARED. Save your changes.

  44. Rerun the momma script. tHe error has been fixed by sharing the variable between the two scripts.

  45. Close all windows.

Functions 

Early, you saw the following code:

date_of_birth = {11/21/1974}
age = int((date()- date_of_birth)/365.25)

used in Xbasic to calculate a person's age. You also learned that a function is a special Xbasic command that optionally takes an input or inputs and produces or "returns" an output. In the code above, the Xbasic command int() is a function. The int() command takes a numeric input and returns the integer portion of that number. The entire expression:

(date()- date_of_birth)/365.25

evaluates to a number which is the input parameter for the int() function. So, int(24.3) would return the value 24, which is the integer portion of a number. The int() function is classified (simply for reference) as a numeric function since it returns a numeric value.

A function is an Xbasic command that processes data (some of which is optionally provided to the function as input parameters) and returns a value for display, assignment to a variable, or incorporation in an expression.

Alpha Anywhere includes hundreds of built-in functions that can be used in any Xbasic expression or script. These functions allow you to transform data, query tables, load arrays, set values and more. Every new version of Alpha Anywhere includes new functions added to the program's built-in function list that allow you to quickly accomplish tasks that you would normally have to program yourself. The Alpha Anywhere help files group functions in the categories shown in the following table. This is simply a classification to help you understand where to look for a function depending on what you need to do. Chances are there is an Alpha Anywhere function that matches your needs already. For example, the code above is used to calculate a person's age given a date of birth. In fact, Alpha Anywhere already includes a built-in function that returns a person's age. Appropriately enough it is the age() function. In the interactive window, the function definition appears in bubble-help as below:

Figure 60

It is not important for you to understand how a function works, only what inputs are required (if any) and what kind of output you can expect from a function.

You can see that the age function takes two parameters, one of which is optional. The first parameter is a date value (indicated by the 'd') named dob (which stands for date of birth). If you use the age() function with the dob parameter alone, the function returns an age as of the current date. So, in this next example, the date() function is used to verify the current date (the date this example was created) and then the age() function is called with a dob parameter.

Figure 61

So, on October 8, 2003, the age() function reports that a person born on July 1st, 1990 is 13 years old.

Now the second (optional) parameter is also a date value and is named asofdate. Including this parameter has Alpha Anywhere return an age as of the input date as seen here:

Figure 62

Exercise 13 - Using the Function Finder to locate a function 

  1. Open the Code Editor.

  2. Open the Interactive window.

  3. Select Interactive > Insert Function. You will see the following window:

    • Figure 63
    • The Insert Function command is accessible from different menus depending on what you're working on. If you're in the Interactive window, it's on the Interactive menu. If you're editing a script or function, it's on the Code menu.

      The function finder has the following parts:

      Search for a Function allows you to type in key words. When you press Search, any functions whose descriptions contain any of the key words are shown in the middle of the screen.

    • Select a Category allows the following selections:

    • which then displays the appropriate functions in the middle of the screen.

      In Select Function you type in characters that begin the function name and matching functions are displayed in the middle of the screen. (This is just how bubble-help works.)

    • A description of the highlighted function and the complete syntax of the function is shown below the middle function listing box. The type of value returned by the function is shown before the function name.

  4. Type the word "trim" in the Search for a function box and then press the Search button. (Don't press Enter after typing "trim" or the Function Finder will close.) Alpha Anywhere displays a listing of five functions that include the word "trim" in their definitions.

  5. Highlight the alltrim() function and press the Insert button. The function is copied into the Interactive window.

  6. Change the line alltrim() to:

    ? alltrim(" this will be trimmed ") + "!"
    While you are editing the line, make use of the Home and End keys to quickly move your cursor to the beginning and end of the line.
  7. Press Enter. You will see the following:

    = "this will be trimmed!"
  8. Close the Interactive window.

Global User Defined Functions 

Like the properties and methods and events of objects, the functions you saw in the previous section are all built-in to Alpha Four. Like object methods, you can call a function to accomplish a pre-designated task. Object events, however, you can define yourself. You control what happens when you write Xbasic code for an object event.

Similarly, you can define your own functions by writing Xbasic code. But unlike object events, which are already named, you can name your own functions. Once created you can call on that function to accomplish something that you need to repeat. It does not make sense to create a function that is only used once for a very specific task. When you have to manipulate data in a custom way that is not provided by a pre-built Xbasic function and you have to do it over and over, that is the time to create your own function.

Once a function is created and named, it becomes part of your own Alpha Anywhere set of functions. You have previously seen that one of the selections for function categories is User Defined. These functions are also called global functions. Once created, they are available to be used in any of your Alpha Anywhere applications.

A global function is like an Xbasic command of your own creation. It has a name, it can accept parameters and it can (optionally) return a value. Global functions have to meet certain criteria in order to function correctly. Alpha Anywhere makes it easy to build-your-own functions.

  • New Functions 

    A new function must be created with a function name, a return type, and optional arguments as shown in a section of the Create New Function window shown below:

    Figure 66
  • Any parameters specified must be provided when the function is invoked. These parameters become local variables available to the Xbasic code that makes up the function.

Let's take a quick look at a global function written for the Its For You application.

The Its For You application stores the names of message takers and receivers in the message_tr table. This table shows the fields from message_tr that store a persons name data along with a sample record from the table.

Tr_Salutation

Character

15

Dr.

Tr_First_Name

Character

15

Suzanne

Tr_Middle_Name

Character

15

M.

Tr_Last_Name

Character

20

Lainson

Tr_Suffix

Character

10

M.D.

Tr_Familiar

Character

15

Sue

In the Its For You application, a persons name is used in selection lists, reports and input forms. There are multiple ways to format a persons name from the available data fields. For example, for the data above, you might want to use the name in the following formats:

Format

Result

Fields Use to Express Result

Familiar Name

Sue Lainson

Tr_Familiar, Tr_Lastname

Formal Name

Dr. Suzanne M. Lainson

Tr_Salutation, Tr_First_Name, Tr_Middle_Name, Tr_Last_Name, Tr_Suffix

Trimmed Name

Suzanne Lainson

Tr_FirstName, Tr_LastName

The Its For You application includes three functions that return formatted strings as Per the above table. The first lines of the Xbasic code that defines these functions are shown below:

FUNCTION fullfamiliarname as C (familiar as C, lastname as C )
FUNCTION fullformalname as C (salutation as C, firstname as C, middlename as C, lastname as C,  suffix as C)
FUNCTION trimmedName as C (firstName as C, lastName as C )

The full function code for fullfamiliarname() is shown below:

Figure 67

In order to properly return a value to the script or expression that invokes a function, the function name itself must be set to the value you wish returned. In this function the variable fullfamiliarname (which is the same as the function name) is assigned the formatted name string.

This function take two character string parameters as inputs (they are local variables named familiar and lastname ). It applies the alltrim() built-in function to each string to trim off leading and trailing blanks and then combines these values with one blank space to return a formatted name. This name string is assigned to the variable fullfamiliarname. It is returned to the expression that invoked the function.

Figure 68

Two character strings, "Penelope " and " Snodgrass" , are input to the function and the formatted name string is output to the screen.

Three calculated fields are defined that are displayed on the Adiministration form. These calculated fields, in turn, each call one of the functions: fullfamiliarname(), fullformalname(), and trimmedName().

In the Administration form of the Its For You application, three fields on the screen display formatted versions of the users name. Below, you see the Calculated Fields dialog box superimposed over the Administration form.

Figure 69

In this exercise you will create function to take a firstname and lastname character strings and a logical value if that person is an admin. If the person is an admin then a string will be returned showing the full name followed by the string "(Admin)". If the person is not an admin only the full name will appear.

Exercise 14 - Defining a new Global Function 

  1. Click on the Code tab of the Control Panel window.

  2. Click on the New button and then choose Function shown in figure 70.

    Figure 70
  3. For the Function Name enter:

    fnadmin
  4. Leave the Return Type as "Character".

  5. Enter the following three arguments (parameters) for the function:

    fname

    Character

    lname

    Character

    admin

    Logical

    Figure 71
  6. Press OK to save the function definition. Alpha Anywhere opens the Code Editor and displays a prototype of the function. A prototype is the shell of a function without any Xbasic commands to process it. The prototype tells you what type of value the functions returns and what parameters (and parameter types) the function expects as input.

    • Figure 72
    • Alpha Anywhere adds an open and close parenthesis to the function name to differentiate a function from a script.

      The FUNCTION command opens with the word FUNCTION followed by the name, the word AS, and the type of the return value. Next is a parentheses, any parameters (expressed as Parameter name, the word AS, and the type of the parameter), a comma to separate multiple parameters, and a closing parentheses. (If there are no input parameters, you still need the open and close parentheses.)

      Next comes your code. Remember, in order for the function to return a value to the calling expression, you must assign that value to a variable with the same name as the function. Finally, the function definition ends with the END FUNCTION command.

  7. Enter the following four lines between the FUNCTION ... and END FUNCTION lines.

    fnadmin = alltrim(fname) + " " + alltrim(lname)
    if admin then
       fnadmin = fnadmin + "(Admin)"
    end if
    When you press Enter after typing the line if admin then, Alpha Anywhere will automatically create the line end if for you.
  8. Select Code > Check Syntax. You should see this:

    • Alpha Anywhere can check that the syntax of your script is correct. This is not the same as a logic check. A syntax check means that you typed in the Xbasic commands the correct way and that all the expressions make sense. Whether they give you the result you really want is up to you to judge.

  9. Delete the word "FUNCTION" from the last line of the script and select Code > Check Syntax. Alpha Anywhere responds with an error pop-up message indicating the Xbasic command FUNCTION...END FUNCTION is incomplete.

  10. Put the word "FUNCTION" back in.

  11. Press Save to save the function.

    After you save the function in Step 11, the * (asterisk) next to the function name in the Code Editor tab will be gone. Whenever an * appears next to a script name in the editor, it indicates you have made changes to that script that you have not yet saved.

  12. Press the Interactive tab to see the Interactive window.

  13. Enter the following commands:

    dim name1 as C
    dim name2 as C
    dim is_an_admin as L
    name1 = " George"
    name2 = "Michael "
    is_an_admin = .T.
  14. Now enter the following:

    ? fnadmin(name1, name2, is_an_admin)
    • Alpha Anywhere replies with:

      = George Michael (Admin)
  15. Enter the following:

    is_an_admin = .F.
    ? fnadmin(name2, name1, is_an_admin)
    • In this invocation of the fnadmin() function, name2 is given as the first parameter and name1 as the second. The function does not care what variables or values you enter as long as the type of the variable matches the parameter definition in the function code. Here, the character string, name2, will be assigned to the parameter, fname, in the function code itself. So name2 will come out first.

      Alpha Anywhere replies with:

      = Michael George
  16. Close the Code Editor.

To recap, most functions you create are called Global functions because they are available to be used in part of your Alpha Anywhere application. However, you can create a local function. A local function is a function defined in a script or another function.

So a function script FUNCTION1 could contain a second function definition named FUNCTION2. Here is the code for FUNCTION1 :

function FUNCTION1 as C (name1 as C, birthdate as D)
  function1 = alltrim(name1)+ +function2(birthdate)
end function
function FUNCTION2 as C (bday as D)
   if age(bday) > 40 then
       function2 = "has already reached the big 4-0"
   else
        function2 = "is still at most 39 years old"
   end if
end FUNCTION

FUNCTION1 calls FUNCTION2. And like a local variable, a local function is only visible or available to the function it is defined within.

Whereas you would be able to call FUNCTION1 from anywhere in Alpha Anywhere, you could not call FUNCTION2 from another script.

Xbasic Explorer - Learning Xbasic

You saw previously that you can look for a global function using the Function Finder window. There is another tool available in Alpha Anywhere that enables you to quickly lookup and identify built-in functions, global functions and other Xbasic commands, variables, and components. This tool is called the Xbasic Explorer.

Figure 73

The Xbasic Explorer is available whenever you are in the Code Editor. You can load it from the toolbar by clicking on the wrench symbol . Or you can select View > Xbasic Explorer from the Code Editor menu.

The Xbasic Explorer, shown at right, is a pop-up window that shows in a tree structure the categories of all the different Alpha Anywhere components that you use when you create a script in Xbasic.

When you expand any of the nodes of the tree, you will see all of the available Xbasic entities for that category or sub-categories, if applicable.

For example, if you expand the "Functions" node, you will see the categories for all the built-in functions. If you expand one of the sub-category nodes, you will see all the functions classified in that sub-category as shown in the next figure for the date functions category.

Figure 74

Under the "Functions" node, you will be able to see all of your own functions. The Xbasic Explorer brings together in one conveniently accessible window all of the possible entries for Xbasic script command lines.

In addition, you can drag-and-drop any of the leaf node entries from the Xbasic Explorer into the Code Editor. This is especially useful when you are selecting objects and their corresponding methods or properties. If you drag-and-drop an object method or property, the absolute reference to that object method or property will appear in your script.

Exercise 15 - Drag-Drop from the Xbasic Explorer 

  1. Open the Interactive window and the Xbasic Explorer.

  2. Expand the "Objects" node

  3. Expand the "Windows" node You see the "Code Editor" window object:

    Figure 75
    The Xbasic Explorer only shows active objects. (In other words, form or other layouts that you have defined in your database but are not currently loaded will not appear). Since the Code Editor is the only active window, that is the only window object shown.
  4. Expand the "Code_Editor" node.

  5. Expand the "Properties" node.

  6. Drag the property "window_title" into the Interactive window. To drag, click and hold down the left mouse button on top of the item you wish to drag. While still holding down the mouse button, move the mouse cursor to the place you wish to move the reference to. When you have reached the position you want, release the mouse button to drop the reference.

    • Figure 76
    • When you drop the item, the Interactive window will show:

      Code_Editor.window_title
    • which is the full reference to the window property.

  7. Put a question mark and space at the front of the line and press Enter. Alpha Anywhere shows:

    = Code Editor
  8. Drag another reference for "window_title" into the Interactive window.

  9. At the end of the new line you are creating type:

    • = "My Code Editor Title"
    • and press Enter. The Code Editor window has a new title.

  10. On a new line type:

    • Form.load("Sign In")
    • and press Enter. When you press Enter, the Xbasic Explorer is refreshed. Now that you have loaded another window, the Xbasic Explorer shows both the "Code Editor" and "Sign In" windows in the "Objects" tree branch.

  11. Type:

    • :Sign_in.close()
    • and press Enter. The reference to the Sign In window is no longer in the Xbasic Explorer.

  12. Close the Xbasic Explorer and the Interactive Window.

Global Scripts - Learning Xbasic 

At the beginning of the book, you saw the script Choose Msg Receiver which is part of the Phone Messages database. Choose Msg Receiver is used when you take a message using the Its For You application. The script is invoked when you press the For button on the Take A Message screen. The script pops-up a dialog box as shown below.

Figure 77

This script is not a function nor is it attached to an object event. Most of the scripts you have analyzed up until now have been one of these two types. Choose Msg Receiver is a Global Script. It was created in the Code Editor by using the N ew > Script using Xbasic editor command. Like a global function, it is accessible (callable) from any other script in the active database.

Unlike a function, a script does not take input parameters, nor does it return a result. But as you saw in the section on variable scoping, data can be passed to a script via shared and global variables.

Generally, you would create a global script when you want to create an Xbasic program that you can invoke in different places of your application or even share among applications. Even if you change the script slightly to accommodate different needs, it is convenient to keep the script as a separate entity (rather than attached to a specific event).

The Choose Msg Receiver script is invoked from the OnPush event of the For button with this Xbasic command.

script_play_local("Choose Msg Receiver")
The script_play command loads and runs the Xbasic commands contained in the named script. The script_play_local command makes any local variables in the calling script available to the called script. See Variable Scoping in this book for more information.

The Choose Msg Receiver script displays a list of message recipients from the message_tr table. When a recipient has been selected, fields in the Take Message form are updated to reflect the name and id of the recipient.

The script performs the following actions:

  • It declares a number of variables used in the script.

  • It checks the number of entries in the message_tr table and defines and initializes array variables to hold data from the table.

  • An Xdialog command opens the pop-up Xdialog box and displays the choices from the array variables.

  • After a selection is made in the Xdialog box, some fields on the Take Message form are updated.

The complete script along with an analysis of how it works follows. Various variables used in the script are declared using dim commands. These variables are all local to this script and are discarded when the script is finished running.

dim rc as N
dim selection as C
dim i as N
dim indx as N

A count of the number of records in the message_tr table is stored in the rc variable. This count is necessary so that the next two array variables, names and nameslist can be declared big enough to accommodate all the records in message_tr.

rc = reccount("message_tr")

names is an array variable of type pointer. nameslist is an variable array of type character. names will be populated with all the field information for each record of message_tr. nameslist will then be populated from the data stored in names.

dim namesrc as P
dim nameslistrc as C
  • Variable arrays 

    Variable arrays are multidimensional and accessed via their index. So a variable declared as dim myvariable3 as C is declaring myvariable to be an array variable holding up to three possible values (sort of three similar variables accessed with the same name). Each value is assigned and accessed using the appropriate index value. Different array variable values are called elements of the array.

    myvariable1 = The   myvariable2 = Big     myvariable3 = Chill
    ? myvariable2 = big
  • Variable arrays are useful for storing lists of items. The nameslist character array above will store message receiver names:

    ? nameslist = 1 = "Mike Ahn"
    2 = "Steve Bacon"
    3 = "George Bush"
    4 = "Duane Casey"
    5 = "Hill Clinton"
    6 = "Pat Douglas"
    7 = "Doc Foglia"
  • This is how the namelist array would appear in the Interactive window. From this listing you can see that:

    nameslist2 = "Steve Bacon"
    nameslist6 = "Pat Douglas"
  • Pointer arrays 

    Pointer arrays can extend in two dimensions. A pointer array variable can be used to load all the field data of a table by record number. When a pointer array is loaded using the appropriate Xbasic command (e.g. initialize_from_table ) each index entry of the array represents a row from the table.

    Each array element points to a string for each table row of every field name from the table and the fields corresponding data. The field names and values from the database become properties of each array element. Data is then accessible from the variable array by index (element) value (which displays all the properties) or by specifying the array element property you are interested in.

    ? names1 = TR_ADMINISTRATOR = .F.
    TR_FAMILIAR = "Mike"
    TR_FIRST_NAME = "Michael"
    TR_ID = "003"
    TR_LAST_NAME = "Ahn"
    TR_MIDDLE_NAME = "K."
    TR_PASSWORD = "password"
    TR_SALUTATION = "Mr."
    TR_SUFFIX = ""
    ? names2 = TR_ADMINISTRATOR = .T.
    TR_FAMILIAR = "Steve"
    TR_FIRST_NAME = "Steven"
    TR_ID = "013"
    TR_LAST_NAME = "Bacon"
    TR_MIDDLE_NAME = ""
    TR_PASSWORD = "password"
    TR_SALUTATION = ""
    TR_SUFFIX = ""
    .
    .
    .
  • Pointer array variable values are accessible via their index value as shown at left or by their property. (Each field from the source table becomes a property of each pointer array element). So you can access the following variable values:

    ? names2.TR_LAST_NAME = "Bacon"
    ? names8.TR_FIRST_NAME = "Carlos"
    ? names1.TR_FAMILIAR = "Mike"

This command fills the pointer array names with data from the message_tr table. All records are loaded (the second parameter is a filter) and they are ordered by the tr_last_name field (the third parameter).

names.initialize_from_table("message_tr", ".T.", "tr_last_name")

This loop cycles through the number of records in message_tr and using the fullfamiliarname() function loads each element of the nameslist array with the character string of the persons familiar name. The parameters for the fullfamiliarname() function are read from the appropriate property values of the names array (which was in turn populated with data from the table itself by the command above).

for i = 1 to rc
   nameslisti = fullfamiliarname(namesi.tr_familiar, namesi.tr_last_name)
next

The variable selection is set to the first name stored in the nameslist array. Selection is used in the following ui_dlg_box() command to hold the value selected from the list box. By setting it before ui_dlg_box() is called, you can control the initial value highlighted in the list box.

selection = nameslist1
ui_dlg_box("Choose Message Recipient",<<%a% {Xsize=2} {position=remember} {font=tahoma,12,bold} {text=35,2selection}; {font=tahoma,9}
.40,20selection^#nameslist!change||<&OK!ok_button>
%a%,<<%b%
if a_dlg_button = "change" then
   indx = nameslist.find(selection)
   a_dlg_button = ""
else if a_dlg_button = "OK" then
end if
%b%)

The ui_dlg_box() command is what actually pops-up the Xdialog box on the screen and accepts the user input. To learn all about the details of the writing an Xdialog command please refer to Learning Xdialog.

topparent:tr_id.value = namesindx.tr_id
topparent:reciever.refresh()

Using Action Scripting

You have covered a lot of ground in this introduction to Xbasic. You have learned about different Xbasic commands, objects, variables, and tools and how to use them in creating Xbasic scripts and functions. And while you have learned a lot about Xbasic, there are many areas of using Xbasic that still remain for you to discover.

One of the best ways to learn more about Xbasic is to use Alpha Anywheres Action Scripting. When you use Action Scripting Alpha Anywhere actually writes Xbasic code for you.

Action Scripting is a tool that can be used when you are creating any script (whether a global script or an event script). When you build a script using Action Scripting you do not type Xbasic commands into an editor. Instead you pick from a menu of dozens of categorized actions that you wish to have your script perform.

When you select an action that you want performed, you then answer a series of questions and prompts for information where you define exactly how you want that action to behave. The Action Scripting tool then creates the Xbasic commands that will perform your desired action. However, a script created using Action Scripting displays symbols and descriptions that represent the actions. Each row of an Action Script is a separate action. Actions in scripts can be edited and modified or deleted altogether. You can string together many actions in one script and change the order that the actions are executed in.

You can also mix actions with Xbasic code. And you can convert an Action script completely into the underlying Xbasic code.

Action Scripting can be used to learn Xbasic. By creating a script first in Action Scripting, you focus on what you want the script to do, rather than how it does it. You can then convert the script from Actions to Xbasic commands and expand or modify the script directly using Xbasic.

When you choose to create a new script using Action Scripting you see the following display in the Code Editor : Picture

Figure 78

Use these commands to insert , delete and edit actions. The up/down arrows allow you to change the order of actions. The If command enables you to conditionally process or skip over actions or groups of actions.

You do not enter Xbasic commands directly n this window. You select from the command menu at the top edge of the window. When you press Add New Action this pop-up window appears:

Figure 79

Action List 

The Action list show all the categories of available actions. When you select a category in the left box, the available actions for that category appear in the right box.

This window shows all the actions listed alphabetically.

After you highlight the action you wish to include in the script you click OK at the bottom of the window. Alpha Anywhere then asks you the details of how that action should work. and includes an Action icon in the script window.

If you select the "Set Field Values" action from the "Fields" category as shown here:

Figure 80

Alpha Anywhere displays a pop-up window where you define the characteristics of this action as shown to the right in Figure 81.

Figure 81

You tell Alpha Anywhere where the field is (on which object), which field to set, and how the value should be set. When you have finished telling Alpha Anywhere how this action should be performed, Alpha Anywhere adds an action icon in the script as shown in figure 82.

Figure 82
This script now has a single action specified. To see or change what field this action acts on, you can use the Edit Action command.

If you right-click on the highlighted Action item, you can select View Xbasic from the drop-down menu as shown in Figure 83:

Figure 83

This menu choice lets you see the Xbasic code that Alpha Anywhere writes behind the scenes in order to perform the Action you specified through the action scripting menu.

When you select View Xbasic, Alpha Anywhere displays an Xbasic Code where you can view the code for a single action or all the actions you have defined in the script.

In Figure 84 is the pop-up window displaying the Xbasic code that underlies the Set Field Value action defined in Figure 82.

Figure 84

You can see that Alpha Anywhere generates more Xbasic commands for an action than you might have expected to perform the requested task. In creating Xbasic scripts via Action Scripting, Alpha Anywhere includes comments and a lot of error checking code. The code generated for this action makes sure that the window that contains the field you want the action to change actually exists before it tries to change the field.

By examining the code that Alpha Anywhere writes to perform Action Scripting actions, you can pick up programming skills and techniques that will improve the efficiency and reliability of your code. Action scripting can also help speed up your work. When you have a script with multiple actions, you can quickly specify tasks you want accomplished through Action Scripting.

Then you can view the Xbasic code for all of the actions in one screen. (via the All Actions tab in the Xbasic Code window). You can copy the code to the clipboard and continue working on the script using the Xbasic Code Editor and editing the Xbasic code directly if you wish.

You have reached the end of Learning Xbasic.

End Note

Hopefully, you have gotten a feel for the power and flexibility of the Xbasic commands and components. You have learned about all the major programming methods and tools that Alpha Anywhere provides with the Xbasic language.

You have seen how you can use Action Scripting to have scripts written for you. Using Action Scripting and then studying the code is an excellent way to get up to speed with Xbasic. You can learn more techniques by running the Its For You application, understanding what it does, and then exploring the scripts that are part of the application in the Code Editor.

Read the Introduction to Action Scripting and Learning Xdialog books that accompany this book to go in-depth with both of these areas.

You will soon be writing your own Xbasic global scripts, events and functions that will enable you to create database applications faster and easier than ever. Watch for new and more features in Xbasic and Alpha Anywhere coming soon.

And, finally, thanks for using Xbasic and Alpha Anywhere and Above: The Revolutionary Way To Build Sophisticated Database Applications!