Kevin Howard and Robert J. Hallett Jr.

Robust Application Development in ArcView

ABSTRACT: As GIS becomes a more mainstream activity, applications now require greater flexibility and functionality while maintaining simple-to-use graphical user interfaces.This paper explores the challenges involved in developing large, sophisticated ArcView applications that are designed to work on a variety of platforms with various datasets and user requirements. It will address:


Introduction

Since the introduction of ArcView, users have requested increasingly sophisticated applications which meet a number of basic criteria. The applications: Unfortunately, it is extremely common when opening an application to encounter a sequence of messages asking the user to re-establish the link between the application and the data it needs:

This is because the paths to all of the data within the ArcView application are saved as part of the Project file.

Once the application has started successfully, any number of fatal error messages can occur, from the 'Nil Object' error:

Through the 'Unrecognized Command':

To the ever faithful, bad Script Parameters:

This document discusses how to avoid these error messages happening, together with other points that should be taken into account when developing a fully customized ArcView application that is robust and maintainable.


Structured Programming

When developing an application - regardless of the development environment - a structured programming methodology should be followed. Although it is not always necessary that the complete design cycle is followed for every application (some systems may be too small to benefit from the time invested in the full design process), several criteria must be taken into account in the application design and implementation.

What is the Problem?

An application must correctly solve the problem it is intended to solve. To fully determine the problem, the developer must talk with the client (whether internal or external), and if possible the potential users, to discuss their requirements and their expectations of the system. From this discussion, as well as any supporting documentation, an application specification document should be produced that clearly details the problem and proposes a method of solution.

There are many cases where good applications have been developed that do not solve the problem, or do not live up to the users expectations. In both of these cases, the application (regardless of its technical merit) will either not be used by the users, or will require extensive and costly reworking.

Application Design

Although this document is not intended to address design methodologies, some form of design analysis must be undertaken prior to the implementation of a system. The design process should analyze the problem specification, and produce a detailed design document giving: It should be noted that due to the simplistic nature of many ArcView applications, and even many of the Avenue scripts within complicated applications, much of the application design is pre-determined by User Interface requirements (see below). Especially with ArcView applications, the User Interface is the area where most of the design analysis should take place.

Reliability

Another criteria of a "well developed' application is that it must be reliable. No significant program can ever be proven to be completely error free. This is because the variety of combinations of test data required to test a program completely is virtually infinite.

Hence, in the design phase all of the possible areas where reliability may be a problem should be addressed. The results of this analysis will either take the form of improved checking within the system, or (in the last resort) the placing of restrictions on the applications performance envelope. In all cases, the client should be made fully aware of the potential problems, and the steps that have been taken to address them.

Maintainability

