Hi, all.
I've tested all (or most) of the individual parts of the following code (which, upon pasting below, lost all of the indentation for some reason, so my apologies for the apparent bad formatting). Also attached the MLTT.lsp file, in case it would help...
When I run the command "MLTT", the command goes through and asks the user for the wall width (say, 6), but once that is chosen the program throws an error which I can't seem to fix:
Error: bad function: "WALLS_6IN_CLOSED"
It happens when the code calls the function MLStyleCreate for the first time (see in blue below).
Question: can't I provide a string to that function? Is there something wrong with the function setup below?
Super thanks in advance for any help!
; --------------------------------------------------------------------------------------------------
; ---------------------------------- Main User Commands --------------------------------------------
; --------------------------------------------------------------------------------------------------
; Dynamic width command call, TOP justification:
(defun C:MLTT ( / MyMLStyleName MyMLWidth MyMLJust)
; First, ask user for MLine width:
(setq MyMLWidth (MLWidthCall))
; Then set the remaining variables:
(setq MyMLStyleName (strcat "WALLS_" (itoa MyMLWidth) "IN_CLOSED"))
(setq MyMLJust 0) ; 0 = top, 1 = zero, 2 = bottom
; Start main function:
(MLStyleCreate (MyMLStyleName MyMLWidth MyMLJust))
)
;
; --------------------------------------------------------------------------------------------------
; ----------------------------- Core Functions (DO NO EDIT) ----------------------------------------
; --------------------------------------------------------------------------------------------------
;
; Ask user for MLine width:
(defun MLWidthCall ( / temp)
; check if MLWidth is set already (set it up otherwise):
(if (null *MLWidth*)
(setq *MLWidth* 6) ; change this integer to most commonly used
)
(initget 6) ; bit 4+2: allows only non-zero, positive integers
(if (setq temp (getint (strcat "\nEnter a positive non-zero integer for wall width <" (itoa *MLWidth*) ">: ")))
(setq *MLWidth* temp)
)
*MLWidth*
)
; Sets MLine style (create it if needed) and calls MLine command:
(defun MLStyleCreate (MyMLStyleName MyMLWidth MyMLJust / *error* OldEcho)
;Error happens before it gets to this point
; Setup the error function:
(defun *error* ( msg )
(if (not (member msg '("Function cancelled" "quit / exit abort")))
(princ (strcat "\nError: " msg))
)
(princ)
)
; Silent mode start:
(setq OldEcho (getvar "CmdEcho"))
(setvar "CmdEcho" 0)
; Only creates if the style does not yet exist:
(if (not (MLineStyleCheck (MyMLStyleName)))
(progn
(if
(dictadd
(cdar (dictsearch (namedobjdict) "ACAD_MLINESTYLE"))
MyMLStyleName
(entmakex
(list
(cons 0 "MLINESTYLE")
(cons 100 "AcDbMlineStyle")
(cons 2 MyMLStyleName) ; 2 = MLine style name
(cons 70 272) ; 70 = endcaps (272 = closed)
(cons 3 (strcat "Walls " (itoa MyMLWidth) "\" wide")) ; 3 = description
(cons 51 (* 90 (/ PI 180))) ; 51 = start angle in radians
(cons 52 (* 90 (/ PI 180))) ; 51 = end angle in radians
(cons 71 2) ; 71 = number of lines in style
(cons 49 (/ MyMLWidth 2.0)) ; 49 = first offset
(cons 62 256) ; 62 = first offset color (256 = Bylayer)
(cons 6 "BYLAYER") ; 6 = first offset linetype
(cons 49 (* -1 (/ MyMLWidth 2.0))) ; 49 = second offset
(cons 62 256) ; 62 = second offset color (256 = Bylayer)
(cons 6 "BYLAYER") ; 6 = second offset linetype
)
)
)
; if MyMLStyleName had to be created above:
(princ (strcat "\n:: MLine style \"" MyMLStyleName "\" has been created ::\n"))
)
)
)
; set MyMLStyleName active, justification, and scale:
(setvar "CMLStyle" MyMLStyleName)
(setvar "CMLJust" MyMLJust)
(setvar "CMLScale" 1)
; Draw MLine:
(MLineDraw)
; silent mode end:
(setvar "CmdEcho" OldEcho)
(princ)
)
; Check if multiline style already exists (returns nil if not):
(defun MLineStyleCheck (MyMLStyleName / MLStyleDict MLStyle)
(if (setq MLStyleDict (dictsearch (namedobjdict) "ACAD_MLINESTYLE"))
(while
(and MLStyleDict
(not
(setq MLStyle
(if
(and
(assoc 3 MLStyleDict)
(= (strcase (cdr (assoc 3 MLStyleDict))) (strcase MyMLStyleName))
)
(list
(strcase MyMLStyleName)
(cdr (cadr (member (assoc 3 MLStyleDict) MLStyleDict)))
)
)
)
)
)
(setq MLStyleDict (cdr(member(assoc 3 MLStyleDict)MLStyleDict)))
)
)
MLStyle
)
; Draw Mline:
(defun MLineDraw ( / CurrLayer MyLayer MyLayerColor MyLayerDesc)
; Set pre-function layer:
(setq CurrLayer (getvar "CLayer")) ;stores current layer in memory
; Set up new layer variables
(setq MyLayer "A-WALL")
(setq MyLayerDesc "Architectural walls")
(setq MyLayerColor 1)
; Create layer if needed, then set it current:
(if (not (tblsearch "layer" MyLayer)) ; Checks if MyLayer exists
; if not (= nil), then create it:
(progn
; using "Make" makes the new layer current:
(command "-.Layer" "Make" MyLayer "Description" MyLayerDesc MyLayer
"Color" MyLayerColor MyLayer "")
(princ (strcat "\n:: Layer \"" MyLayer "\" created ::\n"))
)
; if yes, then make it current:
(setvar "CLayer" MyLayer)
)
(command "MLine")
; Wait for the MLine command to end:
(while (> (getvar "CMDACTIVE") 0) (command pause))
; Set pre-function layer back:
(setvar "CLayer" CurrLayer)
)
Solved! Go to Solution.
Solved by john.uhden. Go to Solution.
Solved by pbejse. Go to Solution.
This
(MLStyleCreate (MyMLStyleName MyMLWidth MyMLJust))
To
(MLStyleCreate MyMLStyleName MyMLWidth MyMLJust)
This
(not (MLineStyleCheck (MyMLStyleName)))
To
(not (MLineStyleCheck MyMLStyleName))
This
(command "-.Layer" "Make" MyLayer "Description" MyLayerDesc MyLayer
"Color" MyLayerColor MyLayer "")
To
(command ".Layer" "Make" MyLayer "Description" MyLayerDesc MyLayer
"Color" MyLayerColor MyLayer "")
@pbejse hit the nail on the head.
You had created MyMLStyleName as a string, but later your code used it at the beginning of an argument list ...
"; Only creates if the style does not yet exist:
(if (not (MLineStyleCheck (MyMLStyleName)))"
which is not taking the MyMLStyleName as a string input, but rather as a call to a function named MyMLStyleName, which does not exist and returns the error "bad function."
Perhaps you are slightly confused about function definitions and function usage.
In defining a function you provide its name followed in parentheses any input arguments and local variable names.
In calling a function requiring one or more input arguments, you do not place them in a list.
For example:
(defun concatenate (1st 2nd)
(strcat 1st 2nd)
)
Later...
(setq str1 "Have a " str2 "nice day!")
(setq concatenation (concatenate str1 str2))
"Have a nice day!" ;; ^__ notice no parenthesis
OR, I prefer to believe it was just a typo.
John F. Uhden
Thanks for helping me troubleshoot my code, @pbejse and @john.uhden - you guys rock!
Very kind of you John, to assume those were just typos 😁 - truth is, I had forgotten those parenthesis were not supposed to be there (as if Lisp doesn't already have enough parenthesis 🤣). I'll probably never forget the correct syntax from now on...
Again, thanks for the comments you both provided - my routine works perfectly now 👍
Can't find what you're looking for? Ask the community or share your knowledge.