Using VBA in AutoCAD r14 / 2000 to control layer standards. Introduction
Have you ever wondered why drawings can contain many layers, but objects such as
"text", "dimensions" and "hatch" do not always end up on the
correct layers? This article addresses a potential solution to that problem. First, I talk
briefly about layer standards and show you how to create a small VBA project for AutoCAD
r14.01 or 2000 to control layers. Next, I show how to load or embed a VBA project in a
drawing with AutoCAD 2000. Third, I look at how to use the VBA Manager to load multiple
VBA projects in AutoCAD 2000. Fourth, I demonstrate how to manage and load programs using
the improved "appload" command in AutoCAD 2000. And finally, I offer some hints
on how to expand the sample code to accommodate multiple disciplines.
Layer Standards
Several times in the past, I have been asked by new users, "Why doesn't AutoCAD
put text objects on the text layer and hatch objects on a hatch layer, etc?" The
answer is that Autodesk has designed AutoCAD to give users unrestricted flexibility with
layer names and to allow companies to create or adopt any layer standard. Unfortunately,
this flexibility of open-architecture layer names within AutoCAD has allowed many an
AutoCAD user to recklessly create layer names. Sometimes, it seems, layer names are chosen
according to what pops into the user's head while staring at the AutoCAD layer dialogue
box! And after several other users in the same company use these layer names, the results
are then called the "company layer standards".
There are many recognized layer standards in existence, such as AIA, Master
Format, British BSD, etc. that companies can adopt, but it seems to be more
trendy for companies to make up their own layer names and standards on the fly. The
rationale seems to be "Those other existing layer standards could not possibly
accommodate the type of work that our company does. " How many times have you come
across a drawing (done by someone else, of course) containing layers called dim, dimension,
and dimensions? The purpose of this small VBA project is to create a mini
layer-manager that enforces layers for "text", "hatch" and
"dimension" objects as they are created in a drawing. Text goes on to a layer
called "text", hatch patterns are placed on a layer called "hatch",
and dimensions are placed on a layer called "dim". Seems almost too obvious!
Sure, this is a rather simplistic way of managing layers for objects, but it works! For
those interested in modifying the code to fit your own company layer standard or for
working with multiple disciplines, take a look at the section called "Extending the
Code" later in the article.
I was recently exposed to the "AcadDocument_BeginCommand" sub-program when I
began a technical review for WROX press of a book called AutoCAD VBA Programmers
Reference (currently being written by Joe Sutphin). Joe's example code made me think,
"Wow! I could apply his technique to do some layer management of my own!" In the
program outlined in this article, I access this sub-program to check on the command being
accessed by AutoCAD. Once the command being used is checked, it creates the appropriate
layer settings before AutoCAD starts the command. Therefore, when a user enters the text
command, my VBA program sets-up and/or creates the text layer, transparently in the
background, before the text command starts. The sub-program
"AcadDocument_BeginCommand" picks up on AutoCAD commands used in LISP programs
and any alias (defined in the ACAD.pgp) that references an AutoCAD command. For example,
if a user types "BH" (standard short cut alias for the "bhatch"
command), the sub-program "AcadDocument_BeginCommand" still traps the
"bhatch" command.
The compliment to the "AcadDocument_BeginCommand" sub-program is the
sub-program "AcadDocument_EndCommand". I use the latter sub-program to check for
the name of the command that has just been completed. If the command name matches my
criteria (using the "select case" method), the layer is set back to the original
layer in use before the command was started. Look at the following commented code to see
if you can follow what is happening inside the VBA program. Start with the
"AcadDocument_BeginCommand" sub-program and finish with the
"AcadDocument_EndCommand" sub-program.
A Look at the Code

