Lisp "Error: bad function" thrown and Help with coding conditions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm trying to create a utility that will ask the users a few questions and then update all instances of a block within appropriately. This also my first attempt at DCL, so it's been a fun process along the way. The issue that I am having is during my initial testing of how the Dialog box functions and behaves, I get an error " ** Error: bad function: "30x42" ** ". One thing I do know is that "30x42" is listed as an available sheet size only for our Arizona off, but regardless of what region and sheet size I choose, I always get the same error. Please see the code below.
On additional note since I am here already, would someone help point me in the right direction on how the utility should approach the conditions in the section area of the tbupdater at the bottom. The selections in the dialog box will determine which block to insert, whether for a model or a lot specific, and which insertion point the block should have. So the code should determine the region, whether it is a model or lot specific, then the insertion point based of the sheet size. Some regions only have one sheet size, so those can skip that part.
Any and all help will be greatly appreciated, so thank you in advance.
Lisp Code:
(defun c:tbu ( / *error* UpdateList data dclfile dclhandle ) ;; Load Visual Lisp Functions (vl-load-com) ;; Set Undo marker (Setq thisdrawing (vla-get-activedocument (vlax-get-acad-object))) (vla-startundomark thisdrawing) ;; Load Accompanying DCL File (setq dclFile "tbuu.dcl") ;; Error Handler - will unload the dialog from memory should the user decide to hit Esc (defun *error* ( msg ) (if dclHandle (unload_dialog dclHandle)) (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\n** Error: " msg " **")) (*return_setvar*) ) (princ) ) ;; Set Variables - will log current values then set them to the appropriate values (defun *new_setvar* () (setq oom (getvar "osmode")) ; store osmode setting (setvar "osmode" 0) ; set osmode to 0 (setq oce (getvar "cmdecho")) ; store cmdecho setting (setvar "cmdecho" 0) ; set cmdecho to 0 (setq ocar (getvar "attreq")) ; store attreq setting (setvar "attreq" 0) ; set attreq to 0 (setq ocfd (getvar "filedia")) ; store filedia setting (setvar "filedia" 0) ; set filedia to 0 (setq occt (getvar "ctab")) ; store current tab name (setvar "tilemode" 0) ; set tilemode to 0 ) ;; Reset Variables - returns variables to previous logged values (defun *return_setvar* () (setvar "osmode" oom) ; reset osmode to original setting (setvar "cmdecho" oce) ; reset cmdecho to original setting (setvar "attreq" ocar) ; reset attreq to original setting (setvar "filedia" ocfd) ; reset filedia to original setting (setvar "ctab" occt) ; reset to original tab ) ;; This function updates the list_box associated with the specified key using the contents of the supplied lst (defun UpdateList ( key lst ) (start_list key) (mapcar 'add_list lst) (end_list) ) ;; Data used to Populate List_Boxes: (setq Data '( ("Arizona" ("30x42")) ("California" ("24x36")) ("Colorado" ("22x34")) ("Florida" ("22x34" "24x36" "34x44")) ("Northeast" ("22x34" "24x36" "34x44")) ("Northwest" ("22x34")) ("Texas" ("22x34")) ("Sales Office" ("22x34")) ) ) ;; Start of Main Routine with lots of Error Trapping to make sure the Dialog Loads: (cond ( (<= (setq dclHandle (load_dialog dclFile)) 0) (princ "\ACA> DCL File not Found.") ) ( (not (new_dialog "tbuu" dclHandle)) (setq dclHandle (unload_dialog dclHandle)) (princ "\ACA> Dialog Definition not Found.") ) ( t ;; If Dialog Loads Successfully. ;; Log the values of current variables then sets them to appropriate values (*new_setvar*) ;; Set up some default selections, for the first-time running of the program. ;; The variables *Region* & *Size* are intended to be global and hence will remember the user's last selections. (or *Model* (setq *Model* "0")) (or *Lot* (setq *Lot* "0")) (or *Region* (setq *Region* "0")) (or *Size* (setq *Size* "0")) ;; Populate the List_Boxes: ;; List_Box 'tbreg' (UpdateList "tbreg" (mapcar 'car Data)) (set_tile "tbreg" *Region*) ;; List_Box 'tbsize' (UpdateList "tbsize" (cadr (nth (atoi *Region*) Data))) (set_tile "tbsize" *Size*) ;; Action_tile Statements: ;; These control the action to evaluate when the user interacts with a tile in the dialog. ;; Note that $value is a string containing the index of the item that the user has selected. (action_tile "mod" "(setq *Model* $value)") (action_tile "lot" "(setq *Lot* $value)") ;; Here, when the user selects a region in 'tbreg', the UpdateList subfunction is fired to update the available sheet size in list_box 'tbsize'. (action_tile "tbreg" (strcat "(UpdateList \"tbsize\" (setq tbsize (cadr (nth (atoi (setq *Region* $value)) Data))))" "(setq *Size*" " (set_tile \"tbsize\"" " (if (< (atoi *Size*) (length tbsize)) *Size* \"0\")" " )" ")" ) ) ;; list_box 'tbsize' is also set to the value of *Size* if the index is available for the selected item, else the first item is selected. (action_tile "tbsize" "(setq *Size* $value)") ;; If user clicks OK, this will store the values then run the "tbupdater" (action_tile "accept" (strcat "(progn (setq tbumod (atof (get_tile \"mod\")))" "(setq tbulot (atof (get_tile \"lot\")))" "(setq tbureg (atof (get_tile \"tbreg\")))" "(setq tbusize (atof (get_tile \"tbsize\")))" "(done_dialog 1)(tbupdater))" ) ) ;; If user clicks Cancel, this will close the dialog box and then return the variables back to previous values (action_tile "cancel" "(done_dialog 0)") ;; Dialog setup complete, now lets start it: (start_dialog) (setq dclHandle (unload_dialog dclHandle)) ) ) ;; End UNDO marker (vla-endundomark thisdrawing) (princ) ); end of tbu ;| (defun tbupdater () ;; Remove All inserted TB Props followed by purging all blocks (DELTB7) ;| Planning If Region = Arizona and Model is selected Size is always 30x42 Insert TB Props at x=0 y=0 z=0 or Lot is selected Size is always 30x42 Insert TB Props Lots at x=0 y=0 z=0 If Region = California and Model is selected Size is always 24x36 Insert TB Props at x=0 y=0 z=0 or Lot is selected Size is always 24x36 Insert TB Props Lots at x=0 y=0 z=0 If Region = Colorado and Model is selected Size is always 22x34 Insert TB Props at x=0 y=0 z=0 or Lot is selected Size is always 22x34 Insert TB Props Lots at x=0 y=0 z=0 If Region = Florida and Model is selected and size is 22x34 Insert TB Props at x=2'-7 1/16" y=9/16" z=0 24x36 Insert TB Props at x=2'-9 1/16" y=9/16" z=0 34x44 Insert TB Props at x=3'-5 1/16" y=9/16" z=0 or Lot is selected and size is 22x34 Insert TB Props Lots at x=2'-7 1/16" y=9/16" z=0 24x36 Insert TB Props Lots at x=2'-9 1/16" y=9/16" z=0 34x44 Insert TB Props Lots at x=3'-5 1/16" y=9/16" z=0 If Region = Northeast and Model is selected and size is 22x34 Insert TB Props at x=2'-7 1/16" y=9/16" z=0 30x42 Insert TB Props at x=3'-3 1/16" y=9/16" z=0 34x44 Insert TB Props at x=3'-5 1/16" y=9/16" z=0 or Lot is selected and size is 22x34 Insert TB Props Lots at x=2'-7 1/16" y=9/16" z=0 24x36 Insert TB Props Lots at x=2'-9 1/16" y=9/16" z=0 34x44 Insert TB Props Lots at x=3'-5 1/16" y=9/16" z=0 If Region = Northwest and Model is selected Size is always 22x34 Insert TB Props at x=0 y=0 z=0 or Lot is selected Size is always 22x34 Insert TB Props Lots at x=0 y=0 z=0 If Region = Sales Office (Northeast TB Props) Size is always 22x34 Insert TB Props at x=2'-7 1/16" y=9/16" z=0 If Region = Texas and Model is selected Size is always 22x34 Insert TB Props at x=0 y=0 z=0 or Lot is selected Size is always 22x34 Insert TB Props Lots at x=0 y=0 z=0 |; (princ) (princ "\nTCS> The Titleblock Properties within this drawing have been updated.") ); end of tbupdater
DCL Code:
// To be saved within a support path and named "tbuu.dcl" lbox : list_box { width = 18; fixed_width = true; alignment = centered; } tbuu : dialog { label ="Update Titleblock Properties Utility"; spacer; : radio_row {label = "Model or Lot :"; : radio_button {key = "mod"; label = "&Model"; value = 1; } : radio_button {key = "lot"; label = "&Lot"; value = 0; } } : row { : lbox { key = "tbreg"; label = "&Region or Department :" ; } : lbox { key = "tbsize"; label = "S&heet Size :"; } } ok_cancel ; }