Grrr 发表于 2022-7-5 17:49:59

绘制特定集团的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

cwake 发表于 2022-7-5 18:01:47

我从这里开始
http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-991AD6A0-61AA-45C9-8C27-CADF9F36BE71
 
请注意,“not”函数只接受一个参数。你现在有五个。
 
我还要看看你的条件
符号“objs”指向上一个setq中的选择集。
即使选择集没有添加新实体,它仍将返回非nil值。

Tharwat 发表于 2022-7-5 18:09:25

早上好
 
除了克林特指出的,让我向你们展示一些你们可能不清楚的潜在错误。
 
测试此代码:

(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函数是相同对象的额外迭代,您可以不用它。
 
希望这不会让你失望,但会鼓励你在下一个项目中意识到它们。
 
快乐的编码。

Grrr 发表于 2022-7-5 18:17:34

谢谢大家!
根据克林特的建议,我设法解决了主要问题。
 
嗨,塔瓦
(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,我们会得到什么类型的对象?什么时候需要转换以用于其他功能?我只是不知道该去哪里了解整个过程。

Tharwat 发表于 2022-7-5 18:22:07

最好检查它是否大于零而不是一,实际上我只是想告诉你,当你调用函数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函数

Grrr 发表于 2022-7-5 18:27:42

谢谢,塔瓦!
 
我查一下:
ssname ssnamex vlax ename->vla对象和vlax vla对象->ename
功能。
 
如果我理解正确,只有这两种类型:
 
实体名称(ename)
10
VLA对象
10
类似于代码中的“物理对象”,可以在其他函数中作为参数接受
(正如我所见,vla get effectivename需要vla obj
entget需要ename)。
 
对不起,如果我写的是废话。很难理解它是如何工作的。

Tharwat 发表于 2022-7-5 18:39:12

是的,我同意你提到的。
使用纯AutoLISP时,不需要任何转换,但必须处理Vlisp和Active-X对象。
 
当你使用长而大的程序时,你会注意到这两种类型之间的速度。DXF是纯AutoLISP,比Vlisp代码更快、更平滑。

Grrr 发表于 2022-7-5 18:44:10

在没有任何离题的情况下,我将继续阅读您在这个论坛上发布了几次的LISP库。
我认为,通过检查每个“未知”函数的参数和返回,我可能会跳过最常见的错误。
祝你晚上愉快!

Tharwat 发表于 2022-7-5 18:50:26

专注于您正在阅读或使用的任何函数的返回值,因为这将帮助您了解程序打算采用的方式。
 
谢谢你也是。
页: [1]
查看完整版本: 绘制特定集团的BBox