BCL 发表于 2022-7-5 16:10:32

需要EED/扩展数据方面的帮助

大家好,第一次海报。我是一名业余程序员和autoCAD新手。我试图在visualLISP中创建一个项目,但在EED/扩展数据方面遇到了问题。我希望能够选择一个实体(在我的情况下,99%的时间它将是一条直线)并向其添加自定义数据。它总是有相同数量的数据条目,9(我需要查看Xrecord吗?),但对于每个实体,实际数据将不同。
 
我发现一些代码实现了一些类似于我试图实现的东西,所以我一直将其用作模板。我对其进行了大量修改,但不断出现DXF错误-如果有人能告诉我如何使用编辑框而不是弹出列表来实现这一点(这是我的“模板”使用的)。我还注释了我有疑问的部分代码,它们也是正确的(作者就在下面)。
 
正如我所说,我不是autoCAD power用户,但有一些面向对象编程的经验-任何示例代码、文献或教程都将不胜感激。
 
 
非常感谢。
 
布莱恩·莱文斯
 
 
这是我当前的DCL文件-它最终将有9个字段,但首先要做的是。
 

 
这是我试图操纵的模板,以实现我想要的功能
(不是我的代码)
 
(defun c:exbolt ( / )
;define function

(setvar "cmdecho" 0)                              
;switch off command echo

(prompt "\nSelect the Line to add data to : ")
;prompt the user

(setq e (entget (car (entsel)) '("AFRALISP")))
;get the associative code list

(setq e1 (assoc -3 e))                              ;what is the assoc doing?
;get the xdata

(if (not e1)
;if there is no exdata

(progn
;do the following

(if (not (tblsearch "APPID" "AFRALISP"))
;check if the application has been registered
       
        (regapp "AFRALISP")
        ;if not, register it

);if

        (setq e1 '(( -3 ("AFRALISP"                ;I'm not to sure exactly this code works
                  (1000 . "3")                     ;I know that 1000 is the DXF reference and the -3 is in
                  (1000 . "3")                     ;reference to the xdata
                  (1000 . "3")
        ))))
        ;create a default xdata list
       
        (setq e (append e e1))
        ;append to to the main list

        (entmod e)
        ;modify the entity
       
);progn

);if

(setq e2 (assoc -3 e))
;get the code -3 list

(setq e3 (car (cdr e2)))
;get the exdata list

(setq SIZ (cdr (nth 1 e3)))
;get the bolt size index number

(setq SIZ1 (cdr (nth 2 e3)))
;get the bolt length index number

(setq gr (cdr (nth 3 e3)))
;get the bolt grade

(setq userclick T)
;set flag

(setq NAMES '("M6" "M8" "M10" "M12" "M16" "M20" "M24" "M30" "M36"
              ))
;create list of bolt sizes