A third criterion of a well programmed application is that it must be easy to read and easy to maintain. Programs are written to be read. In the past, good programmers were often thought to be those who could write clever and tricky code that ran in the shortest amount of time and used the least amount of resources. Typically, once a program is put into production, the clever and tricky code has to be maintained by another programmer. (The maintenance of a program involves removing subsequent errors that may be found and altering the code to reflect changes in the program's specification). Today, maintenance costs can be significantly (orders of magnitude) higher than the development costs. Hence, in an effort to minimize costs, it is essential that easy-to-read and easy-to-maintain programs are developed.


Graphical User Interface Design

GUI development is a complex and sophisticated area of system design. The GUI should reflect the needs of the users (not the system designer or GIS administrator) and reduce the learning curve associated with the system. Modern computer systems succeed or fail by the quality of their user interface. Regardless of how good the underlying functionality of the system is, if the users do not find the interface intuitive and easy to use, the complete system will not be used. Merely making cosmetic changes to a standard interface and adapting existing functionality is no longer acceptable to most users. This only succeeds in confusing the user. The customized interface should add value to the system, and this must be apparent to the user in order to make them want to use the system.

Modern user-interface design methodologies involve the users from the initial design to final implementation. If one of these methodologies is not followed, and the user is just presented with the prototype, it must be designed by experienced individuals familiar with the design methodologies and with users' "normal" requirements.

ArcView Menus

The menu system is the means by which the user interacts with the application. The menu system should allow access to all of the functionality normally available in ArcView, together with all of the customized functionality.

To minimize confusion, all of the customized options required for the application should be made available on a customized ArcView menu system. The series of customized menus (one or more for each ArcView document class) should be the primary menus for the application.

This involves creating a customized menu system, as well as performing small modifications to a copy of related native ArcView menu system. However, at no time should the native ArcView menu system be altered. If a menu system is to be customized (regardless of how minor the modification is), a copy of the native ArcView menu should be taken and it is this copy that is modified.

Toggling Menus

To minimize confusion, the native and customized ArcView menus should be kept separate, with a method implemented which allows toggling between the two menu systems. This can be either in the form of a toggle button (which should be in the same location on both menus), or via a menu option. In both cases, a small amount of customization must be performed on the native ArcView menu system.

Dynamic Menus

The customized menu should be dynamic so as to reflect the data that has been loaded into the application. This allows tailoring of the menu system for specific instances of the application.

User Feedback

Throughout the ArcView application, feedback should be given to the user as to the current state of the system. This can be in the form of using the wait cursor (av.UseWaitCursor) if a long process is being undertaken (i.e. query of an Oracle database), or use of the status bar giving the percentage of the process completed (i.e. accessing records in a table).

The status bar should also be used to provide useful information to the user. This is useful as it does not delay the execution of a script. This can be in the form of brief help information, the results of a calculation, or details of the current process.


ArcView Project File

A Project is the file ArcView uses to organize and store information. Projects keep any combination of related ArcView documents, Views, Tables, Charts, Layouts, and Scripts, together in one file. A Project also stores references to the spatial and tabular attribute information used within the system.

Hence, by opening and closing a single Project, the user can open or close all of the components needed for a specific task or application. For example, Views and related Scripts can be saved in a single Project file. This ensures that when working with a View the required Scripts are also available. In addition, Projects can be used to keep joined Tables, or Tables and Charts together.

Although this seems the most logical way of storing the information, it does create several problems.

These problems can be minimized by storing the data references externally from the Project file. This approach provides a number of advantages:


Data Formats

Naming Convention

With the introduction of ArcInfo 7.0, Esri reformatted data workspaces to conform to the MS-DOS standard of 8.3 filenames - up to an 8 character name and a 3 character extension. This allows data to be transferred more easily between UNIX-based and MS-DOS-based systems. Hence, any data tables accessed or created should, wherever possible, conform to the 8.3 convention.

Spatial Data

Spatial data is at the heart of every ArcView application. Spatial data is geographic data that stores the geometric location of particular features, along with attribute information describing what these features represent. Spatial data is also known as digital map or digital cartographic data.

With the introduction of ArcView 3.0, spatial data can be stored in several different formats. Each format has advantages and disadvantages.
 

Format Advantages Disadvantages
ArcView Shapefile Comparatively small size. 

Comparatively fast drawing speed.

Can only have one feature type per file 

Cannot be used with route systems

ArcInfo Coverage Fully compatible with ArcInfo. ArcView cannot repair an ArcInfo workspace. So if one coverage becomes corrupted, the whole workspace has to be replaced.
ArcInfo Librarian Allows coverages to be stored as tiles. 

Setting the View's Area of Interest means only the tiles required for the View are accessed, improving speed.

Difficult to implement.
ArcStorm Improved version of ArcInfo Librarian. Latest version unstable.
 
Note: ArcInfo 7.0 has routines for converting from shapefiles to coverages (shapearc) and vice-versa (arcshape).

Wherever possible, it is recommended that shapefiles are used as the standard spatial data format. If ArcInfo coverages are to be used, each separate spatial layer should be stored in its own workspace, so if it becomes corrupt, only one spatial layer needs to be replaced/repaired.

ArcView can also display AutoCAD drawings and Image data (i.e. satellite images, air photographs and other remotely sensed or scanned data). The valid image formats include ArcInfo GRID data, TIFF, Windows Bitmap (.bmp), TIFF/LZW compressed image data, and Sun rasterfiles.

Attribute Data

Native ArcView can access three different types of attribute data.
 
Format Advantages Disadvantages
Tab or comma Delimited Text Virtually all applications (Word processors, spreadsheets etc.) can access/display 

Easily understood format

Cannot edit the data within ArcView, without exporting it to INFO or dBase format
INFO More secure than other file formats (tables encoded in workspace) Can not delete INFO tables, although they can be overwritten 

If an INFO table becomes corrupted, the whole workspace has to be replaced 

Proprietary file format

dBase Industry-wide standard format 

Native ArcView format 

Can be accessed from other applications

Can be accessed from other applications - users can change data
 
Note: ArcView cannot directly access fixed-length ASCII text files. These must be pre-processed into one of the known formats before the data can be accessed.

ArcView can also connect to database servers, such as Oracle, Ingress or Sybase, and retrieve records using SQL queries. For details on this process, refer to the ArcView Help section entitled "Connecting to a database to create a table", "Setting up a database connection with ODBC" (MS-Windows) and "Logging into a database with the Database Integrator" (UNIX).


Help Files

All ArcView projects should have on-line Help. This documentation can be based on the User Guide and other technical documents written for the project.

The method of creating the Help files depends upon both the operating system and the required sophistication of the Help system.

MS-Windows 3.1x, NT and '95

Microsoft (and other compiler developers) distributes a Help file compiler called WinHelp. This processes a file into the required format to be displayed by the Windows Help system. However, there are several methods for generating the initial file.

ArcView Method

ArcView contains an internal Help file generation system that uses control codes within a rich text format (RTF) file. Refer to ArcView for Windows on-line Help file under the topics "Building You Own Help File", "Building context-sensitive help in ArcView for Windows" and "Running a script from a help file".

Word Processor Method

There are many utilities available (both commercially and share/free-ware) which can generate a Windows Help file from a Word processing document. This has the advantage that the written documentation will already exist in a word processor document, although because it is outside of the ArcView system, it is unlikely that Scripts could be run directly from the help file.

UNIX Method

Creating Help files for use with ArcView for UNIX requires use of an internal ArcView Help file generation system. For details, refer to the ArcView for UNIX on-line Help file under the topic "Building you own Help file".


Extending ArcView

Extension Methods

The basic functionality of ArcView can be extended using a number of different systems. Each one has a different level of sophistication with a proportional level of effort to implement. The actual extension method to use depends upon the application, although there are a number of factors to take into account:

"Command-line" Interface

The simplest way of extending ArcView is to call an external program by using the System.Execute Avenue command. While this method works on any operating system for which ArcView is available, it lacks control since no parameters can be returned to the application.

"Table" Interface.

This method is similar to the command-line interface apart from the fact that all of the data being passed is written to tables which are processed by the external program. While it is still relatively simple to implement and works on all operating systems, it still requires some command-line parameters to be passed, as well as extensive data checking in the creation/reading of the table.

Neuron Data

Before the introduction of ArcView 2.1, Neuron Data Open Interface was virtually the only viable method for producing sophisticated applications for use with ArcView. However, the current ability to use DDE and DLL as well as ArcView Extensions has negated the requirement to use this extension method.

Dynamic Data Exchange (DDE)

DDE can be used to inset data into a third-party application (i.e., MS-Excel). This method requires a DDE server to be running upon the third-party application. There are also a limited number of data types that can be passed with a relatively slow data transfer rate. It is also complicated to implement and requires different implementations for different operating systems.

Dynamic Link Libraries (DLL)

Use of DLL's provides the closest integration between ArcView and the extension application, with a fast transfer of a wide variety of data types. However similar to DDE, it is complicated to implement and requires different implementations for different operating systems.

ArcView Extension

Since the introduction of ArcView 3.0, native Extensions that use Avenue code can be developed. Use of ArcView Extensions provides a module environment for developing ArcView applications by grouping related functionality within one Extension. However, care must be taken when developing the Extensions so that they do not interfere with the rest of the application. This may happen if the Extension resets global variables or the object tags on documents. If variables need to be stored, each Extension maintains a Dictionary that can be accessed via the aExtension.GetPreferences. Refer to the Extension Discussion document in the ArcView on-line Help file.

DDE/DLL Development Environment

Creation of DLL's (or any of the other extension methods) can be performed in a number of development environments. The choice of development environment depends upon the type of application, the specific operating system, and whether the code has to be portable across operating systems.

It is recommended that the preferred development environment will be a high-level programming language (C/C++ or Visual Basic) together with a cross-platform set of GUI development libraries.


Programming Style

The way a programmer writes code is as individual as the way that they talk. The programming style adopted should be flexible enough to take into account these programmer preferences. However, the code produced should have clear and concise comments and make good use of indentation so that another programmer should easily be able to understand a code fragment. Whatever style the programmer adopts, they should remain consistent throughout the code. For example, the same number of indentation characters should always be used, and meaningful names should always be used to describe data items and functions.

Naming Conventions

Avenue Scripts

To help in the process of identifying the purpose of a function and for grouping functions into similar areas, a standardized naming convention should be adopted. Restrictions on the naming convention depend upon the code type being written, the hardware type and portability requirements.

As there are few length restrictions on Avenue script names, the script name should give a fairly detailed idea as to its function. Scripts normally fall into 3 main categories:

These types of scripts can use the following naming convention. In defining the menu path, a delimiter should be used. It is recommended that the pipe character (|) should be used for this function.
 
Name Description
Custom View : Area | State.Click Associated with the State option under the Area option respectively of the Custom View GUI.
Custom View : Area | State.Update Associated with the State option under the Area option respectively of the GIS View GUI. This script is called when the option receives the Update event from the system.
Custom View Button : Toggle GUI.Click Associated with menu button for swapping the active GUI to the alternate GUI. The script is run when the button is clicked.
Custom View Tool : Identify.Click Associated with the Identify tool on the Custom View. The script is run when the tool is clicked.
Custom View Tool : Identify.Apply Associated with the Identify tool on the Custom View. The script is run when the tool is applied.
GIS/Trans : Get Theme Type Utility script that finds the type of a theme. This is of general use (i.e. should be part of a software library) so has the 'GIS/Trans' prefix.
App : Startup The Project startup script. This is implementation specific so has the prefix App.

Local Variables

Although a developer may believe they are saving time by using short or cryptic variable names, in the long term this is a incorrect belief. Variable names should clearly indicate the purpose of the variable.

Esri has defined a convention as to the naming of variables created directly from Avenue classes.

Examples:
theProject = av.GetProject
theDoc = av.GetActiveDoc
Examples:
theDocs = av.GetDocs
theThemes = theView.GetThemes
Example:
theThemes = theView.GetThemes
for each aTheme in theThemes
  aTheme.SetActive(FALSE)
end

Global Variables

Global variables should use the same naming conventions as local variables, with the addition of the prefixed "_" character.

Traditionally, due to the way ArcView processed scripts at startup, all of the global variables had to be placed in one script which is named to be the first script in alphabetical order. For example, the script could be called aaGlobals. With the introduction of ArcView 2.1, this restriction was removed. However, all global variable definitions should be kept in one script.

Script Headers

For each script, a header must be included to give all of the relevant details relating to that function. From this header, a programmer unfamiliar with the code should be able to understand the purpose of the function, together with the parameters and data that it requires to execute correctly.

However, the script name should give a good idea as to the purpose of the script. This is especially the case with Avenue scripts as described above. Also as many Avenue scripts are of a simplistic nature, the time expended on creating the header may never be recouped in future use of the code.

Although the actual headers will vary with the programming language, certain flags should be reserved for use in all headers. This means that set names are used for specific header fields, and has the added benefit that programs could be written that could automatically generate documentation form the source code. This process can be partially automated by changing the default ArcView project to always create a customized script.
 

Flag Name Description
N File name  
C Copyright  
D Description Description of the function purpose
P Parameters List of any arguments that need to be passed to the file.
R Returns The object that is returned by this Script
G Global Variables used List of any global variables used. Also states if the variable needs to be predefined or if it is set during the function execution.
E Called Scripts List of calls that the function makes.
S Called By List of other functions that call this function.
K Keywords Space-delimited list of keywords for searching purposes.
O Operating system dependencies Any dependencies that the function has on the operating system.
H History History for the function. Include items such as version number, date, author and a brief message of changes performed

Comments

In commenting a piece of code, the programmer must weigh the time required to fully comment the code, against the time it would take a person who is unfamiliar with the code to understand it without comments.

The comments should be clear and concise!

Appendix A gives examples of commenting an Avenue script.

Indentation

Good use of indentation should be used to help identify the flow of the script. Consistent indentation (i.e. number of spaces) should always be used. It is recommended that a 2-space character indentation is used. This size of indentation is partially imposed by ArcView as this is the indentation used by the 'Shift Lines Left' and 'Shift Lines Right' Script Editor buttons.

To help reduce the number of levels of indentation, care should be taken to exit a script once an error has occurred or no further processing is required. A good example of this is a MsgBox that allows the user to press Cancel.

Example:
  ' Performing an inappropriate check requires the remainder of the script to
  ' be indented
  theResult = MsgBox.ChoiceAsString(theChoiceList,
                                    "Select the required choice",
                                    "Title")
  if (nil <> theResult) then
    ' Perform processing within the indentation
       :
       :
  end
 

  ' Careful checking of results remove a level of indentation
  theResult = MsgBox.ChoiceAsString(theChoiceList,
                                    "Select the required choice",
                                    "Title")
  if (nil = theResult) then
    return nil
  end

  ' Processing can now be performed without requiring indentation

This correct checking of returned values also means that the processing level is reduced as the remainder of the script does not have to be parsed.


Writing Robust Avenue Code

Whenever code is written, it should be written so that it will continue to function (i.e. not crash) even if invalid data is supplied to it, or the code is trying to execute with the system in an unexpected state.

ArcView Versions

With the release of ArcView 3.0, there are 4 different versions of ArcView currently in use - v1.0, v2.0, v2.1x and v3.0x.

To combat incompatibilities between the different versions, Esri has included an av.GetVersion command which returns the version number plus any patch letter code (i.e. "2.1b"). Therefore, any version specific code must be bracketed by this command

Example:
  if ("2.1" = av.GetVersion.Left(3)) then
    ' Do v2.1x specific code
  else
    ' Do v3.0 specific code
  end

Note: This command was not available in v2.0. Hence, the first knowledge the application would have that it is running on version 2.0 is when it causes a system crash on the av.GetVersion command!

Note: The if.then.else statement should be written in order of version number. This means that if a command does not change in a future version, no Avenue code will have to be altered.

Note: The av.GetVersion command returns the full ArcView version. Hence, to perform version specific code, the left-most three characters need to be compared.

Returned Values

When a Script completes execution either successfully or with an error condition, a value is returned to the calling Script. This value should indicate the success or failure of the Script. By Avenue convention, when an error occurs nil is returned to the calling Script. However, the nil value is returned if a Script is exited without a return call. Hence, even if a Script does not return an object, it should return a non-nil value (TRUE) to indicate it executed successfully. The type of returned value should depend upon a number of factors. The proposed types of returned values are as follows:
  1. Boolean. No Avenue object is returned so TRUE is returned if the script terminated successfully, FALSE otherwise.
  2. Numeric Error Code. If a script does not return an Avenue object, but the state of termination of required, a numeric error code can be returned. The value 0 should indicate success, whilst errors should be indicated by various negative values.
  3. Avenue Object. If on successful termination, a script returns an Avenue object, a error condition should be indicated by returning a nil. Although numeric error codes could be returned for failure, the calling script must filter the returned value.

Checking Returned Values

Throughout Avenue code, the Scripts frequenty ask objects to return both values and pointers to other objects. In most cases, it can be assumed that these operations will succeed, especially when interrogating standard objects.

Example:
  theProject = av.GetProject
  theFTab = theTheme.GetFTab

However, in some cases the Script may be asked to find a field in a Table, open a disk file, or process the response of a message box. In all cases, the returned value may be incorrect (null) or invalid (nil). The response to these statements must be checked.

Example:
  ' Access the field XYZ in the FTab
  theField = theFTab.FindField("XYZ")
  if (nil = theField) then
    MsgBox.Error("Failed to find field 'XYZ' in table '"+theFTab.GetName+"'",
                 Script.The.GetName)
    return FALSE
  end

  ' Select one of the entries from the Choice List
  theChoice = MsgBox.ChoiceAsString(theChoiceList,
                                    "Select the required choice",
                                    "Title")

  ' If Cancel was pressed, then nil is returned
  if (nil = theChoice) then
    exit
  end

Clear Error Messages

The above example highlight the need for clear error messages, for both the developer and the user. This not only assists the programmer in tracking down errors but also gives the user a clear indication as to the position of Script errors.

The developer should also pick the level of the error and display the correct ArcView dialog.

Note: It is not possible to obtain the "stack" of calling Scripts so as to give more informative error reporting.

Checking Script Parameters

If a Script is called with a set of parameters, these parameters must be parsed to check they are of the correct format. This traps a number of problems (too few/many parameters, incorrect classes etc.) that would cause problems later in the Script.

Example:
  ' It is assumed that a Script exists that takes 2 parameters:
  ' - the parameters passed to the Script (as a list)
  ' - a list of the required classes for those parameters
  if (av.Run("App : Verify List", {SELF, {String, Theme, FTab}}).Not)
    MsgBox.ListAsString(SELF,
                        "Invalid Parameters",
                        Script.The.GetName)
    exit
  end

Note: In the above code fragment, the message gives the name of the script that the error occurred within as its title. This gives the developer an idea as to where an error has occurred.

Checking the State of the System

Many Scripts require the ArcView system to be in a particular state (i.e. a View is the currently active document) for them to function correctly. It is a big assumption that because a Script is attached to a View GUI, that the active document is a View. For example, when the system is changing state (i.e. displaying a Table of data associated with a Theme), as many Scripts are event driven (i.e. update scripts) a View update Script may be called when a Table document is active.

This problem also arises when an error occurs in an update Script. ArcView immediately displays the offending Script, so the active document is now a Script Editor (SEd). However, the update event still has to be processed by all of the other update Scripts.

Hence, whenever the state of the system is requested, the response must be checked.

Example:
  theActiveDoc = av.GetActiveDoc
  if (theActiveDoc.Is(View).Not) then
    MsgBox.Error("The Active Document is not a View",
                 Script.The.GetName)
    exit
  end
 

Use of Menu Update Scripts

Many options are only valid when the system is in a particular state. For example, many options work on the active Themes in a View, while "Show Table" is only valid for Feature Themes in the View, not Image Themes.

Checking for these conditions can be performed by the Script associated with the Click/Apply operation. However, by performing the checking in the Update script, the menu option can be enabled/disabled as appropriate. This gives several benefits:

Variable Comparison

The above examples also show the correct method for checking values. This is namely that the constant should be on the left of the equality sign. This has the benefits that: Example:
  theChoice = nil ' This will set the variable theChoice to nil
  nil = theChoice ' This will produce an interpreter error

Note: Although the proposed method of variable comparison is not strictly necessary in Avenue, it is good practice to use one standard across programming languages. Hence, when a programming language is used that has different comparison and setting symbols (i.e. Pascal (= and :=) and C/C++ (== and =)), the proposed comparison method can still be used.

Use of Example Datasets

While it is generally agreed that using a reduced dataset during the coding process has many benefits, care must be taken during this process not be develop code that is optimized for the reduced dataset. This may manifest itself in problems displaying large datasets (i.e. landuse), or the use of Theme Legends that may be OK at a "zoomed-in" level but may not be correct when looking at the whole dataset.

Use of the 'Tab' character

While most programming languages treat Tab characters as "white space", just like "space" and "carriage return" characters, strange things can happen if you insert tabs in code. Such bugs can be especially difficult to detect because Tab characters cannot easily be seen in the code.


Conclusion

By using a consistent set of standards, ArcView developers can build upon the work undertaken for previous applications creating:


Appendix A - Example Avenue Script

This script shows how the parameters to a script can be parsed to check for problems.

'N  Name           : ADM : Verify List
'
'C  Copyright      : (c) GIS/Trans, Ltd. 1997
'
'D  Description    : Verifies a set of Objects in a List against a set of Classes in a List. The two
'D                 : Lists must be the same size.
'
'P  Parameters     : List - List of Classes
'P                 : List - List of Objects
'P                 : Boolean - TRUE if errors should be displayed in a MsgBox. FALSE otherwise
'
'R  Returns        : Boolean - TRUE if the List of Objects is valid against the List of Classes.
'R                 :           FALSE otherwise
'
'E  Called Scripts : ADM Message : Set Error
'
'S  Called By      : ADM Message : Display
'S                 : ADM Message : Get
'S                 : ADM Message : Get Level
'S                 : ADM Message : Get Title
'
'K  Keywords       : Parameters Verify
'
'O  OS Depends.    : None
'
'H  History        : K Howard    1-Jan-97  Initial Coding
'

' Check to make sure that a list of 2 items as been passed
if (nil = SELF) then
  av.Run("ADM Message : Set Error", {"nil pointer passed to function",
                                     Script.The.GetName})
  return nil
end
if (SELF.Is(List).Not) then
  av.Run("ADM Message : Set Error", {"SELF object is not a List - it is a '"+SELF.GetClass.GetClassName+"'",
                                     Script.The.GetName})
  return nil
end

' Retrieve the parameters from the list
parametersList = SELF.Get(0)
if (nil = parametersList) then
  av.Run("ADM Message : Set Error", {"Parameters List pointer is nil",
                                     Script.The.GetName})
  return nil
end
if (parametersList.Is(List).Not) then
  av.Run("ADM Message : Set Error", {"Parameters List is not a List - it is a '"+
                                       parametersList.GetClass.GetClassName+"'",
                                     Script.The.GetName})
  return nil
end

' See how many parameters are passed. If there are only two, set the
' report errors flag to TRUE
if (3 = SELF.Count) then
  reportErrors = SELF.Get(2)
else
  av.Run("ADM Message : Set Error", {"There is an invalid number of parameters ("+SELF.Count.AsString+
                                       ") in the passed list",
                                     Script.The.GetName})
  return nil
end

' Get the passed class definitions
classList = SELF.Get(1)
if (nil = classList) then
  if (reportErrors) then
    av.Run("ADM Message : Set Error", {"Class List pointer is nil",
                                       Script.The.GetName})
  end
  return nil
end
if (classList.Is(List).Not) then
  if (reportErrors) then
    av.Run("ADM Message : Set Error", {"Class List is not a List - it is a '"+classList.GetClass.GetClassName+"'",
                                       Script.The.GetName})
  end
  return nil
end

' Check to see that there is the the same number of passed parameters
' as there are class definitions
if (parametersList.Count <> classList.Count) then
  if (reportErrors) then
    av.Run("ADM Message : Set Error", {"Number of parameters ("+parametersList.Count.AsString+
                                         ") and classes ("+classList.Count.AsString+") do no match",
                                       Script.The.GetName})
  end
  return nil
end

' Check each parameter against it's class definition
listSize = parametersList.Count
for each i in 0..(listSize - 1)
  aParameter = parametersList.Get(i)
  aClass = classList.Get(i)
  if (nil = aClass) then
    if (reportErrors) then
      av.Run("ADM Message : Set Error", {"Failed to get Class "+i.AsString+" from Class List",
                                         Script.The.GetName})
    end
    return nil
  end

  ' Check to see parameter is of the correct class
  if (aParameter.Is(aClass).Not) then
    if (reportErrors) then
      av.Run("ADM Message : Set Error", {"Parameter "+i.AsString+" is not of type '"+aClass.GetClassName+"'"+nl+
                                           "It has Class '"+aParameter.GetClass.GetClassName+"'",
                                         Script.The.GetName})
    end
    return nil
  end
end

' The parameter list has been successfully verified
return TRUE


Kevin Howard
Senior Analyst
GIS/Trans, Ltd.
675 Massachusetts Ave
Cambridge, MA 02139

Tel: +1 (617) 354-2771
Fax: +1 (617) 354-8964
E-Mail: khoward@ma.gistrans.com
WWW: www.gistrans.com
 

Robert J. Hallett Jr.
Analyst
GIS/Trans, Ltd.
675 Massachusetts Ave
Cambridge, MA 02139

Tel: +1 (617) 354-2771
Fax: +1 (617) 354-8964
E-Mail: rhallett@ma.gistrans.com
WWW: www.gistrans.com