绘制特定集团的BBox
大家好,我正在尽全力,但仍然不明白为什么会出现这样的错误:
Error: too many arguments
代码假设通过名为“VLD\uРАМКАКАV2”的特定动态块过滤选择,然后围绕每个具有该名称的选定块对象绘制边界框:
; Make a selection and filter certain block by its effective name
; Get and draw the boundingbox around each block object
(defun c:test (/ blkname found objs ss name blk vlst ovar minpt maxpt crds)
(if
(and
(not
(setq blkname "VLD_РАМКА_V2") ;<-BLOCK NAME
(princ "\nSelect objects" )
(setq found (tblsearch "BLOCK" blkname))
(setq objs (ssadd))
(setq ss (ssget "_:L" '((0 . "INSERT"))))
);not
);and
(progn
(repeat
(setq i (sslength ss))
(setq name (vla-get-effectivename
(vlax-ename->vla-object
(setq blk (ssname ss (setq i (1- i))))
)
)
)
(if (eq (strcase blkname) (strcase name))
(ssadd blk objs)
)
)
(if objs
(progn
(sssetfirst nil objs) ; is this required ?
(setq vlst '("CMDECHO" "OSMODE" "DIMASSOC")
ovar (mapcar 'getvar vlst))
(mapcar 'setvar vlst '(0 0 2))
(foreach obj(mapcar 'vlax-ename->vla-object
(vl-remove-if 'listp (mapcar 'cadr (ssnamex objs))))
(vla-getboundingbox obj 'minpt 'maxpt)
(setq crds (mapcar 'vlax-safearray->list (list minpt maxpt)))
(command "_.rectangle" (car crds) (cadr crds))
(mapcar 'setvar vlst ovar)
);foreach
(princ (strcat "\nSelected " (itoa (sslength objs)) " blocks "))
);progn
); if objs
);progn
(cond
((null ss)
(princ "\nEmpty Selection!") ;(C:test)
)
((not blkname)
(princ "\n Missed name of block ***")
)
((not found)
(princ "\n Block not found in drawing !!!")
)
(t
(princ "\n couldn't find any block !!! ")
)
);cond
);if
(princ)
);defun 我从这里开始
http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-991AD6A0-61AA-45C9-8C27-CADF9F36BE71
请注意,“not”函数只接受一个参数。你现在有五个。
我还要看看你的条件
符号“objs”指向上一个setq中的选择集。
即使选择集没有添加新实体,它仍将返回非nil值。 早上好
除了克林特指出的,让我向你们展示一些你们可能不清楚的潜在错误。
测试此代码:
(if (setq objs (ssadd))
(alert "Variable objs has values")
(alert "Variable objs doesn't have any value")
)
上述代码永远不会返回nil,因为函数ssadd总是有一个值,您可能会认为它只是一个变量声明,如果实体名称与您的条件匹配,则向其添加实体名称,因此您在项目中的语句(如果objs….永远不会等于nil,这被认为是获得代码预期结果的错误且不正确的方法。
因此,在这种情况下,您需要检查变量“objs”的值是否不止一个,因为函数ssadd的第一次返回将有一个选择集。
包含在cond函数中的代码永远不会返回nil,因为变量“blkname”的值是原始块名(字符串类型),因此永远不会到达cond函数的下一个表达式。
((not blkname) ......
foreach函数中包含以下代码,这意味着只有第一个边界框将正确绘制到其位置,其余边界框不会正确绘制到其位置,因为系统变量OSMODE将返回到其原始设置。
(mapcar 'setvar vlst ovar)
最后一件需要注意的事情是,当您检查块名称时,您已经拥有了vla对象,因此只需将实体名称的vla对象添加到变量中,而不是使用ssnamex函数再次检索它们,ssnamex函数是相同对象的额外迭代,您可以不用它。
希望这不会让你失望,但会鼓励你在下一个项目中意识到它们。
快乐的编码。 谢谢大家!
根据克林特的建议,我设法解决了主要问题。
嗨,塔瓦
(if (setq objs (ssadd))
(alert "Variable objs has values")
(alert "Variable objs doesn't have any value")
)
那么支票必须变成这样
(if (> (sslength objs) 1)
(alert "Variable objs has values")
(alert "Variable objs doesn't have any value")
)
谢谢你的其他建议,但我不完全理解:
老实说,在将对象转换为实体以及将实体转换为对象的过程中,我有点不知所措。我只是从您/LM的代码中提取一些部分并重用它们(很抱歉,但我尝试从最好的代码中学习)。
你有什么例子说明这是怎么回事吗?我的意思是,如果使用entsel/entsel或ssget,我们会得到什么类型的对象?什么时候需要转换以用于其他功能?我只是不知道该去哪里了解整个过程。 最好检查它是否大于零而不是一,实际上我只是想告诉你,当你调用函数ssadd时,它将有值,为了检查是否有任何对象添加到我们第一个构建的ssadd中,我们需要检查其变量的数量是否大于零,正如你在上面的示例中所示,尽管你在程序中根本不需要它。
看看下面的MOD;
(repeat (setq i (sslength ss))
(setq vla-obj (vlax-ename->vla-object (setq blk (ssname ss (setq i (1- i)))))
name (vla-get-effectivename vla-obj)
)
(if (eq (strcase blkname) (strcase name))
(setq lst (cons vla-obj lst))
)
)
(if lst
(progn
(setq vlst '("CMDECHO" "OSMODE" "DIMASSOC")
ovar (mapcar 'getvar vlst)
)
(mapcar 'setvar vlst '(0 0 2))
(foreach obj lst
(vla-getboundingbox obj 'minpt 'maxpt)
(setq crds (mapcar 'vlax-safearray->list (list minpt maxpt)))
(command "_.rectangle" "_non" (car crds) "_non" (cadr crds))
)
(mapcar 'setvar vlst ovar)
)
)
您可以在此链接中找到所有AutoLISP函数 谢谢,塔瓦!
我查一下:
ssname ssnamex vlax ename->vla对象和vlax vla对象->ename
功能。
如果我理解正确,只有这两种类型:
实体名称(ename)
10
VLA对象
10
类似于代码中的“物理对象”,可以在其他函数中作为参数接受
(正如我所见,vla get effectivename需要vla obj
entget需要ename)。
对不起,如果我写的是废话。很难理解它是如何工作的。 是的,我同意你提到的。
使用纯AutoLISP时,不需要任何转换,但必须处理Vlisp和Active-X对象。
当你使用长而大的程序时,你会注意到这两种类型之间的速度。DXF是纯AutoLISP,比Vlisp代码更快、更平滑。 在没有任何离题的情况下,我将继续阅读您在这个论坛上发布了几次的LISP库。
我认为,通过检查每个“未知”函数的参数和返回,我可能会跳过最常见的错误。
祝你晚上愉快! 专注于您正在阅读或使用的任何函数的返回值,因为这将帮助您了解程序打算采用的方式。
谢谢你也是。
页:
[1]