Title of Paper
Authors' Names
Abstract
Paper Body
1. Introduction
2. General
Conversion Guidelines
Heading = "My
Command"
Default = True
ians = MsgBox.YesNoCancel(Msg,
Heading, Default)
if (ians = Nil)
then
.... do something
end
if (ians.Not)
then
.... do something
else
.... do something
end
Dim Default
As Boolean
Dim ians
As Integer
Msg = "Okay
to continue ?"
Heading = "My
Command"
Default = True
Call avMsgBoxYesNoCancel(Msg,
Heading, Default, ians)
If (ians
= vbCancel) Then
.... do something
End If
If (ians
= vbNo) Then
.... do something
End If
If (ians
= vbYes) Then
.... do something
End If
If (a.NE.B) then x = y End
If (a <> b) then
x =
y
End If
"Error
Trapping":
Finally, a good feature to take advantage of in the VB/VBA
environment, which is not available in Avenue, is
the ability to trap errors.
Error trapping provides the developer a means to avoid
application runtime errors, which typically result in the application
to cease to operate properly. By avoiding application
runtime errors, the application can still be used to perform other
functions, should an error be encountered, rather than simply
"dying". This results in giving
the application a more professional appearance.
The code below demonstrates the use of error trapping:
'
Public Sub ShowErrorTrapping()
'
Dim pMxApp As IMxApplication
Dim pmxDoc As IMxDocument
Dim pActiveView As IActiveView
Dim pMap As IMap
'
' ---This
statement informs the application where to
' ---branch
when an error is detected in the procedure
On Error GoTo Errorhandler
'
' ---Get
the active view
Call avGetActiveDoc(pMxApp, pmxDoc,
pActiveView, pMap)
'
' ---do
something else
.
.
.
'
' ---At
this point, our work is done
Exit Sub
'
' ---Handle
any errors detected in the procedure
Errorhandler:
'
' ---Display
detected error number and a description
MsgBox "Error " & Err.Number & "
- " & Err.Description & _
Chr(13) & "Subroutine:
ShowErrorTrapping"
'
End Sub
Note that the introduction of comments in VB/VBA is the same as in Avenue with the exception that comments appear in the color green. In addition, syntax errors detected in VB/VBA appear in the color red as soon as the typing of a statement has been completed. This is quite a good feature, but it has a bothersome side effect. In addition to displaying the erroneous statement in red, VB/VBA also beeps and displays an error message box, which must be closed before the user can continue typing.
3. Application
- Document Avenue Wraps
vThemesList = theView.GetVisibleThemes
Dim pMxApp As
IMxApplication
Dim pmxDoc As
IMxDocument
Dim pActiveView
As IActiveView
Dim pMap As
IMap
Dim vThemesList
As New Collection
Call avGetActiveDoc(pMxApp,
pmxDoc, pActiveView, pMap)
Call avGetVisibleThemes(pmxDoc,
vThemesList)
The first point that needs to be
made, in reviewing the above code, is that in Avenue a developer
applied a request to an object, which resulted in another object
being created, vThemesList in the above Avenue example.
This approach is not possible using ArcObjects.
Therefore, to simulate the Avenue approach, Avenue Wraps
provides a subroutine or function to perform the function of the
Avenue request by using the argument list in the subroutine or
function to pass objects in and out.
The second point is that a List
object in Avenue translates to a Collection object in VB/VBA.
Note that List objects in Avenue are zero based, while
Collections begin at the index value 1.
For example, the first visible theme in vThemesList would
be found by issuing the following statement:
firstVTheme = vThemesList.Get(0)
while in VB/VBA
the statement would appear as:
firstVTheme = vThemesList.Item(1)
Note that the Avenue request Get
becomes Item in VB/VBA. So
that, the search for and revision of lists into collections, the
change of Get to Item, and the altering of the indexing could
be done at the start of the conversion process.
The final point is that the Avenue code contains two lines of code, while the VB/VBA code contains seven, the first five of which are declaration statements. Thus, even though there is a one to one correspondence between the Avenue requests and the wraparounds, the number of lines of VB/VBA code is greater than its Avenue counterpart due to the declaration statements. To make the VB/VBA code easier to read, it is suggested that all of the declaration statements be placed at the top of the procedure, rather than scattered throughout the subroutine or function. One procedure, which one may consider, is to introduce the declaration statements within the code where new variables are first encountered, and then, after the code has been tested, move the declaration statements to the top of the procedure in the same sequence of occurrence.
4. File
Input and Output Avenue Wraps
For example
the Avenue statement to open a file for writing would appear as:
aLineFile = LineFile.Make
(aFileName, #FILE_PERM_WRITE)
while using
Avenue Wraps, the statement would look like this:
Dim aFileName
As String
Dim aLineFile
Set aLineFile
= avLineFileMake(aFileName, "WRITE")
Note the
use of the word Set.
In VB/VBA when dealing with objects the keyword Set
is used to create an object. In this example, aLineFile
is a file system object.
In addition, in Avenue there were enumerations (predefined
values or constants), which certain requests recognized.
Avenue Wraps simulates enumerations by using strings
that reflect the enumeration, such as "WRITE" for "FILE_PERM_WRITE".
5. Theme
and Table Avenue Wraps
For example
the following Avenue code writes a value, 24, to a specific record,
12, in an FTab:
theTheme = theView.FindTheme("L_0ln")
theFTab = theTheme.GetFTab
col = theFTab.FindField("MAP")
rec = 12
theFTab.SetEditable(true)
theFTab.SetValue(col, rec, 24)
theFTab.SetEditable(false)
Using Avenue
Wraps, the above code could be converted as follows:
Dim pMxApp As
IMxApplication, pmxDoc As IMxDocument
Dim pActiveView
As IActiveView, pMap As IMap
Dim theTheme
As String
Call avGetActiveDoc(pMxApp,
pmxDoc, pActiveView, pMap)
theTheme = "L_0ln"
Call avGetFTab(pmxDoc,
theTheme, theFTab, pFeatCls, pLayer)
Call avSetEditable(pmxDoc,
theTheme, true)
Call avSetValue(pmxDoc,
theTheme, col, rec, 24)
Call avSetEditable(pmxDoc,
theTheme, false)
The Avenue
Wraps code shown above could be used on either an FTab or
a VTab, because the "wraparounds" check if the given
name passed in corresponds to a theme or to a table.
Note that the FindField request has a direct counterpart
in the ArcObjects world.
This is one of the very, very few examples where a "wraparound"
was not required.
As stated
above, the "wraparound", avSetValue, operates
on either an FTab or a VTab.
However, it cannot be used to store geometry (a feature's
shape). In this case
the "wraparound", avSetValueG, must be used. The reason is that when
storing attribute information with avSetValue,
the ArcObjects Value property
is used. However,
in order to store geometry (a feature's shape), the ArcObjects
Shape property needs to be used. Since there are two different
properties, two different wraparounds were created,
one to store attribute data and the other to store geometry.
Continuing with the example above, the Avenue code below would store a two-point line in record 12 of the FTab:
aShape = Polyline.Make({{20000.0,
20000.0, 30000.0, 25000.0}})
col = theFTab.FindField("SHAPE")
theFTab.SetEditable(true)
theFTab.SetValue(col, rec, aShape)
theFTab.SetEditable(false)
Using Avenue
Wraps, the above code could be converted as follows:
Set aShape =
avPolyline2Pt(20000#, 20000#,
30000#, 25000#)
Call avSetEditable(pmxDoc,
theTheme, true)
Call avSetValueG(pmxDoc,
theTheme, col, rec, aShape)
Call avSetEditable(pmxDoc,
theTheme, false)
In reviewing
the above Avenue Wraps code, note the # character in the
"wraparound" avPolyline2Pt. When a number is hard coded
with .0, .00, .000, etc., VB/VBA will remove the zeros and replace
them with the # character.
In addition, note that there is no direct Avenue counterpart
to the "wraparound", avPolyline2Pt. During CEDRA's conversion
process, in an effort to minimize the amount of recoding, certain
"wraparounds" were developed that do not have corresponding
Avenue requests, but satisfy a need in that they facilitate the
conversion process. In
the CEDRA software there were a lot of cases in which two point
lines were being created using the double left ({{) and the double
right (}}) brace characters.
Rather than using the "wraparound", CreateList
and adding point features to the lists (reference is made
to the Section 8 example), the "wraparound", avPolyline2Pt
was created.
As a matter
of fact, there are a number of "wraparounds" which do
not have an Avenue counterpart, but when used, greatly help in
the conversion of Avenue to VB/VBA code.
Finally,
a good feature to take advantage of is the Undo / Redo capabilities
of ArcObjects. The wraparound,
avSetEditable, when used with
the false parameter on a theme will not terminate the editing
of the theme. Rather, the wraparound
only flushes any buffered writes there may be on the theme.
Thus, the theme remains in an editable state. This is intentionally done
so that the developer can take advantage of the Undo / Redo capabilities. To do so, the wraparounds,
avStartOperation and avStopOperation,
should be used. These
wraparounds begin and terminate an edit operation
which is added to the Editors operation stack.
This enables the end user to perform an Undo or Redo operation.
The avStartOperation subroutine is called
after the theme has been made editable. The avStopOperation
subroutine is called when the desired editing has been completed.
A call to the avStopOperation
subroutine must be made if a call to the avStartOperation
subroutine has been issued.
There is no limit to the number of times these subroutines
can be called within an edit session. The wraparound,
avStopEditing, will terminate
the Editor saving any edits that may have been made.
6. Feature
Selection Avenue Wraps
theTheme = theView.FindTheme("L_0ln")
theFTab = theTheme.GetFTab
col = theFTab.FindField("Deposits")
sel = theFTab.GetSelection
total = 0.0
for each rec in sel
deposit
= theFTab.ReturnValue(col, rec)
total = total + deposit
end
Using Avenue
Wraps, the above code could be converted as follows:
Dim pMxApp As
IMxApplication, pmxDoc As IMxDocument
Dim pActiveView
As IActiveView, pMap As IMap
Dim theTheme
As String
Call avGetActiveDoc(pMxApp,
pmxDoc, pActiveView, pMap)
theTheme = "L_0ln"
Call avGetFTab(pmxDoc,
theTheme, theFTab, pFeatCls, pLayer)
Call avGetSelection(pmxDoc,
theTheme, sel)
Call avGetSelectionIDs(sel,
selList)
total = 0#
In reviewing
the above Avenue Wraps code, note the use of the "wraparound",
avGetSelectionIDs. This "wraparound"
returns a collection of OIDs (object identification numbers) for
each of the selected features.
So that, rather than looping on the selected set, sel,
as was done in Avenue, a loop is performed on the collection,
selList. An
OID is extracted from selList and a feature extracted from
the pFeatCls object. Using the feature, pFeat,
the deposit value is extracted and added to total.
This example illustrates the main difference between Avenue
and ArcObjects, in that, in Avenue manipulation of data was performed
on FTab or VTab objects.
Using ArcObjects, manipulation of data is performed using
the IFeature interface, for FTab's, and the IRow interface, for
VTab's. Obviously,
this difference poses an obstacle in converting Avenue code, but
using the "wraparound", avGetSelectionIDs, a
work-around is fairly easily achieved.
7. Message
and Menu Boxes Avenue Wraps
MsgBox.Info("A sample
message string.", "MsgBox Test")
would be converted
using Avenue Wraps as:
Call avMsgBoxInfo("A
sample message string.", "MsgBox Test")
Internally,
avMsgBoxInfo calls another subroutine
passing information, which denotes that the Info request is to
be simulated. By taking
the approach to programmatically modify a single form, we avoid
the alternative of having to create a unique form for every type
of dialog box that is used in the CEDRA software.
So that, the Avenue requests Warning, YesNo and YesNoCancel,
as well as Info, all end up calling the same subroutine which
in turn uses the same Avenue Wraps form, MessageBox.
Likewise, the other Avenue message box requests, Choice,
Input, List, MultiInput and MultiList all end up using the Avenue
Wraps form, VDialogBox. Thus, based upon what information
is passed into the controlling subroutine, the appropriate dialog
box is displayed.
In addition, to simply the conversion of the standard MsgBox requests, additional "wraparounds" were developed to provide for more sophisticated dialog boxes, such as dialog boxes that could contain "drop-down" items in addition to typical data line items. Shown below is an example of a dialog box created with the VDBbuild subroutine. So that, not only is VDBbuild used to create the Choice, Input, List, MultiInput and MultiList dialog boxes, it can also be called directly to create the dialog box below.
Additionally,
some CEDRA commands required the use of a horizontal version of
VDBbuild. In
the ArcView GIS 3.x environment, the Dialog Designer was used
to create the appropriate dialog boxes.
In Avenue Wraps, the subroutine HDBbuild
was written to provide the developer a horizontal implementation
of VDBbuild. Shown below is an example
of a dialog box created by HDBbuild.
The VDBbuild
and HDBbuild wraparounds
are examples of where the extended functionality in VB/VBA was
used to enhance the appearance of CEDRA's applications.
8. Geometry
Avenue Wraps
aPoint = 5000.0 @ 5000.0
There is
no counterpart for the @ character, so
that, the above statement needs to be rewritten as:
Dim aPoint As IPoint
Set aPoint = avPointMake(5000#, 5000#)
q
To
create a polyline, which is comprised of four vertex points in
Avenue, the developer could use the statement:
Dim shapeList As New Collection
Dim partList As New Collection
Dim aPt1 As IPoint, aPt2 As IPoint, aPt3 As IPoint, aPt4
As IPoint
Dim myLine As IPolyline
Call CreateList(shapeList)
Call CreateList(partList)
partList.Add aPt1
partList.Add aPt2
partList.Add aPt3
partList.Add aPt4
shapeList.Add partList
Set myLine = avPolylineMake(shapeList)
9. User
Document Interaction
10. Graphics
and Symbols
aShape = Point.Make(5000.0, 5000.0)
theShape = GraphicShape.Make(aShape)
With ArcObjects, every type of graphic element uses a different interface. Hence, the easiest way to implement graphic element support is to have the developer pass in the type of graphic element that is being operated on. As such, the above Avenue statement would be converted into:
Dim aShape As IGeometry
Dim theShape As IElement
Set aShape
= avPointMake(5000#,
5000#)
Set theShape = avGraphicShapeMake("MARKER",
aShape)
The first
argument in avGraphicShapeMake denotes the type of graphic
element to be created. This value could be PEN,
MARKER or FILL, which correspond to line, point and polygon graphic
elements, respectively.
Another
difference between the Avenue requests and the "wraparounds"
is that in the ArcGIS environment, the developer can control which
layer (annotation target) the graphics are added to.
In Avenue all graphics, in a view, were added to the view's
graphic list. In the ArcGIS environment,
the developer has the option of adding graphics to the basic graphics
layer or to any other graphics layer that may exist.
This gives the developer a lot more flexibility in managing
graphic elements.
11. Classifications
and Legends
thmName =
"SomeName"
aTheme = theView.FindTheme(thmName)
aLegend = aTheme.GetLegend
aLegend.SingleSymbol
Dim pMxApp As
IMxApplication
Dim pmxDoc As
IMxDocument
Dim pActiveView
As IActiveView
Dim pMap As
IMap
Dim thmName As String
Dim aDesc As String, aLabel As String
Dim pSym As ISymbol
Call avGetActiveDoc(pMxApp,
pmxDoc, pActiveView, pMap)
thmName =
"SomeName"
Call avSingleSymbol(pmxDoc, thmName,
aDesc, aLabel, pSym)
Call avSingleSymbol(pmxDoc, thmName,
NULL, NULL, NOTHING)
12. Utility
Macros
13. Avenue
Wraps Forms
14. Application
Deployment Methods
Shown below is a possible directory structure for converting
an Avenue based application, or developing a new ArcMap based
application.
As
can be seen, a top-level directory is created for the application. Within this directory,
three sub-directories are created, Testing, VBAcode
and DLL, although any naming convention can be used.
These directories will contain certain information, as
described below, which will be established during the conversion
or development cycle.
The Testing
directory is to contain the ArcMap document file appl.mxd,
where the application will be initially developed and debugged.
As mentioned above, all of the code modules, forms, etc.
are stored within the document file, just like an ArcView GIS
3.x project file contains all of the dialogs and scripts that
comprise an application. Therefore, for safety reasons,
it is suggested that the ExportVBAcode wraparound
be used to export the modules, forms, etc., within the ArcMap
document file, into the VBAcode folder.
In so doing, should "tragedy" strike the ArcMap
document file, all would not be lost.
The VBAcode
directory, as stated above, provides a repository for the
code modules forms, etc., external to the ArcMap document file.
In addition to providing this service, it is the code modules
in this directory that will be added to the VB project file, which
is used to create the Active X DLL.
The DLL
directory is to contain the VB project file appl.vbp,
which builds the Active X DLL for the application.
In addition, all of the Class modules and forms comprising
the Active X DLL will also be stored in this directory.
Note that the forms created in the VBA environment
within the ArcMap document file will need to be recreated in the
VB environment. The code modules in the
VBAcode directory will be added to the VB project file
without modification. Thus, the DLL directory
will contain only those modules that are specific to building
the Active X DLL. Note that the VB project
file does not actually contain the code.
The VB project file only contains pathnames to the files
referenced in the project file.
So that, if one of the files referenced by the VB project
file is deleted or modified, the VB project file will not function
as desired.
15. Summary
Acknowledgements
Appendixes
End Notes
References
Author Information
Constantine N. Tonias,
P. E. is a professional civil engineer and president of The CEDRA
Corporation. Graduating
from Rensselaer Polytechnic Institute with Bachelor of Science
and Masters of Science degrees in Civil Engineering he oversees
the research and development operations of the corporation. Mr.
Tonias has been responsible for the
development of The CEDRA System, an interactive design and drafting
system particularly tailored for the civil engineering practice,
major portions of which have been ported to ArcView®
GIS 3.x and ArcGIS.
His computer experience also includes the conversion of
numerous computing programs between various computing hardware
and operating system environments.
Organization: The CEDRA Corporation
Address:
Phone: 585-232-6998
Fax: 585-262-2042
E-mail: cedra@cedra.com
Elias C. Tonias, P. E., is a professional
civil engineer and a pioneer in the application of computers in
Civil Engineering. Mr.
Tonias holds a Bachelor of Science degree
in Civil Engineering from Rensselaer Polytechnic Institute and
a Masters of Science from The Ohio State University and is a technical
consultant to The CEDRA Corporation in the development of engineering
computing software. He
has written extensively in this field, and has managed the development
of a wide variety of software.
Having been involved with software development since the
very early days of the computer age, he was forced to go through
a series of program conversions from computer environment to computer
environment.
Organization: Tonias Engineers
Address:
Phone: 585-232-6995
Fax: 585-262-2042
E-mail: ect@tonias.com