pman860507 发表于 2022-7-6 08:53:56

复制并替换objec文本

这仅用于插入块的多行文字和文字。我遇到的问题是,如果该项是文本,那么它将只替换最后一个对象的文本,因为im使用(setq ss1(ssget“L”))也有(entlast),但它只会创建最后一个实体。有没有一种方法可以在不必选择复制文本的情况下获取所有这些文本。然后一个while循环来编辑每一个。
 
谢谢
 
Lisp文件:
 
(defun sVars()
(setq text_edit(get_tile "text_edit"))
(princ))

(defun edit ()
(setq dcl_id (load_dialog "copy_blk.dcl"))
(if (not (new_dialog "copy_blk" dcl_id) ) (exit))
(set_tile "text_edit" temp1)
(mode_tile "text_edit" 3)
(action_tile "cancel" "(setq ddiag 1)(done_dialog 0)")
(action_tile "accept" "(setq ddiag 2)(sVars)(done_dialog 1)")
(start_dialog)
(unload_dialog dcl_id)

(if (= ddiag 1)
   (progn
   (setq newval temp1)
   (princ "\n Command cancelled\n") (exit)))

   (if (= ddiag 2)
   (progn
   (setq newval text_edit)
   (princ "\n Text Changed\n")))
   (princ))
         