(setq LEN '("10" "15" "20" "25" "30" "35" "40" "45" "50" "55" "60"))
;create list of bolt lengths

(setq dcl_id (load_dialog "exbolt.dcl"))
;load dialogue

(if (not (new_dialog "exbolt" dcl_id)
;check for errors

      );not

   (exit)
   ;if problem exit

);if

(set_tile "sel1" SIZ)
;initilise list box

(set_tile "sel2" SIZ1)
;initilise list box

(start_list "sel1")
;start the list

(mapcar 'add_list NAMES)
;add the bolt size

(end_list)
;end the list

(start_list "sel2")
;start the list

(mapcar 'add_list LEN)
;add the lengths

(end_list)
;end the list

(cond
;on condition

((= gr "4,6") (set_tile "rb1" "1"))
;if GR 4,6 switch on radio button rb1

((= gr "8,8") (set_tile "rb2" "1"))
;if GR 8,8 switch on radio button rb2

((= gr "HSFG") (set_tile "rb3" "1"))
;if GR HSFG switch on radio button rb3

);end cond

(action_tile "rb1"
;if radio button rb1 selected

           "(setq gr \"4,6\")"
;set grade of bolt

);action_tile

(action_tile "rb2"
;if radio button rb2 selected

           "(setq gr \"8,8\")"
;set grade of bolt

);action_tile

(action_tile "rb3"
;if radio button rb3 selected

           "(setq gr \"HSFG\")"
;set grade of bolt

);action_tile

   (action_tile "cancel"       
   ;if cancel selected

        "(done_dialog)
;end dialog

(setq userclick nil)"
;set flag to nill

   );action_tile
   ;if cancel set flag to nil

(action_tile "accept"       
                                                ;why is this section in quotations?
"(setq siz (get_tile \"sel1\"))         
;get the bolt size

(setq siz1 (get_tile \"sel2\"))
;get the bolt length

(done_dialog)
;end the dialog

(setq userclick T)"
;set the flag to true

);action tile

(start_dialog)       
;start the dialogue

(unload_dialog dcl_id)       
;unload the dialogue

(if userclick       
;if OK has been selected

   (progn
   ;do the following

(setq NSIZ (cons 1000 SIZ))                     
;construct a new bolt size list

(setq NSIZ1 (cons 1000 SIZ1))
;construct a new bolt length list

(setq NGR (cons 1000 gr))
;construct a new bolt grade list

(setq e4 (chnitem NSIZ 2 e3))
;change the existing bolt size list

(setq e5 (chnitem NSIZ1 3 e4))
;change the existing bolt length list

(setq e6 (chnitem NGR 4 e5))
;change the existing bolt grade list

(setq e7 (subst e6 e3 e2))
;update list

(setq e8 (subst e7 e2 e))
;update list

(entmod e8)
;update the entity

    (setq SIZ (nth (atoi SIZ) NAMES))
    ;get the size of the bolt from the list

    (setq SIZ1 (nth (atoi SIZ1) LEN))
    ;get the length of the bolt from the list

    (alert (strcat "The size of bolt is " SIZ "\n"
    "The length of bolt is " SIZ1 "\n"
    "The grade of bolt is " GR)
    );alert


   );end progn

);end if

(princ)
;finish cleanly

);end defun


;;This function replaces any element in a list with another element
;;It requires 3 parameters (chnitem value itemnumber list)

(defun chnitem (value num lst)                                  ;I understand what this codes urpose is
    (setq num (- num 1))                                        ;but do not it is the most confusing to me
    (setq tmplt (list nil))
    (setq tmplt2 (list nil))
    (setq counter 0)
    (repeatnum
         (setq tmplt (append tmplt (list (nth counter lst))))
         (setq counter (+ counter 1))
    )
    (setq counter (+ counter 1))
    (repeat (- (length lst) (+ num 1))
         (setq tmplt2 (append tmplt2 (list (nth counter lst))))
         (setq counter (+ counter 1))
    )
    (setq tmplt (cdr tmplt))
    (setq tmplt2 (cdr tmplt2))
    (setq lst (append tmplt (list value) tmplt2))
)
(princ)
;load cleanly

BIGAL 发表于 2022-7-5 16:26:42

下面是Afralisp的扩展数据示例,它似乎是代码的起点
,您需要更改的唯一一行是(setq thedata’(-3(“AFRALISP”(1000。“Kenny很帅”)(1000。“And intelligent”()))))),您可以添加9个值,也可以将AFRALISP更改为您希望的xata的名称。
 
如果你想要一个简单的9行dcl,我还会看一个库例程。我家里有一个,可以根据需要生成尽可能多的条目,我稍后会发布。在编写dcl时,只需要在lisp中编写几行代码。最近有一些帖子说要将多条目dcl作为库例程。
 

Another important thing to remember about Xdata is that you can have more than one of the same associative code.
Let's attach some xdata to an entity in a drawing. Draw a line then type this:
(regapp "AFRALISP")
AutoLisp should return :
"AFRALISP"
You have now registered your external entity data name. This name is a unique identifier to your own extended entity data. Next we need to get the entity data list of the entity that we want to add exdata to. Type this :
(setq oldlist (entget (car (entsel)))) ; SINGLE ENTITY
AutoLisp should return something like this :
Select object: ((-1 . <Entity name: 2100888>) (0 . "LINE") (5 . "271")
(100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbLine") (10 336.561 591.45 0.0)
(11 672.362 497.304 0.0) (210 0.0 0.0 1.0))
Now, let's create the exdata that we want to add to the entity :
(setq thedata '((-3 ("AFRALISP" (1000 . "Kenny is handsome") (1000 . "And intelligent")))))
Append it to the entity data list :
(setq newlist (append oldlist thedata))
Now, update the entity :
(entmod newlist)
We have now attached the xdata to the entity. To retrieve it we would type this :
(setq elist (entget (car (entsel)) '("AFRALISP")))
This would return the modified entity list. It should look something like this :
Select object: ((-1 . <Entity name: 2100888>) (0 . "LINE") (5 . "271")
(100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbLine") (10 336.561 591.45 0.0)
(11 672.362 497.304 0.0) (210 0.0 0.0 1.0) (-3 ("AFRALISP" (1000 . "Kenny is handsome")
(1000 . "And intelligent"))))
To retrieve the xdata we would type this :
(setq exlist (assoc -3 elist))
This gets the xdata list from the entity list.
(-3 ("AFRALISP" (1000 . "Kenny is handsome") (1000 . "And intelligent")))
To retrieve the xdata itself we would type this :
(setq thexdata (car (cdr exlist)))
Now, we should have this :
("AFRALISP" (1000 . "Kenny is handsome") (1000 . "And intelligent"))
We now have an ordinary list. Because we created the xdata list, and we know in what order we created it, it's very simple to retrieve each individual part :
(setq data1 (cdr (nth 1 thexdata)))
(setq data2 (cdr (nth 2 thexdata)))
This should return :
"Kenny is handsome"
"And intelligent"

BCL 发表于 2022-7-5 16:33:22

谢谢你,我也想看看你的图书馆日常工作-谢谢你的回复

BIGAL 发表于 2022-7-5 16:38:38

这不是多少dcl,而是一个12或3条目,它可以扩展到9,但我会做不同的,因为我已经发布了。
 

(if (not AH:getval3)(load "getvals3"))
(setq default1 "1" default2 "2" default "xx")
(ah:getval3 "Line 1" 5 4 default1 "Line2" 8 7 default2 "Line 3" 6 4 default)

 

; InputDialog box with variable title
; multiple lines of dcl input supported
; add extra lines if required by copying code defun
; By Alan H 2015
(vl-load-com)
; 1 line dcl
; sample code (ah:getval1 "Line 1" 5 4 defualt)
(defun AH:getval1 (title width limit def1 / fo fname)
; you can hard code a directory if you like for dcl file
;(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(setq fo (open (setq fname "c:\\acadtemp\\getval.dcl") "w"))
(write-line "ddgetval : dialog {" fo)
(write-line " : row {" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = "(chr 34) "key1" (chr 34) ";") fo)
(write-line(strcat " label = "(chr 34) title (chr 34) ";")   fo)
; these can be replaced with shorter value etc
(write-line (strcat "   edit_width = " (rtos width 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit 2 0) ";" ) fo)
(write-line "   is_enabled = true;" fo)
(write-line "    }" fo)
(write-line "}" fo)
(write-line "ok_only;}" fo)
(close fo)
(setq dcl_id (load_dialogfname))
; pt is a list 2 numbs -1 -1 centre ('(20 20))
;(not (new_dialog "test" dch "" *screenpoint*))
(if (not (new_dialog "ddgetval" dcl_id))
(exit))
(set_tile "key1" (setq val1 def1))
(action_tile "key1" "(setq val1 $value)")
(mode_tile "key1" 3)
(start_dialog)
(done_dialog)
(unload_dialog dcl_id)
; returns the value of val1 as a string
(vl-file-delete fname)
) ; defungetval1
; 2 line dcl
; sample code (ah:getval2 "Line 1" 5 4 default1 "Line2" 8 7 default2)
(defun AH:getval2 (title1 width1 limit1 def1 title2 width2 limit2 def2 / fo fname)
;(setq fo (open (setq fname "c:\\acadtemp\\getval.dcl") "w"))
(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(write-line "ddgetval2 : dialog {" fo)
(write-line " : column {" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key1" (chr 34) ";") fo)
(write-line(strcat " label = "(chr 34) title1 (chr 34) ";" ) fo)
(write-line (strcat "   edit_width = " (rtos width1 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit1 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key2" (chr 34) ";") fo)
(write-line (strcat " label = "(chr 34) title2 (chr 34) ";") fo)
(write-line (strcat "   edit_width = " (rtos width2 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit2 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)
; code part
(setq dcl_id (load_dialogfname))
(if (not (new_dialog "ddgetval2" dcl_id))
(exit))
(mode_tile "key1" 3)
(set_tile "key1" (setq val1 def1))
(action_tile "key1" "(setq val1 $value)")
(mode_tile "key2" 3)
(set_tile "key2" (setq val2 def2))
(action_tile "key2" "(setq val2 $value)")
(start_dialog)
(done_dialog)
(unload_dialog dcl_id)
; returns the value of val1 and val2 as strings
(vl-file-delete fname)
) ; defungetval2
; sample code (ah:getval3 "Line 1" 5 4 default1 "Line2" 8 7 default2 "Line 3" 6 4 "123")
(defun AH:getval3 (title1 width1 limit1 def1 title2 width2 limit2 def2 title3 width3 limit3 def3 / fo fname)
;(setq fo (open (setq fname "c:\\acadtemp\\getval.dcl") "w"))
(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(write-line "ddgetval3 : dialog {" fo)
(write-line " : column {" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key1" (chr 34) ";") fo)
(write-line(strcat " label = "(chr 34) title1 (chr 34) ";" ) fo)
(write-line (strcat "   edit_width = " (rtos width1 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit1 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key2" (chr 34) ";") fo)
(write-line (strcat " label = "(chr 34) title2 (chr 34) ";") fo)
(write-line (strcat "   edit_width = " (rtos width2 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit2 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key3" (chr 34) ";") fo)
(write-line (strcat " label = "(chr 34) title3 (chr 34) ";") fo)
(write-line (strcat "   edit_width = " (rtos width3 2 0) ";" ) fo)
(write-line (strcat "   edit_limit = " (rtos limit3 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)
; code part
(setq dcl_id (load_dialogfname))
(if (not (new_dialog "ddgetval3" dcl_id))
(exit))
(mode_tile "key1" 3)
(set_tile "key1" (setq val1 def1))
(action_tile "key1" "(setq val1 $value)")
(mode_tile "key2" 3)
(set_tile "key2" (setq val2 def2))
(action_tile "key2" "(setq val2 $value)")
(mode_tile "key3" 3)
(set_tile "key3" (setq val3 def3))
(action_tile "key3" "(setq val3 $value)")
(start_dialog)
(done_dialog)
(unload_dialog dcl_id)
; returns the value of val1 val2 and val3 as strings
(vl-file-delete fname)
) ; defungetval3

BCL 发表于 2022-7-5 16:48:22

谢谢,但要么我不理解你的代码(只看了大约3周的lisp)
 
这是我修改过的代码
 
(defun c:ENDT ( / )
;define function

(setvar "cmdecho" 0)
;switch off command echo

(prompt "\nSelect the Hole to Add/Modify Xdata : ")
;prompt the user

(setq e (entget (car (entsel)) '("AFRALISP")))
;get the associative code list

(setq e1 (assoc -3 e))
;get the xdata

(if (not e1)
;if there is no exdata

(progn
;do the following

(if (not (tblsearch "APPID" "AFRALISP"))
;check if the application has been registered
       
        (regapp "AFRALISP")
        ;if not, register it

);if

        (setq e1 '(( -3 ("AFRALISP"
                  (1000 . "Description")
                  (1000 . "PartNumber")
                  (1000 . "Elevation")
                  
        ))))
        ;create a default xdata list
       
        (setq e (append e e1))
        ;append to to the main list

        (entmod e)
        ;modify the entity
       
);progn

);if

(setq e2 (assoc -3 e))
;get the code -3 list

(setq e3 (car (cdr e2)))
;get the exdata list

(setq PN (cdr (nth 1 e3)))
;get the partnumber index number

(setq EV (cdr (nth 2 e3)))
;get the elevation index number

(setq DS (cdr (nth 3 e3)))
;get the description index number

(setq userclick T)
;set flag

(setq PartNumber '(" "))
;Part Number Entry       

(setq Elevation '(" "))
;Elevation Value Entry

        (setq Description '(" "))
;Description

(setq dcl_id (load_dialog "ENDT.dcl"))
;load dialogue

(if (not (new_dialog "ENDT" dcl_id)
;check for errors

      );not

   (exit)
   ;if problem exit

);if

(set_tile "PN1" PN)
;initilise list box

(set_tile "EV1" EV)
;initilise list box

(set_tile "DS1" DS)
;initilise list box

(start_list "PN1")
;start the list

(mapcar 'add_list PartNumber)
;add the partnumber

(end_list)
;end the list

(start_list "EV1")
;start the list

(mapcar 'add_list Elevation)
;add the elevation

(start_list "DS1")
;start the list

(mapcar 'add_list Description)
;add the description

(end_list)
;end the list


;I commented out this next section because its not needed but I wanted to understand it later
;will delete it at completion - basically the origional template i used had radial buttons also

; (cond
;on condition
;        ((= gr "4,6") (set_tile "rb1" "1"))
;        ;if GR 4,6 switch on radio button rb1
;
;        ((= gr "8,8") (set_tile "rb2" "1"))
;        ;if GR 8,8 switch on radio button rb2
;
;        ((= gr "HSFG") (set_tile "rb3" "1"))
;        ;if GR HSFG switch on radio button rb3
;
; );end cond

;(action_tile "rb1"
;;if radio button rb1 selected
;
;            "(setq gr \"4,6\")"
;        ;set grade of bolt
;
;);action_tile
;
;(action_tile "rb2"
;if radio button rb2 selected

;           "(setq gr \"8,8\")"
;set grade of bolt

;);action_tile

;(action_tile "rb3"
;if radio button rb3 selected

;            "(setq gr \"HSFG\")"
;set grade of bolt

; );action_tile

   (action_tile "cancel"       
   ;if cancel selected

        "(done_dialog)
;end dialog

(setq userclick nil)"
;set flag to nill

   );action_tile
   ;if cancel set flag to nil

(action_tile "accept"       

"(setq PN (get_tile \"PN1\"))

(setq EV (get_tile \"EV1\"))

(setq DS (get_tile \"DS1\"))

(done_dialog)

(setq userclick T)"
;set the flag to true

);action tile

(start_dialog)       
;start the dialogue

(unload_dialog dcl_id)       
;unload the dialogue

(if userclick       
;if OK has been selected

   (progn
   ;do the following

(setq NPN (cons 1000 PN))
;construct a new part numberlist

(setq NEV (cons 1000 EV))
       ;construct a new elevation list

(setq NDS (cons 1000 DS))
;construct a new description list

(setq e4 (chnitem NPN 2 e3))
;change the Partnumber list

(setq e5 (chnitem NEV 3 e4))
;change the elevation list

(setq e6 (chnitem NDS 4 e5))
;change the Description list

(setq e7 (subst e6 e3 e2))
;update list

(setq e8 (subst e7 e2 e))
;update list

(entmod e8)
;update the entity

    (setq PN (nth (atoi PN) PartNumber))
    ;get the Part Number from the list

   (setq EV (nth (atoi EV) Elevation))
    ;get the elevation from list
   
   (setq DS (nth (atoi DS) Description))
    ;get the Description from the list

   (alert (strcat "The Part Number is " PN "\n"
    "The Elevation is " EV "\n"
    "The Description is " DS)
    );alert


   );end progn

);end if

(princ)
;finish cleanly

);end defun


;;This function replaces any element in a list with another element
;;It requires 3 parameters (chnitem value itemnumber list)

(defun chnitem (value num lst)
    (setq num (- num 1))
    (setq tmplt (list nil))
    (setq tmplt2 (list nil))
    (setq counter 0)
    (repeatnum
         (setq tmplt (append tmplt (list (nth counter lst))))
         (setq counter (+ counter 1))
    )
    (setq counter (+ counter 1))
    (repeat (- (length lst) (+ num 1))
         (setq tmplt2 (append tmplt2 (list (nth counter lst))))
         (setq counter (+ counter 1))
    )
    (setq tmplt (cdr tmplt))
    (setq tmplt2 (cdr tmplt2))
    (setq lst (append tmplt (list value) tmplt2))
)
(
princ)
;load cleanly

 
我总是会遇到这样的“坏DXF组:(-3(“AFRALISP”(1000)(1000)(1000))”错误-我想这与我需要使用编辑框这一事实有关,其中模板使用popup\u列表?

BCL 发表于 2022-7-5 16:54:14

仍然不能完全得到我想要的-如果有人可以看看上面的代码,也许可以批评它或帮助我一点,这将是伟大的。
 
谢谢-回到绘图板,
 
布瑞恩

Grrr 发表于 2022-7-5 17:04:05

这有点混淆了您的意图,因为您在谈论Visual LISP中的项目,但实际代码使用Vanilla LISP来操作某个ename的DXF列表中的扩展数据。
还有DCL编码,这会让你更加困惑——毕竟你提到你是“业余程序员和autocad新手”。
 
那么你的意图是什么
[列表]
[*]A.使用vanilla lisp处理扩展数据(需要dxf列表操作)示例
[*]B.使用visual lisp处理扩展数据(GetXdata/SetXdata方法)示例
[*]C.将DCL与lisp结合使用-从这里开始。
[/列表]

BIGAL 发表于 2022-7-5 17:13:36

像Grr一样,你的示例dcl是3行,但你的帖子说你想要9个项目,如果你发布一个dwg,比如说一行,这9个项目是文本,或者它们是其他对象属性或混合,试着给我们一张你想要的图片,用标签手工绘制dcl。
 
你并不是在要求任何努力,对我们来说,重新开始比尝试修补你的代码更容易。
页: [1]
查看完整版本: 需要EED/扩展数据方面的帮助