Boyce aug Cadence head: Database Access sub: Bringing It In by Jim Boyce Integrating cad with a database usually means generating data in the cad program and exporting it to a database
boyce.aug CADENCE Head: Database Access sub: Bringing It In by Jim Boyce Integrating CAD with a database usually means generating data in the CAD program and exporting it to a database. Generating bills of mate rial, door and window schedules, and other data lists to be manipulat ed by the database outside of the CAD program are good examples. But there are cases in which you may need to bring data in, rather than send it out. Let's take a look at one such example. Assume your company manufactures a fairly standard item, such as a door, but your market niche is selling custom sizes and configura tions. Even though each one is a custom order, most of your product drawings fall into a few categories: single door, double door, hinges on the right, hinges on the left, and so on. Generating a drawing for each order involves putting together standard parts in a custom con figuration and then generating a drawing. In this case, the drawing would probably not even have to be to scale. Creating these drawings wouldn't be much of a problem if both your business and the number of orders you take in are still small. But what happens when business is booming? If you're receiving orders for 20 doors per day, 20 drawings have to be generated. One solution would be to use AutoCAD to speed up the drawing process. Then you would be stringing those standard parts together even faster. But there may be a better way, assuming your order entry system is computerized. In all likelihood, the information needed to generate the drawing is either already in the computer when the salesperson takes the order or can be entered at that point. The order is going to include information about whether it is a single or double door, where the hinges are, what specia l hardware is needed, and so on. All you have to do now is export that data to AutoCAD and have the drawings generated automatically. When properly set up, you can take the order, generate an A-size drawing, print it, and FAX the drawing to the customer within minutes for a confirmation of size, configuration, and other factors. This alone may make the time and effort involved in setting up this system worthwhile (even if you have a dedicated engineering staff that will generate detailed scale drawings late r on). There are two approaches to generating these drawings using AutoLISP. The first would be to write an AutoLISP routine that generates the drawing "on the fly" as it reads the data file. The other method would be to read the data file and generate a script file that could be used immediately or saved for use in generating the drawing at a later time. In this example, we'll read from the data file and build the drawing as it is read. Data Structure More than likely, the data you export from your database will have to be manipulated more than once to get it in a format usable by AutoCAD. How you do that will depend on the database program you are using, whether it's running on a mini or micro, and a host of other factors. Because that facet of the problem is so individualized, let's start with a generic data file_one we'll assume your database system could generate based on the information a salesman would provide when plac ing an order. Customizing it for your situation would only involve placing the right lines of information in the right place in the file. Listing 1 shows the data file we're going to work with. Like an Auto CAD DXF file, it is segregated into different sections, each preceded by a header. The first section, "parts," lists the drawing name of each of the standard parts that will be used on this door. The next section, "notes," contains all the general notes that are to appear on the drawing. The last section, "tblock," lists order-specific informa tion that will be included in the drawing's title block. Your actual configuration will depend on y our drawing format and how much you are willing to standardize. Breaking It Down The main function, MAKE.LSP, will control access to both the data and script files (Listing 2). MAKE.LSP checks for the existence of the source (data) file, and if it exists, calls three other functions that will read the parts list section of the file, the notes section, and the title block section. Each of these functions will read the data file, massage it into the right format, then process it using AutoCAD commands. Because each door is a collection of standard parts, generating a composite drawing is simple. Each of the individual part drawings must share a common origin, which, when they are inserted, will place each part in its correct location relative to the others. The location of the common origin is irrelevant, as long as all the parts match. But picking a known point will make it easier to add parts in the future. Since we know we'll be using an A-size sheet, we'll use the lower left corner of the drawing bord er as the origin for all of the parts. Figure 1 shows some of the sample parts. All the script generator has to do is read the part names and attach the Insert command to it, along with a common refer ence point and scale. The function in the AutoLISP file that will read the parts list and insert the individual drawings is called (readpart) and is shown in Listing 3. Because the only way AutoLISP can access an external file is sequentially (and can only access ASCII files), all these functions work sequentially. As detailed in Listing 3, (readpart) reads a part name from the data file and uses that part name along with the appro priate parameters of the Insert command to insert the part. The coor dinate 0,0 is used as the inser tion point, 1 is used as the X and Y scales, and 0 is used as a rota tion value. The (readnote) function (Listing 4), which creates the Notes section of the script file, works very much like (readpart). Both go through a loop, reading lines from the data file until they read a "0," which indicates the end of that section of the file. The main difference in (readnote) is that it uses the Text command rather than the Insert command. The variable pnt in (readnote) controls the location of the text, and the Y-component of pnt is decremented each time the routine loops. This sample program i s set up for an A-size drawing and places the notes in the upper left-hand corner, starting 1/2" below the top border and placing each succeeding line of text below the last. Finally, the (readtblk) function (Listing 5) reads the title block information from the data file, then uses the Text command to place it in the correct location in the title block. Unlike the previous func tions, (readtblk) doesn't include a loop, as there are a fixed number of entries in this section of the data file, and each entry has a specific location on the drawing. Each line is read in, the proper coordinate for that line is attached to it, and the line of text is placed on the drawing. Create Your Own MAKE.LSP Program There are several additions you would probably want to make to your automated drawing system. For one, this program doesn't include much error checking. In fact, the only thing it does check for is the existence of the data file. Standardizing the source file extension would be another good addition. In any case, MAKE.LSP illustrates how to take an ASCII data file, manipulate it, then and generate a drawing automatically from that data. This approach to product documentation may not be right for your situation. You may need more detailed drawings than you would be able to generate this way. But there are some significant benefits to this type of database/CAD integration. Being able to create a drawing in a matter of minutes and FAX it to a customer for verification could save you not only lost time but the expense of remanufacturing the product. If simple drawings such as these are all you need, the savings in drawing creation time alone w ould quickly repay the investment in time in developing the system. @ Jim Boyce is a senior instructor at Texas State Technical Institute in Harlingen, Texas, where he teaches advanced CAD and programming. Listing 1. Listing 2. Listing 3. Listing 4. Listing 5. Listing 6. cadence.aug ahrens DATABASE MANAGEMENT SYSTEMS UNDER THE ADS C-BINDINGS Developing fully integrated DBMS programming in AutoLISP by Tom Ahrens Traditionally, using relational data-bases in the AutoCAD environment required extracting data to an intermediate file and either exiting or shelling out of AutoCAD and running a dedicated compiled program or loading one of the many database application programs available. After entering one of these external programs, the data must be read from the intermediate file and appended to an existing or newly created database file. This method interfaces AutoCAD with external programs. These can then process the data and create modified intermediate files that can be read back into the AutoCAD environment using AutoLISP or the DXF/DXB features of AutoCAD. Some third party programs create many intermediate files in the process of modifying data in a drawing. There are also programs that can read the DWG file directly and either extract data from the drawing or modify the drawing file itself, but these programs must be run outside the AutoCAD environment and require programming in a language alien to AutoCAD. With the AutoCAD Develop ment System (ADS) it is now possible to build a truly integrated database management system (DBMS) with relational capabilities that runs in the drawing editor and uses AutoLISP programming exclusively. Rather than merely discussing the potential of an ADS application, this article will develop some of the building blocks of a truly integrated database management system. For a database file format, we'll use Ashton-Tate's DBF file format, which is supported by most popular database and spreadsheet programs. We'll use the dBASE III/III+ version because of its widespread support and ability to be read directly by dBASE IV, the latest version of Lotus, and many other popular applications. We will be using the ADS package included in the OS/2 version of AutoCAD Rel. 10 and compiling the C code that we develop with the Microsoft OS/2 C V5.1 compiler. Because of the portability of C this code will port to Rel. 11 386 and Rel. 11 DOS with little or no modification. ADS development allows freestanding C programs that can be called from and appear to AutoCAD the same as any AutoLISP program; it can also provide additional functions of AutoLISP's new atom type Exsubr that in effect expands the set of internal subroutines used by AutoLISP. To provide the AutoLISP programmer with the tools needed for an integrat ed DBMS we will use the Exsubr approach. To achieve this goal we must include the functions to create a DBF file of the proper format. AutoLISP has always had the capability of creating a DOS text mode file by using the (open filename w) subrou tine. Unfortunately, DBF files include binary characters as well as text characters that AutoLISP cannot create. With C we can open files in the DOS binary mode and create any file format required. We will be using the C library routine fopen (filename wb) to create a file for writing to in binary mode, and add this to the AutoLISP environment as an Exsubr. File Format In order to write to this file properly, we must first become familiar with the file format of dBASE III/III+. An excellent reference book for many file formats is File Formats for Popular PC Software by Jeff Walden (Wiley Press). Briefly, the DBF format includes a header fol lowed by field descriptors followed by all the data records. It is necessary to look at the header section, which is the first 32 bytes of all DBF files, in detail. The first byte or byte 0 is set to ASCII character 3 to denote a dBASE III/III+ file. The next three bytes (bytes 1 through 3) hold the date of the last update of the file. We'll look at the date format later. The next four bytes (bytes 4 through 7) declare the number of records in the file. Bytes 8 and 9 indicate the length of the header and field descriptor sections. Bytes 10 and 11 indicate the total l ength of all fields plus one byte for the deletion field. The next 21 bytes are reserved for internal usage by the application program that loads this file and is therefore inconsequential to the creation of this file. Before we can write the header section, we need the following: the current date to be used in the last file update area (bytes 1 through 3); the number of records we will be adding to the file; the number of fields; and the total of all field lengths. We will obtain this data in an AutoLISP program. For an example we have included an AutoLISP program (Listing 1) that collects all blocks with attributes into a selection set on line 3 and then prompts for a database filename. Line 6 opens a file with a DBF ex tension for writing to in DOS binary mode. We have not hard coded the DBF extension because in future articles we may use this same exsubr to open NDX and CAT files. The current date is obtained from the AutoCAD variable CDATE, and converted to the required string on line 7. The total number of re cords to be sent to the DBF file is evaluated on line 8. The AutoLISP program then builds a list of field names to be used in the field descriptor area of the DBF file, on lines 9 through 14. In this exam ple the tag will agree exactly with the field names used in the DBF file. The user should also note that field names in the dBASE environ ment are limited to a character string of 10 or less. Line 15 gives the total number of fields that will be included in the DBF file, and the only other information required for the creation of the header section is the total of field character widths. Next we will query the user for the field type, length, and decimal accuracy on lines 16 through 21 while including the attribute tag in the prompt. We'll use the same format AutoCAD uses in the attribute extraction template (i.e., N009002 denotes a numeric field type with a length of nine places, including the decimal point and having a two decimal place accuracy). After appending all of the field information into the list struct lines 22 through 25, totalling all the field widths by using the substr subro utine, and looking at the three characters starting at character position 2, we are now ready to write the header section to the DBF file. THE HEADER SECTION The ADS code (Listing 2) provides the Exsubrs called by the LISP program. The code found in the main module (lines 8 through 39) pro vide the linkage necessary to all ADS programs (see June CADENCE). Line 5 declares the Exsubrs whose code will follow. Line 6 is a global variable of C datatype file, which is a pointer to the file used in all Exsubr calls. The loadfuncs module starts on line 42 and has one local variable, i, which is used as a counter. The programmer must insure that the number 5 on line 46 ag rees with the total count of external subroutines declared on line 5. The dofun module starts on line 55 and must be of storage class stat ic, which retains the variable's values between calls. The variable id gets the function code on line 63 and is used by the switch function to select the appropriate case. Each of the Exsubrs in our application except fclose require arguments when called from the LISP program. AutoLISP has an internal error handler but the ADS programmer must provide error handling in the C environment. The vast majority of code inside the switch function, lines 64 through 252, is dedicated to error checking (see July CA DENCE). A resource buffer rb is used to receive arguments from the LISP pro gram. All error checking is done on this buffer and all arguments are assigned to local variables from it. The first subroutine, fopen, uses a string for the DOS filename to open in write-binary mode. This assignment is made on line 72 and the file is opened on line 85 using the C library function fopen. Note there is no conflict in using the same name for the Exsubr in the ADS environment. The syntax as we define it also returns a string to AutoLISP on line 91 if the file opens successfully, otherwise it returns 0. The second subroutine, fclose, uses no arguments and closes the file on line 104. The third subroutine, fputhdr, is the most complex call. It requires four arguments_a string and three integers for the date, number of records, number of fields, and total width of all fields. With this many arguments, error checking and variable assignments require 60 lines of code (lines 108 to 167). The fputhdr variable assignments are made on lines 118, 132, 146, and 160. Lines 168 to 182 write the header section of the DBF file. Line 168 writes a binary 3 to the file, denoting dBASE III format. The date string variable strng is a pointer to nine characters of the form CCYYMMDD\0. The last character is a null terminator, as all C strings are in fact null terminated character arrays. The date string must be converted to binary characters before writing them to the file. The day is converted by using po inter arithmetic. Starting at the sixth character position, change the DD\0 string to an integer with the atoi function and save the result in dd. We must then place a null terminator in the sixth character position to extract the month, mm, and the fourth position to extract the year, yy. The century data is not needed. We then write these three values to the file as binary characters (one byte each). The file format uses a long integer (four bytes) for the total count of records and this is written to the file on line 177. The next entry in the header is the length, in bytes, of the header plus all field descriptor sections plus a terminator. Both the header and field descriptor sections are 32 bytes long and the terminator following these sections takes one byte. This number is determined on line 178, and written to the file on line 179 as a short integer (two bytes). The total of all field lengths is written to the file on line 180 as a short integer, and line 181 pads the dBASE internal pointer section with 20 null characters. The header is now complete and the field descriptors will follow. Referring to Listing 1, lines 27 to 31 extract the field name from taglst, the field type from struct, and write the field descriptor sections inside a repeat loop by making a call to the fputdesc exter nal subroutine. Line 32 writes the terminator, character 13, to the file. We are now ready to add the records to the file, but first we'll look at fputdesc and fputc in the ADS program. Field Descriptors Since we decided to use the AutoCAD attribute extraction format for the struct list, only two strings have to be passed in the fputdesc call. These assignments are made on line 196 and 210. Before writing the field descriptor section we must be familiar with its format. Thirty-two bytes are used for each section. Bytes 0 through 10 are reserved for the field name. If its length is less than 10 characters, it is padded with trailing null characters (0). Byte 11 is an ASCII character representing the field ty pe. The following types are supported in dBASE III/III+: C (character), N (numeric), L (logical), M (memo) and D (date). Bytes 12 through 15 are used by dBASE internally and we will be padding them with nulls. Byte 16 is used for field length (max 256). Byte 17 is used for field decimal count. Bytes 18 through 31 are reserved for internal usage by the application program that loads this file and is therefore inconsequential to our program. Line 218 writes the field name to the file one character at a time, and line 219 pads it to Byte 10 with zeros. Line 220 places the first character in our field type strng2 into the file. Four zeros are written to bytes 12 through 15 on line 221. Using pointer arithmetic and atoi conversion again, we assign the decimal place count to variable i on line 222. Line 223 and 224 write the field length as an integer, and variable i is written on line 225. Bytes 18 through 31 are padded with zeros, and the field description is complete. The final external subroutine fputc defined in the ADS program re quires one argument, atom type INT, and places it in the file as a character (one byte) on line 249. This call is used in our AutoLISP program to add all the records to our DBF file. In order to write the LISP code that fills out the record section, a knowledge of the record format is necessary. Actually we've determined its format when we wrote the field descriptors section of our DBF file. In addition to the record format, the programmer mus t include one byte at the beginning of each record for a deletion field and set it to ASCII 32, the space character (i.e., not marked for deletion). All data in the record section is saved as ASCII char acter strings and not as binary data. Character fields are left justi fied and padded with trailing spaces (ASCII 32) and numeric fields are right justified and padded with leading spaces. Therefore, a test must be done on field type Listing 1, line 42 in the AutoLISP program. After all records have been added to the file, an ASCII 26, the end of file (EOF) marker, is added on line 67, and a call is made to fclose line 68. At this point the dBASE file is complete and its data is available to the many applications programs that support this file format. Attributes and More This AutoLISP program only addresses attributes in a drawing, but certainly any data accessible in the AutoLISP environment can be used to create a DBF file. Besides attributes, this includes all entity information in the DWG file, all data saved in the tables section, all AutoCAD environmental variables, all entity information included in the block definitions, any settings in the DOS environment using (getenv, any data in text files opened with LISP's (open filename r) command, etc. All blocks with attributes are collected on line three. This requires block definitions to include the same number of attr's having the same tag names in the same order. This is common when implementing a global bill of material environment. If this is not the case in your draw ings, replace line 3 with the two preceding commented lines and build DBF files based on block names. A fully implemented DBMS would require many more exsubrs. This ADS program could provide a starting point for such a program. Using these techniques, an ADS programmer could support other file formats, in cluding spreadsheets. As we have seen, ADS programmers can now develop applications that are totally integrated and can be programmed in AutoLISP. The obvious advantage is that AutoLISP programmers can now expand the capabilities of their programs while continuing to work in a familiar environment. @ Tom Ahrens is a consultant and C and AutoLISP instructor with OmniCAD of Houston, Texas. userlib.beach.july cadence head: XY.LSP and DRAWXY.LSP by Anthony D. Beach This LISP routine was written for those currently using a coordinate geometry package outside the AutoCAD environment or who need to import COGO data from a third party source. It allows a user to input COGO data without the additional time and training expense required from a coordinate geometry package that operates inside the AutoCAD environ ment. Almost all coordinate geometry packages can export the coordinate data to a standard ASCII file. The ASCII files written by most packages usually contain fields for the point numbers and XY coordinates. A few add elevation and description fields. This routine will allow you to import these coordinate geometry ASCII files into AutoCAD. This program will open and read any standard ASCII text file contain ing point numbers and XY-coordinate pairs. The program will then plot the point numbers and draw a circle at each coordinate pair location. The center of the circle will contain the exact coordinates of the point specified by the input file. The data fields in the ASCII file may be in any order, and each may contain variable field lengths. XY.LSP will prompt for the starting column and field length for the Point number, X-coordinate, and the Y-coordinate data fields. Next, the routine will prompt for a text height for the point numbers. The routine will then prompt for an input ASCII filename. A default file name COGO.DAT is used if no filename is specified. This routine will begin plotting all points and terminate at the end of the file. This routine was written in Release 10 AutoLISP. It could be easily modified by adding elevation and description fields in separate lay ers. (A special thanks is given to Earl Bosl, who made this program possible.) DRAWXY.LSP This LISP routine is a companion program to the XY.LSP routine. In large coordinate point files, many pans and zooms are necessary to read point identification numbers and construct the geometrical shape. This routine reduces the amount of zooming and panning by simply entering the corresponding point number to the coordinate pairs to construct the geometric shape. This routine has the identical initial prompts as the XY.LSP. The routine will prompt for the starting point number and then the next point to construct the geometrical shape. This routine accesses the identical ASCII file and allows the same flexibility as the XY.LSP routine. Default parameters that match the values entered from the XY.LSP routine will be supplied by DRAWXY.LSP. @ For more information on these two routines, contact Anthony Beach, P.O. Box 711, Temple, Texas, 76503, (817) 773-6557. segal.aug CADENCE Head: ATTRIBUTE SORTING Sub: by Kenneth J.L. Segal In the May issue, Auntie Edlin described how to perform "block counts" without invoking external files, and also using DXF and attribute extract files. These solutions are appropriate for performing takeoffs of drawings that have a unique block name for each object. However, many drawings and drafting standards cannot use the "block count" technique to sort and count drawing information. In many cases, unique blocks cannot be used for every object. If you have several unique objects in a drawing, it may be neither wise nor economical to make a block for each one. Instead, labeling each instance with an attribute "tag" may be preferable. Even where you have used blocks, you may wish to count or sort information not readily available in the block name. For instance, you may use a single door symbol, with multiple attributes describing each door's unique characteristics. An attribute sorting and counting program would allow using a single symbol for all doors (or no "symbol" at all, just free entities) and counting them using attributes. In the case of a piping diagram, if you have unique symbols for each length and type of pipe, you can count the block names. Since pipe can be cut to almost any length, it is almost impossible to anticipate every case with unique blocks. However, you might also draw the lengths of pipe as non-blocked entities and tag them with attributes. The first image (PIPE.DWG) includes the insertion of "tagging blocks" named ATTRIB, which contain no entities except the attributes PIPETYP, PIPEDIA, and PIPELEN. For each piece of pipe, there is an insertion of the ATTRIB block with the appropriate values for the pipe type, diameter, and length. To create an attribute extract file, you must first have a "template" file. For this drawing, I created PIPE.TXT, which reads: PIPETYP C010000 PIPELEN N008002 PIPEDIA N008002 You may make an attribute extract file in Comma Delimited Format (CDF), Space Delimited Format (SDF), or Drawing Exchange Format (DXF). For this sample drawing, a section of CDF output (PIPEC.TXT) would read: '90 Elbow', 6.00, 4.00 '90 Elbow', 6.00, 4.00 'Straight', 12.00, 4.00 'Straight', 12.00, 4.00 and a section of SDF output (PIPES.TXT) would read: 90 Elbow 6.00 4.00 90 Elbow 6.00 4.00 Straight 12.00 4.00 Straight 12.00 4.00 ATTSRT.LSP will sort a CDF or SDF extract file, listing a count of all like attributes. To use it, enter the code into a file called "ATTSRT.LSP" using any ASCII text editor. After creating a template file and exporting attributes with the Attext command, load the pro gram by typing (load "ATTSRT") and run it by typing ATTSRT at the Command: prompt. ATTSRT responds: What is name of TEMPLATE File (omit extension) ? Type the name of the file. For the "pipe" drawing I would type PIPE (after PIPE.TXT, the template file) and press return. You may include a path as long as you use forward slashes, as in "D:/TEMP/TEMPLATE" or double backslashes, as in "D:\\TEMP\\TEMPLATE." If you make a mistake ATTSRT will prompt: *ERROR* FILE " (file name) " DOES NOT EXIST and give you another chance to name the template file. The program reads the template file, pulling out the names and string lengths of each attribute tag and calculating the starting position of that tag in each line of the extract file. It also counts the attribute tags and creates a list of this information, called LABLST. After reading the template file, ATTSRT displays: SORTING THESE ATTRIBUTES: followed by the attribute tag names. For the "pipe" drawing it would print: SORTING THESE ATTRIBUTES: PIPETYP PIPEDIA PIPELEN You are then prompted: What is name of ATTEXT File (omit extension) ? Type the name (and path, if any) of the extract file and press return. Assuming the file exists, you'll be prompted: Is this file omma Delimited or pace Delimited ? Type C or S and press return. ATTSRT will prompt: Reading and Counting (file name) . . . Please Wait When the sorting is finished, you will be prompted: Output count to creen or ile and screen ? Type S or F and press return. If you choose to output to a file, you will be asked: Name of output file ? Type the name and press return. ATTSRT will print its report to screen and/or file in this format: "Attribute sort for: (extr. file name)" "Insertions: # ATTR1: VALUE ATTR2: VALUE Insertions: # ATTR1: VALUE ATTR2: VALUE" and so on. For the piping drawing, this file (PIPE.OUT) reads: Attribute sort for: PIPEC.TXT Insertions: 7 PIPETYP: Straight PIPELEN: 12.00 PIPEDIA: 4.00 Insertions: 6 PIPETYP: 90 Elbow PIPELEN: 6.00 PIPEDIA: 4.00 The report format is very simple because ATTSRT has been generalized to accommodate any number of attribute labels. Printing the data in a horizontal format would require additional routines to check the width of attribute labels and data. You may wish to modify the printing and output section to your own report standards. It would be relatively easy to extend this program to read a "report generation file," which includes the desired attribute names as well as headings and other text, and insert the data a t the appropriate locations. During an attribute extraction it is possible to include block infor mation not included as attributes, including block name, layer, posi tion, and so on. Just include the reserved field names BL:NAME, BL:X, etc. in the template file. (See the AutoCAD Reference Manual for a complete description of Attext. However, it is necessary to include at least one attribute field name in the template to perform an extrac tion. You can use Attext and ATTSRT.LSP to count blocks if each block includes an attribute which st ores its name. As an example, I created a drawing (GEO.DWG) that contains the blocks TRIANGLE, SQUARE, and CIRCLE. Each block contains a single attribute with the tag NAME, which stores the block name. In the sample drawing, I've inserted four SQUARE, two TRIANGLE, and three CIRCLE blocks. The template file (GEO.TXT) reads: NAME C008000 and a portion of the resulting extract files (GEOC.TXT, GEOS.TXT) reads: 'CIRCLE' 'TRIANGLE' 'SQUARE' 'SQUARE' and CIRCLE TRIANGLE SQUARE SQUARE After running ATTSRT, the sort file (GEO.OUT) reads: Attribute sort for: GEOS.TXT Insertions: 4 NAME: SQUARE Insertions: 2 NAME: TRIANGLE Insertions: 3 NAME: CIRCLE The task of making a more sophisticated report or creating a full bill of material, must be left to other programs. For a bill of material, a "library file" containing a list of standard symbols and their pricing can be cross-indexed to estimate costs for the drawing or project. @ Ken Segal is a regular columnist and reviewer for CADENCE. His con sulting firm, LOG NINE, is based in Southeastern, Pennsylvania. thurmond.aug CADENCE Head: Seamless AutoLISP Sub: Using the *error* Function and PRIN1 by LeAnne C. Thurmond AutoCAD users who do not program in AutoLISP but make use of AutoLISP functions written by others can be baffled and confused by the actions of the AutoLISP interpreter. Some users are disconcerted when an AutoLISP defined command returns "nil" or "1.0000" or "DONE." They can be even more annoyed and confused when an AutoLISP function is cancelled, or "bombs," and masses of statements in parentheses scroll by. To compound the annoyance, this can cause a noticeable delay in performance if the error occurs i n a long program. These two actions of the AutoLISP interpreter can be easily masked by the programmer for the comfort of the user. Not only will the user be undisturbed by the extra information appearing at the Command: prompt, but the program will perform and appear more like AutoCAD itself. The first problem, the printing of "nil" or a value at the Command: line when a program concludes, can be easily masked by the print functions. When an AutoLISP function is entered at the Command: prompt, AutoLISP evaluates it and prints the result of the last ex pression evaluated. If the last expression evaluates to "nil," the word "nil" appears at the Command: prompt. If it evaluates to a real number, the number is displayed with up to six significant digits. If it evaluates to a list, the list is printed . The AutoLISP interpreter will exit a completed function without print ing "nil" or anything else at the Command: prompt if a print function with no arguments is issued as the last evaluated function in a pro gram. The one most commonly used is (prin1), which causes a null string to be printed when the function is complete. For example, the function created by the following program would return "(1.0 1.0)" at the Command: prompt, since the last function evaluated sets the varia ble "GRIDUNIT" to the list (1.0 1 .0). (defun C:FRACTION () (setvar "LUNITS" 5) (setvar "SNAPUNIT" '(0.0625 0.0625)) (setvar "GRIDUNIT" '(1.0 1.0)) ) Command: FRACTION (1.0 1.0) Command: Merely adding (prin1) before the final right parenthesis closing the DEFUN statement would cause the program to end "quietly." (defun C:FRACTION () (setvar "LUNITS" 5) (setvar "SNAPUNIT" '(0.0625 0.0625)) (setvar "GRIDUNIT" '(1.0 1.0)) (prin1) ) Command: FRACTION Command: Printing the value from the last evaluation can be an annoyance to an AutoCAD user, but scrolling lines and lines of a function traceback can be very frustrating. Whenever a function cannot be evaluated properly due to entry error or a CTRL C, the AutoLISP interpreter iss