Search code examples
autocadautolisp

How to create a lisp to insert blocks with AutoLISP?


So, I am kinda new to the AutoLisp world and I wanted to create a lisp that defines a command named "FF" to insert specific blocks. For example, the user types FF, then defines the first point and then types a string like "TFN". The thing is, in this string all characters are blocks, F corresponds to a block, and so do N and T. Here is the code:

(defun c:FF () 
(setq P (getpoint "Define origin:"))
(setvar aux 1)
(setq seq (getstring "Define the sequence of blocks:"))
(foreach str seq
     (command "insert" str (polar P (* pi 2) (aux*2)))
     (incf aux) 
)
)

It's supossed to look like this:

enter image description here

By the way, the "aux" variable is used to create separation between the blocks.

Autocad 2010 does recognize the command FF, then requires a point, but when the point is defined it returns this: error: bad argument type: (or stringp symbolp): nil


Solution

  • There are several issues with your code, but the error arises from the use of setvar in the expression:

    (setvar aux 1)
    

    Here, the symbol aux is being evaluated as an argument to the setvar function and is yielding a value of nil, which is an invalid string or symbol representing a system variable as required by the setvar function.

    Instead, you should assign variables using the setq (aka "set quote"), which will not evaluate the first supplied argument:

    (setq aux 1)
    

    You'll also encounter an error with your foreach statement, as seq is a string and foreach can only iterate over lists.

    Instead, you'll need to separate the string into a list of individual characters, either using substr or a combination of vl-string->list & chr.

    Or alternatively, iterate over the string using substr until you're left with an empty string, for example:

    (while (/= "" seq)
        (setq blk (substr seq 1 1)
              seq (substr seq 2)
        )
        (if (or (tblsearch "block" blk) 
                (setq blk (findfile (strcat blk ".dwg")))
            )
            (command "_.-insert" blk "_S" 1.0 "_R" 0.0 "_non" (polar p 0.0 (* aux 2.0)))
        )
    )
    

    This will also account for the user pressing ENTER at the getstring prompt, as the test expression for the while loop will not be satisfied.

    Note that incf is not a valid AutoLISP function, unless this is a function that you have separately defined.

    You may also want to consider setting the ATTREQ system variable to 0 prior to inserting the blocks, so that you do not receive the prompt to supply attribute values.