(defun C:Copy_blk (/ blkType INDEX COUNT en2 enlist temp temp1 enlist2 ins newblk newblk2 newent newent2 newval ss en newentlist2 ss1 INDEX1)
(vl-load-com)
(setq acadObject (vlax-get-acad-object))

(defun *Error* (Msg)
(cond ((member Msg '("Function cancelled" "quit / exit abort")))
((princ (strcat "Error: " Msg))
(princ "\nRestoring System Variables ")
(terpri)))
(princ))

(if (setq ss(ssget "_:L" '((0 . "INSERT,TEXT,MTEXT"))))                              
(progn
(setq INDEX1 -1)
(setq en (ssname ss (setq INDEX1 (1+ INDEX1))))                              
(setq enlist(entget en))
(setq ins(cdr(assoc 10 enlist)))                                          
(command "copy" ss "" ins pause)
(setq ss1 (ssget "L"))
(setq INDEX -1 COUNT 0)
(while (setq en1 (ssname ss1 (setq INDEX (1+ INDEX))))
(setq enlist1(entget en1))
(setq blkType(cdr(assoc 0 enlist)))                                             

(if (= blkType "INSERT")                                                      
(progn
   (if(= (cdr(assoc 66 enlist)) 1)                                                
   (progn
       (setq en2(entnext en1))                                                      
       (setq enlist2(entget en2))
       (setq temp1 (cdr (assoc 1 enlist2)))
       (edit)
       (setq enlist2 (subst (cons 1 newval)(assoc 1 enlist2)enlist2))
       (entmod enlist2)))))
   
(if (or(= blkType "TEXT")(= blkType "MTEXT"))
(progn
   (setq temp1 (cdr (assoc 1 enlist1)))
   (edit)
   (setq enlist1 (subst (cons 1 newval)(assoc 1 enlist1)enlist1))
   (entmod enlist1))))))
(princ))
 
DCL文件:
 
copy_blk : dialog {
   label = "Edit value of object";
   initial_focus = "text_edit";
       :column{
       spacer;
       : edit_box
       {
       label = "Enter value:";
       key = "text_edit";
       edit_width = 75;
       edit_limit = 256;
       alignment = centered;
       allow_accept = true;
       }
       spacer;
      
         :row{
         : button{
         key = "accept";
         label = "Ok";
         is_default = true;
         edit_width = 1;
         alignment = centered;
         }
         :button{
         key = "cancel";
         label = "Cancel";
         is_default = false;
         is_cancel = true;
         edit_width = 1;
         alignment = centered;
         }
       }
       }
       }
      
      

BlackBox 发表于 2022-7-6 08:59:54

欢迎来到CADTutor!
 
为了澄清:
 
在ssget语句中使用“L”作为sel方法将创建添加到数据库的最后一个可见对象的选择集。
 
使用“_:L”作为sel方法,将提示用户选择解锁层的对象。
 
也许您会受益于vla copy方法,而不是重复(命令“\u copy”…调用。此外,考虑使用cond语句代替多个if语句。
 
HTH公司

pman860507 发表于 2022-7-6 09:02:45

我认为自己是LISP的初学者,我发现自己总是使用IF语句。使用cond有什么好处。此外,我不知道任何关于视觉Lisp。当我需要它的时候,我读了一些关于它的东西,但我什么都不记得了。我会看看vla副本。

BlackBox 发表于 2022-7-6 09:04:18

 
当您需要测试多个条件(恰当地命名)时,Cond非常好。
 
举个简单的例子:
 

(defun c:FOO ( / opt)
(if (and (not (initget 1 "This tHat Other"))
          (setq opt (strcase (getkword "\nEnter an option : "))))
   (prompt
   (strcat
       "\nYou entered: "
       (cond ((= "THIS" opt) "THIS ")
             ((= "THAT" opt) "THAT ")
             ((= "OTHER" opt) "OTHER ")))))
(terpri)
(princ))

 
编辑:注意,在这个示例中,我故意使用显式文本“THIS”、“that”或“OTHER”,通常如果使用具有所述值的变量,您只需使用该变量。
 
有关更多信息,请参阅开发人员文档。
 
 
别担心;稍后我们将重新访问Visual LISP。。。我花了一些时间来学习vl*函数,然后我就喜欢上了。

pman860507 发表于 2022-7-6 09:08:40

酷,在我弄清楚如何自动添加复制到实体或选择集的新对象后,我将研究cond。

BlackBox 发表于 2022-7-6 09:11:45

 
考虑ssadd函数:
 

(setq newSS (ssadd (entlast)))

Lee Mac 发表于 2022-7-6 09:14:50

与多个非嵌套IF语句相比,COND的另一个优点是,在测试条件返回非nil值时,不会不必要地评估其他测试条件。
 
例如:
 

(defun c:test ( / num )
   (if (setq num (getint "\nEnter a Number: "))
       (cond
         (   (minusp num)
               (princ "\nYou Entered a Negative Number.")
         )
         (   (zerop num)
               (princ "\nYou Entered Zero.")
         )
         (   (= 3 num)
               (princ "\nYou Entered the Number 3.")
         )
         (   t
               (princ "\nYou Enter a Positive Non-zero Number not equal to 3.")
         )
       )
   )
   (princ)
)而不是:
 
由于只有一个条件可以返回T,因此在测试条件返回T后评估任何其他条件都没有意义。
 
COND的求值顺序与一组嵌套的IF语句相同,即您在其他语言中可能看到的“IF/Else-IF”结构(在其他语言中找到的“switch”语句也类似):
 
但是我认为你会同意COND语句更具可读性。
 

pman860507 发表于 2022-7-6 09:18:47

我确实同意cond声明更容易阅读。它还使您的程序不必计算每个if语句。让它跑得更快一点。
 
如果我使用

(setq newSS (ssadd (entlast)))

它只获取放入数据库的最后一个对象。
我想使用多行dtext,那么它只会选择一行
的行(始终放在最后)。

BlackBox 发表于 2022-7-6 09:21:26

也许这个例子可以澄清:
 

(defun c:FOO ( / ss e ss2)
(if (setq ss (ssget "_:L"))
   (progn
   (setq e (entlast))
   (command "._copy" ss "" '(0 0 0) '(0 0 0))
   (while (/= nil (setq e (entnext e)))
       (setq
         ss2 (ssadd e
                      (cond (ss2)
                            ((setq ss2 (ssadd (entnext e))))))))
   (sssetfirst nil ss2))
   (prompt "\n** Nothing selected ** "))
(princ))

 
注意entlast的顺序、复制操作,然后是后续的entnext调用。
 
下面是另一种对声明较少的变量执行相同操作的方法:
 
9
 
HTH公司

BlackBox 发表于 2022-7-6 09:22:46

我会补充说,虽然已经重新阅读了你的一些代码。。。而不是生成结果复制项的选择集,然后逐步通过二级选择集。。。只需在while循环本身期间对实体执行操作。更少的迭代。
 
我稍后将发布一个示例。
页: [1] 2
查看完整版本: 复制并替换objec文本