英文:
How to create a lisp to insert blocks with AutoLISP?
问题
这段代码的目标是创建一个名为"FF"的AutoLisp命令,用于插入特定的块。用户输入"FF",定义第一个点,然后输入类似"TFN"的字符串。在这个字符串中,每个字符都对应一个块,F、N和T都是块。代码中的"aux"变量用于在块之间创建间隔。
请注意,Autocad 2010会识别"FF"命令,然后要求输入一个点,但当点被定义后,出现了错误:"error: bad argument type: (or stringp symbolp): nil"。
英文:
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:
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
答案1
得分: 0
你的代码存在一些问题,但错误是因为在表达式中使用了 setvar
:
(setvar aux 1)
在这里,符号 aux
被评估为 setvar
函数的参数,返回值是 nil
,这不是 setvar
函数所需的有效字符串或符号来表示系统变量。
相反,你应该使用 setq
(又称 "set quote"),它不会评估第一个提供的参数:
(setq aux 1)
你还将遇到与你的 foreach
语句相关的错误,因为 seq
是一个字符串,而 foreach
只能迭代列表。
相反,你需要将字符串分割成单个字符的列表,可以使用 substr
或 vl-string->list
与 chr
的组合。
或者,你可以使用 substr
迭代字符串,直到你得到一个空字符串,例如:
(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)))
)
)
这还可以处理用户在 getstring
提示处按下 ENTER 键的情况,因为 while
循环的测试表达式将不满足条件。
请注意,incf
不是有效的 AutoLISP 函数,除非这是你单独定义的函数。
你还可以考虑在插入块之前将 ATTREQ
系统变量设置为 0
,这样你就不会收到提示以提供属性值。
英文:
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 <kbd>ENTER</kbd> 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论