This work is licensed under a
Creative
Commons Attribution-ShareAlike 2.5 License.
' Using Option Explicit -- you must explicitly declare all variables using the
' Dim, Private, Public, ReDim, or Static statements.
' If you attempt to use an undeclared variable name,
' an error occurs at compile time.
' Option Explicit is a great way to make sure you do not have wonkie typo mistakes
' in your code.
Option Explicit
' set the public object current Layer to be an AutoCAD Layer
Public objCurrentLayer As AcadLayer
' set the public object Previous Layer to be an AutoCAD Layer
Public objPreviousLayer As AcadLayer
Private Sub AcadDocument_BeginCommand(ByVal
CommandName As String)
' Save the current / active AutoCAD layer
Set objPreviousLayer = ThisDrawing.ActiveLayer
' Check for the folowing cases of the AutoCAD command.
Select Case CommandName
' Check the AutoCAD command,
' is there a match for TEXT, MTEXT, or DTEXT
Case "TEXT", "MTEXT", "DTEXT" ' then do the
following..
' check for to see if the current layer is Text
' if the current layer is not TEXT then set up the TEXT
' layer for use.
If Not ThisDrawing.ActiveLayer.Name = "TEXT" Then
' set up the TEXT layer
' this layer will be created if it does not exist
Set objCurrentLayer = ThisDrawing.Layers.Add("TEXT")
' make the TEXT layer blue
objCurrentLayer.Color = acBlue
' turn the TEXT layer ON
objCurrentLayer.LayerOn = True
' Thaw the TEXT layer
objCurrentLayer.Freeze = False
' Unlock the TEXT layer
objCurrentLayer.Lock = False
' Make the TEXT layer the current
' active layer in this drawing.
ThisDrawing.ActiveLayer = objCurrentLayer
' end of if checking for TEXT being the current layer.
End If
' Check the AutoCAD command,
' is there a match for HATCH, or the BHATCH command.
Case "HATCH", "BHATCH"
' check for to see if the current layer is HATCH
' if the current layer is not HATCH then set up the HATCH
' layer for use.
If Not ThisDrawing.ActiveLayer.Name = "HATCH" Then
' set up the HATCH layer
Set objCurrentLayer = ThisDrawing.Layers.Add("HATCH")
' make the HATCH layer red
objCurrentLayer.Color = acRed
' turn the HATCH layer ON
objCurrentLayer.LayerOn = True
' Thaw the HATCH layer
objCurrentLayer.Freeze = False
' Unlock the HATCH layer
objCurrentLayer.Lock = False
' Make the HATCH layer the current
' active layer in this drawing.
ThisDrawing.ActiveLayer = objCurrentLayer
' end of if checking for HATCH being the current layer.
End If
' check for AutoCAD dimension commands..
Case "DIMALIGNED", "DIMANGULAR", "DIMCENTER", _
"DIMCONTINUE", "DIMDIAMETER", "DIMLINEAR",
"LEADER", _
"DIMORDINATE", "DIMRADIUS", "DIM", "DIM1"
If Not ThisDrawing.ActiveLayer.Name = "DIM" Then
Set objCurrentLayer =
ThisDrawing.Layers.Add("DIM")
objCurrentLayer.Color = 140
objCurrentLayer.LayerOn = True
objCurrentLayer.Freeze = False
objCurrentLayer.Lock = False
ThisDrawing.ActiveLayer = objCurrentLayer
' end of if checking for DIM being the current layer.
End If
' end of the Select
End Select
' end of Private Sub AcadDocument_BeginCommand
End Sub
Private Sub AcadDocument_EndCommand(ByVal
CommandName As String)
' Check for the folowing cases of the AutoCAD command that has just ended.
Select Case CommandName
' check for a match on the following AutoCAD commands
Case "HATCH", "BHATCH", "MTEXT", "TEXT",
"DTEXT", _
"DIMALIGNED", "DIMANGULAR", "DIMCENTER", _
"DIMCONTINUE", "DIMDIAMETER", "DIMLINEAR",
"LEADER", _
"DIMORDINATE", "DIMRADIUS", "DIM", "DIM1"
' make the current active AutoCAD layer the previously saved layer.
ThisDrawing.ActiveLayer = objPreviousLayer
' clear the objCurrentLayer
Set objPreviousLayer = Nothing
End Select
' clear the objCurrentLayer
Set objCurrentLayer = Nothing
' end Private Sub AcadDocument_EndCommand
End Sub
The Results
Below is an AutoCAD drawing created
using the standard "mtext", "bhatch", and "dimlinear"
commands with the above VBA code. The AutoCAD drawing started with only layer
"0". No user-creation of layers or changing of layers was required. And most
significantly every object is on the correct standard layer.
The VBA Manager
AutoCAD 2000 drawing files can have a VBA program embedded into the drawing file. The
VBA project then becomes part of the "DWG" file and can be active each time the
drawing is edited in AutoCAD 2000. To load or embed a VBA project in a drawing within
AutoCAD 2000 use the VBA manager. Start the VBA manager from the AutoCAD command prompt by
typing "vbaman". AutoCAD 2000 allows multiple VBA projects to be loaded.
Multiple users on a network can now also access VBA projects without the problems found in
the AutoCAD r14 version of VBA that created a "file in use locking error".

