Lesson 14
Table Access

This lesson explains tables, sometimes called "symbol tables," and how AutoLISP can extract information from them.

What are tables?

AutoCAD uses tables to store information about named items that you create.  For example, when you create a new layer, you give it a name and probably assign a particular color and linetype.  In addition, the layer will have a certain status depending on how you use it.  It may be the current layer, or it may be frozen, or locked.  And the information about each other layer in the drawing will have different data, but it will be stored in the same categories (name, color, linetype, freeze-thaw status, etc.).  Each of the other tables operates similarly, that is, it has different information about each entry in the table, but the same categories.  This sort of information is well suited to be organized into tables where each row holds a different entry, and each column represents a different category appropriate to that particular table.

AutoCAD presents some tables to the user as tables, while others are less obvious.  If you use the LAYER command, or DDUCS, or DDVIEW with "?" (especially in a drawing where several layers/ucs's/views already exist) you can see some of AutoCAD's more obvious tables.

Here is a list of the various tables AutoCAD uses.

appid
Table identifying loaded applications
block
Table listing internal blocks in the current drawing and external references
dimstyle
Table of dimension styles
layer
Table of layers
ltype
Table of linetypes
style
Table of text styles
ucs
Table of User Coordinate Systems
view
Table of defined views
vport
Table of model space viewport configurations


The tblsearch function

The tblsearch function allows your program to search for a particular entry in a given table.  The first argument can be "block" or "ucs" or any of the table names listed above, as a string (between quotation marks).  The second argument will be the name of the entry your program is trying to find.  If the entry is found in the specified table, an association list is returned which contains detailed information about that entry, associated with particular codes.  If the entry is not found, the tblsearch function returns nil.

Example 1:  If your drawing contains a layer called "Hidden" with linetype Hiddenx2 and color red (1) assigned to it.

Example 2:  If your drawing has a text style called "Mono-spaced" which uses the Monospac821 BT font, and has a variable (zero) height. Example 3, If your drawing has a view called TB (short for Title Block). Obviously, many of the above codes pertain to the types of views created in 3D modeling.

The codes are similar to the DXF codes described in the AutoCAD R14 Customization Guide, Appendix C.  You can also figure out many codes simply by creating a table entry, using the tblsearch function to display its table information, modifying it, then using tblsearch again and noting the differences.

By the way, these string arguments in the tblsearch function are not case sensitive.  That is, "layer" works the same as "LAYER" or "Layer" when used in the tblsearch function.  However, what is returned contains all upper case for such things as layer name, linetype name, text style name, etc.  This is important to remember if your program needs to search a table entry for a match.

There are several examples of the tblsearch function in previous Lessons, listed below.  In each case the tblsearch function is searching the text style table.

Also, the sample program below, balloon3,  uses the tblsearch function to search both the text style and the layer tables.

The tblnext function

The tblnext function allows your program to "read through" a table, getting information from each subsequent entry in the table.  Usually, it is used in an iteration loop.  The first argument to the tblnext function is the name of the table, as a string.  Suppose, for example, that you want your program to read through every entry in the layer table.  You could place an expression like the one below inside a while loop.

    (tblnext "layer")

With each successive iteration, it returns information on the next layer.  If there are no more layers, nil is returned.

In order to force the tblnext function to read the first entry in the table, include a second argument which is non-nil, as shown below.  This is known as the "rewind" form of the tblnext function, since it rewinds the pointer back to the beginning of the table.

    (tblnext "layer" 1)

For example, the following could be used to read through every entry in the text style table and print each entry to screen.

    (print (tblnext "style" 1))
    (while (print (tblnext "style")))

By the way, when tables are listed in a dialog box (such as the drop-down list in the "Style name" section of the text style dialog box, or the listing in the layer dialog box) they are alphabetized.  However, when you use the tblnext function to retrieve the same information, it appears in the order in which the items were created.

Sample program 1, balloon3

Balloon3 is a revision of the balloon2 program found in Lesson 12.  In addition to storing the balloon diameter in a file (similar to balloon2), this program also stores, in the same file, the layer on which the balloon should be created and the color assigned to that layer.  When the user wants to change one of these three items, he/she enters "S" instead of picking the startpoint of the balloon leader.

Some of the sections are similar to balloon2.  The lines that have been added (and that pertain especially to the use of the tblsearch function) and marked "ADDED" in the program, but other lines have also been added or altered, and the overall program has been re-organized.

Similar to balloon2, this program must exist in its own file called balloon3.lsp, and should be located on the AutoCAD default folder or on one of the folders in the AutoCAD search path.

You will need to study this program carefully if you want to understand its logic.  For example, note the use of a setup "subroutine" or "module" (section 50 - 58) which gets the desired layer, color, and balloon diameter from the user.  This blnsetup function is called from two places in the program -- sections 140 and 150.  Each time the setup module is run, it stores the information in a file called balloon3.lcd, which it places in the same folder as the program file.  (The "lcd" stands for Layer, Color, Diameter.)

Also, it may appear that it is overloaded with if statements.  However, remember that there are many different situations that can exist which the program must test for.  For example, if the program is being run for the first time, it will not know the desired layer, color, or balloon diameter, so it must run the setup module to get these from the user.  If the program is being run for the second time in the same editing session, it already knows these three items and does not need to run the setup module.  If the program is being run for the first time in a new editing session (but has been run previously), it will read these three items from the balloon3.lcd file.  What happens if the drawing in the new editing session does not have the layer identified by the balloon3.lcd file?  Or, what happens if the user runs the setup option and enters a layer that already exists?  Or enters a layer that does not exist?  All of these contingencies, and several others, must be "covered" by the program, which accounts for the over abundance of if statements.

There are four occurrences of the tblsearch function in this program:

In sections 54 and 140
the layer table is searched merely to find out if a certain layer exists.
In section 130
the program knows that the layer being searched for already exist because the layer that is being searched for is the current layer, according to the previous line.  Here it is extracting the color assigned to that layer (associated with code 62).
In section 160
the text style table is searched to see if the current text style has a fixed height.


------ marker ------ beginning of working program ------ try it out ------

;|  BALLOON3 -- Stores balloon information in a
    file named balloon3.lcd
    Copyright © 1988,1998,1999 Ronald W. Leigh
    Input: (layer, color, balloon diameter), arrow location,
           balloon location, number
    Output: draws assembly balloon
Variables:
blncol  Balloon layer color, GLOBAL                          ADDED
blndia  Balloon diameter, GLOBAL
blnfl   Balloon info. file location, GLOBAL
blnlay  Balloon layer name, GLOBAL                           ADDED
blnnum  Balloon number, GLOBAL
cen     Center of balloon
ep      Endpoint of arrow
fr/fw   File descriptors: file opened for reading/writing
olay    Old layer                                            ADDED
oom     Old osnap mode
sp      Start point of arrow
temp    Temporary value for blnlay, blndia, & blnnum input
ts      Name of current text style
tshei   Text style height                              |;
 

;50====BLNSETUP ROUTINE, Gets layer, color, diameter from user

(defun blnsetup ()
(princ "\n** Setup **")

;52--------Get blnlay from user

(setq temp
  (getstring (strcat "\n** Balloon layer name <" blnlay ">: ")))     ; ADDED
(if (/= "" temp) (setq blnlay temp))

;54--------If layer blnlay does not exist, create layer

(if (null (tblsearch "layer" blnlay)) (progn
  (setq blncol (acad_colordlg blncol nil))
  (princ (strcat "\n** Creating layer " blnlay " with color " (itoa blncol) " **"))
  (setvar "cmdecho" 0)
  (command ".layer" "N" blnlay "C" blncol blnlay "")
  (setvar "cmdecho" 1)
))

;56--------Get blndia from user

(initget 6)
(setq temp (getreal (strcat "\n** Balloon diameter <" (rtos blndia 2 3) ">: ")))
(if temp (setq blndia temp))

;58--------Store information in file.

(if (= (type blnfl) 'STR) (progn
  (setq fw (open (strcat blnfl "balloon3.lcd") "w"))
  (write-line blnlay fw)                                        ; ADDED
  (write-line (itoa blncol) fw)                                 ; ADDED
  (write-line (rtos blndia 2 4) fw)
  (close fw))))
 

;100====MAIN PROGRAM, SETUP

(defun c:balloon3 (/ cen ep fr fw olay oom sp temp ts tshei)
(setq olay (getvar "clayer"))                                   ; ADDED
(setq oom (getvar "osmode"))
(graphscr)

;110====GET LOCATION OF BALLOON3.LSP PROGRAM FILE

(if (/= (type blnfl) 'STR) (progn
  (setq blnfl (findfile "balloon3.lsp"))
  (if (= (type blnfl) 'STR)
    (setq blnfl (substr blnfl 1 (- (strlen blnfl) 12))))))

;120====IF BLNLAY OR BLNDIA NOT SET, AND IF BLNFL IS A STRING,
;       AND IF FILE BALLOON3.LCD HAS BEEN LOCATED, READ INFO.
;       FROM THE FILE.

(if (and (or (/= (type blnlay) 'STR) (/= (type blndia) 'REAL))    ; ADDED
         (= (type blnfl) 'STR)
         (findfile (strcat blnfl "balloon3.lcd"))) (progn
  (setq fr (open (strcat blnfl "balloon3.lcd") "r"))
  (setq blnlay (read-line fr))                                    ; ADDED
  (setq blncol (atoi (read-line fr)))                             ; ADDED
  (setq blndia (atof (read-line fr)))
  (close fr)))

;130====IF PREVIOUS SECTION FAILED, SET LAYER, COLOR, AND DIAMETER
;       FROM INTERNAL DATA

(if (or (/= (type blnlay) 'STR) (/= (type blncol) 'INT))
  (setq blnlay (getvar "clayer")
        blncol (cdr (assoc 62 (tblsearch "layer" blnlay)))))
(if (/= (type blndia) 'REAL)
  (if (= 0 (getvar "dimscale"))
    (setq blndia (/ (getvar "dimtxt") 0.28))
    (setq blndia (/ (* (getvar "dimtxt") (getvar "dimscale")) 0.28))))

;140====IF LAYER (RETRIEVED FROM FILE) DOES NOT EXIST, RUN SETUP,
;       THEN REPORT SETTINGS

(if (null (tblsearch "layer" blnlay)) (blnsetup))

(foreach v
  (list "\n** Balloon layer = " blnlay " (color " blncol
        ") Diameter = " (rtos blndia 2 4) " **")
  (princ v))

;150====GET STARTPOINT, CENTER, AND NUMBER FROM USER

(setvar "osmode" 512)
(while
  (progn
    (initget 1 "Setup")
    (= "Setup" (setq sp
        (getpoint "\nStartpoint of arrow (or 'S' for Setup): "))))
  (blnsetup))
(setvar "osmode" 0)

(initget 1)
(setq cen (getpoint sp "\nLocation of balloon: "))

(if (null blnnum) (setq blnnum 0))
(setq blnnum (1+ blnnum))
(initget 6)
(setq temp (getint (strcat "\nBalloon number <" (itoa blnnum) ">: ")))
(if temp (setq blnnum temp))

;160====CALC. END POINT OF ARROW, GET TEXT STYLE HEIGHT, DRAW BALLOON

(setq ep (polar cen (angle cen sp) (/ blndia 2)))

(setq ts (getvar "textstyle"))
(setq tshei (cdr (assoc 40 (tblsearch "style" ts))))
(if (> tshei 0)
  (princ "\nText style has fixed height; may not fit balloon."))

(setvar "cmdecho" 0)
(command ".layer" "S" blnlay "")                                  ; ADDED
(command ".dim1" "leader" sp ep) (command)
(command ".circle" cen "D" blndia)

(if (> tshei 0)
  (command ".text" "M" cen 0 blnnum)
  (command ".text" "M" cen (* 0.28 blndia) 0 blnnum)
)
(command ".layer" "S" olay "")                                   ; ADDED

;170====RESET

(setvar "cmdecho" 1)
(setvar "osmode" oom)
(princ)
)

-------- marker -------- end of working program -------- try it out --------
 
 

Sample program 2, tstyles

The following program, called tstyles (short for text styles), illustrates the use of the tblnext function.  It creates a table which lists all the text styles in the current drawing, listing those with variable height first, then those with fixed height.  The table also includes the font file that is used by the style, and, in the case of the fixed height styles, it lists the fixed height as well.

The program reads through the style table twice -- once in section 20 to build a list of variable height styles, and once in section 30 to build a list of fixed height styles.  In order to be sure that the first style returned is actually the first one in the table, each section uses the tblnext function in its "rewind" form first (with a non-nil second argument).  Then the while loop reads through the remaining items in the table.

------ marker ------ beginning of working program ------ try it out ------

;|  TSTYLES -- Creates a two-part table that lists the fixed
    height and variable height text styles in a drawing
    Copyright © 1999 Ronald W. Leigh
    Input: none
    Output: table of styles
Variables:
fhlist  Fixed height list
font    Font file used by style
hei     Height
item    Each subsequent item retrieved from the table
name    Style name
vhlist  Variable height list                     |;

;10====PROGRAM

(defun c:tstyles ()
(textscr)

;20====BUILD LIST OF TEXT STYLES WITH VARIABLE HEIGHT

(setq vhlist ())
(setq item (tblnext "style" 1))
(if (zerop (cdr (assoc 40 item)))
  (setq vhlist (cons item vhlist)))
(while (setq item (tblnext "style"))
  (if (zerop (cdr (assoc 40 item)))
    (setq vhlist (cons item vhlist))))
(setq vhlist (reverse vhlist))

;30====BUILD LIST OF TEXT STYLES WITH FIXED HEIGHT

(setq fhlist ())
(setq item (tblnext "style" 1))
(if (not (zerop (cdr (assoc 40 item))))
  (setq fhlist (cons item fhlist)))
(while (setq item (tblnext "style"))
  (if (not (zerop (cdr (assoc 40 item))))
    (setq fhlist (cons item fhlist))))
(setq fhlist (reverse fhlist))

;40====PRINT TABLE OF STYLES TO SCREEN

(terpri)
(repeat 12 (princ "-----"))
(princ "\n              TEXT STYLES WITH VARIABLE HEIGHT\n")
(if (zerop (length vhlist)) (princ "\n (none)"))
(foreach v vhlist
  (setq name (cdr (assoc 2 v)))
  (while (< (strlen name) 16) (setq name (strcat name " ")))
  (setq font (cdr (assoc 3 v)))
  (princ (strcat "\n " name " Font file " font)))
(princ "\n\n               TEXT STYLES WITH FIXED HEIGHT\n")
(if (zerop (length fhlist)) (princ "\n (none)"))
(foreach v fhlist
  (setq name (cdr (assoc 2 v)))
  (while (< (strlen name) 16) (setq name (strcat name " ")))
  (setq font (cdr (assoc 3 v)))
  (while (< (strlen font) 18) (setq font (strcat font " ")))
  (setq hei (cdr (assoc 40 v)))
  (princ (strcat "\n " name " Font file " font
                 " Height " (rtos hei 2 3))))
(terpri)
(repeat 12 (princ "-----"))
(terpri)
(princ)
)

-------- marker -------- end of working program -------- try it out --------
 
 

HOME


Copyright © 1988, 1998 Ronald W. Leigh