Embedded VBA Macros
An embedded project allows a drawing file to become a
self-contained wrapper for a VBA application or macro. Hmmm
Have we just entered a
new era of the AutoCAD 2000 drawing macro virus? I strongly suggest that all users start
the VBA manager and enable the macro warning options to be set (click on the Macros
button in the VBA manager then click on the Macros Options button). [Image of macro options here]
The Appload command
The VBA manager provides an excellent way to manage VBA programs on a day-to-day
development basis. But, for a tighter, long-term management strategy to control VBA, LISP,
and other custom programs loaded into AutoCAD 2000, I recommend looking at the
"appload" command. If you have used this command in AutoCAD r14 in the past,
your initial thoughts on "appload" in AutoCAD 2000 might be: "So what? I
found the old "appload" command practically useless for loading programs. I had
to manually click on each LISP routine in the history list and I had to do this each time
AutoCAD loaded!" In AutoCAD 2000, the "appload" command gets a major
"inter-facelift" and capability improvement.

The appload command still handles the chore of loading user-selected ObjectARX Files
(*.arx), AutoLISP Files (*.lsp) and ADS (*.exe) programs on a user select-and-load basis.
However, the best new feature of the improved "appload" command is the addition
of the Startup Suite. The icon for this, inside the "appload" program, looks
like an over-stuffed briefcase (see [Appload dialogue box figure]
above) The Startup Suite (run from within the appload program) is capable of automatically
loading multiple ObjectARX Files (*arx), AutoLISP Files (*.lsp), VBA Files (*.dvb),
ObjectDBX Files (*.dbx), Visual LISP Executables (*.vlx), and Fast-load AutoLISP Format
(*.fas). Programs added to the Startup Suit are loaded automatically for each drawing file
within AutoCAD 2000. Once added, these programs automatically load in every new session of
AutoCAD 2000. Aha a truly useful feature!

The appload interface change can make finding the area for creating a history list of
favorite programs to load somewhat confusing for the seasoned r14 user. I am of the
opinion that users just starting in AutoCAD with AutoCAD 2000 will have a technical
advantage over longtime AutoCAD users. New users do not have to unlearn how to use AutoCAD
commands. How many "experienced" AutoCAD r14 users never got a grip on grips or
direct distance entry? My favorite quote from a harried AutoCAD 12 user was "I'm too
busy to learn this new stuff that will help me become more productive." Hmmm
what's wrong with this picture? The AutoCAD 2000 appload does not write a separate text
file into each directory from which AutoCAD 2000 starts: no more ugly AutoCAD r14
appload.dfs files in drawing directories. The AutoCAD 2000 appload information is written
directly into the Windows system registry each time the user runs the appload command from
within AutoCAD 2000. Obviously the average (or even above-average) AutoCAD user is not
going to mess with the Windows system registry to get at the appload settings. However,
for developers, the Windows system registry and the settings in the appload section for
AutoCAD allow yet another method of setting up the loading of a custom application during
an AutoCAD 2000 session. Developers (and end users) can stop using the acad.lsp to load
their programs.
Extending the Code
After reading this article, some of you may have your own ideas on how to improve upon
this code to accommodate your company's standards and/or specific discipline (e.g.
structural, electrical, mechanical, etc.). You could easily create an interface to select
the discipline (via a VBA form with a listbox) of your choice to force objects onto the
corresponding layer. For example, in the structural discipline, hatch objects could be
forced onto the "structural-hatch" layer.
I leave you with a code snippet to get you started.
If Not ThisDrawing.ActiveLayer.Name = strDiscipline & "-HATCH" Then
' set up the discipline specific HATCH layer
Set objCurrentLayer = ThisDrawing.Layers.Add(strDiscipline &
"-HATCH")
Hint: Your interface would drive the string variable "strDiscipline".
In Conclusion
I have looked at the need for layer standards and have presented VBA code that could
provide a partial solution to enforcing layer standards. The code is easily customizable
to accommodate multiple disciplines and standards. I have touched upon the new AutoCAD
2000 -VBA manager and the improved appload command including the new StartUp Suite option.
If you need sample code for developing an interface for this VBA project or want more VBA
code examples (including this one) visit my Website at www.contractcaddgroup.com. Happy programming!
|