PDA

View Full Version : cycle through an entity with multiple dxf codes



ccowgill
2007-05-23, 06:41 PM
I dont know how best to title this, but I want to know how to cycle through an entity that has multiple parts and duplicate dxf codes, for example, I want to search a table for a dxf code 1 whose second part is a wild card match of "{*" , then modify the text and replace it in the table.
Or filter out all the vertex points in a polyline to create a list of vertexes.

tyshofner
2007-05-23, 11:42 PM
Two Examples

First collects polyline vertices:



(setq ent (entget (car (entsel))))
(setq vertex_lst (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) ent)))


Second will parse through the entity list looking for dxf code 1, then run the wcmatch and execute code if needed:



(setq ent (entget (car (entsel))))
(foreach dp ent
(if (= (car dp) 1)
(if (= (wcmatch (cdr dp) "{*") T)
(progn
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
)
)
)
)


Ty :mrgreen:

ccowgill
2007-05-24, 11:16 AM
so if I wanted to replace the contents of the dxf code, I would use the following?



(progn
(setq leftside (vla- "{`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ|0123456789" (cdr dp)))
leftside2 (vla ";" leftside)
rightside (vla "}" leftside2)
)
(setq Ent (subst (cons 1 rightside) dp Ent))
(entmod Ent)
);end progn

tyshofner
2007-05-24, 02:07 PM
Yes, the "subst" & "entmod" functions will replace the string. I'm assuming that the "vla" function you have in your code is a user sub-routine if this is correct than yes this should work. One thing I will point out:

Although "entmod" modifies the entity list, you still need to "update" the entity grachically. To do this you must use "entupd". You could just regen at the end of the routine, but why have acad redraw everything when you can have it just do the one entity. See below:



(progn
(setq leftside (vla- "{`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ|0123456789" (cdr dp)))
leftside2 (vla ";" leftside)
rightside (vla "}" leftside2)
)
(setq Ent (subst (cons 1 rightside) dp Ent))
(entmod Ent)
(entupd (cdr (assoc -1 Ent)))
);end progn


Ty :mrgreen:

ccowgill
2007-05-24, 02:26 PM
sorry, vla was supposed to be vl-string-left-trim, I couldnt remember the proper function at the time, so it was just a place holder I think I have my program running now, I will post it as soon as I have done more testing. When it is done, people will be able to use it to strip a table back to default formatting.

ccowgill
2007-05-24, 02:38 PM
feel free to modify it, it is probably pretty crude by programming standards, maybe someone could help me clean it up. all it does right now is just convert the text style back to the table's text style.

Thanks for your help Ty



(defun c:striptable
(/ BlName EntName EntDxf dp leftside leftside2 rightside)
(setq BlName (ssget '((0 . "ACAD_TABLE")))
EntName (ssname BlName 0)
EntDxf (entget Entname)
) ;_ end of setq
(foreach dp EntDxf
(if (= (car dp) 1)
(if (= (wcmatch (cdr dp) "`{*") T)
(progn
(setq leftside (vl-string-left-trim
"{\\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ|0123456789 "
(cdr dp)
) ;_ end of vl-string-left-trim
leftside2 (vl-string-left-trim ";" leftside)
rightside (vl-string-right-trim "}" leftside2)
) ;_ end of setq
(setq EntDxf (subst (cons 1 rightside) dp EntDxf))
(entmod EntDxf)
(entupd (cdr (assoc -1 EntDxf)))
) ;end progn
) ;end if
) ;end if
(if (= (car dp) 302)
(if (= (wcmatch (cdr dp) "`{*") T)
(progn
(setq leftside (vl-string-left-trim
"{\\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ|0123456789 "
(cdr dp)
) ;_ end of vl-string-left-trim
leftside2 (vl-string-left-trim ";" leftside)
rightside (vl-string-right-trim "}" leftside2)
) ;_ end of setq
(setq EntDxf (subst (cons 302 rightside) dp EntDxf))
(entmod EntDxf)
(entupd (cdr (assoc -1 EntDxf)))
) ;end progn
) ;end if
) ;end if
) ;end foreach
(princ)
) ;_ end of defun

nelson
2008-10-31, 08:13 PM
This does exactly what it says, but I have one problem. If you have a datalinked table, it strips the link out to the table.

irneb
2008-11-04, 05:06 AM
Maybe if you use the vla functions to edit the contents of the table instead of entmod, it won't break the datalink. E.g.
(setq EntObj (vlax-ename->vla-object EntName))
(setq ColCount (vla-get-Columns EntObj)) ; Gets the number of columns
(setq RowCount (vla-get-Rows EntObj)) ; Gets the number of rows
(vla-GetCellValue EntObj 2 5) ;Gets value of 2nd row 5th column
(vla-SetCellValue EntObj 6 10 NewVal) ;Sets the cell in 6th row 10th column to the string contained in NewVal
Just a thought though ... if you're changing a value inside a table linked to attributes / excel - wouldn't that in itself break the link?

nelson
2008-11-21, 03:31 PM
First, I think that I need to think about how I used this. I'm pretty new to working with code, so I don't think that I understood what this did. :Oops:

What I did was use this on an Autocad Table to reset the font styles to an Autocad font, and this table was datalinked back to excel. Does that make sense? Excel used a TTF font like Arial, and Autocad has a curent style of simplex.shx. So what I thought this would do is strip the table back to the Autocad Table style, which it did, but then stripped the link away from the table.
I'm reading this whole post again, and lookin at the OP, this has nothing do do with a "Table" but more of the internal code of Autocad's table of entities. Right?

But it worked all the same, but lost the datalink.

So irneb, are you telling me that you see a way to strip the Autocad Table back to a table style, and not lose the datalink?

If what I'm doing, (second paragraph), is not what this code is for, someone let me know and I'll know that I'm going down the wrong track for my problem. I don't want to cause confusion, and get unrelated code put in this post.

ccowgill
2008-11-21, 04:22 PM
My original post was formatted generally so I could hopefully apply the knowledge I gained to more than one application. But then I posted the table strip command, because that is what I was working on, and why I needed the information. Kind of like, here is how I used this knowledge I obtained from you. If you could post the entdata for a linked table, I could possibly help modify the strip command so it will only strip formatting, not a link. Use this command, select the object, copy the command line content and paste it back here.


(defun select (/ object objent objentdata)
(setq object (ssget)
objent (ssname object 0)
objentdata (entget objent)
) ;_ end of setq
) ;_ end of defun

to call the above command use: (select)

irneb
2008-11-24, 05:42 AM
I'm actually unsure of why you want to do this through Lisp. It's already an option with standard ACad. Notice on the right of the status bar ... after you've pasted a link from excel (attachments 1 & 2) ... you'll see an icon with something looking like 2 links of a chain. Right-clicking on this brings up 2 options "Data Links ..." and "Update All Data Links ...". The 1st opens the Data Link Manager (3rd attachment). Right-click on the Excel Link displayed brings up the Modify Excel Link dialog. One of the options (if you open the dialog further by clicking the (>) button lower right) is "Use Excel formatting" (4th attachment). If you turn this off, the default Table Style's formatting is used and you don't break the link. Play around with the other options for different formatting.

The problem with modifying the code is that ACad uses several "entities" to create that link through to Excel. The Table entity is only the displayed portion. There's several "Dictionary" entities involved as well. The above scenario actually changes one of these - it doesn't really touch the Table entity.

It does become a bit confusing with Table / Table (especially when you bring into account that Excel also hast "Tables" - see 1st attachment). In ACad the "Table" was orriginally a gourping mechanism for the non-graphical entities defining stuff like Dimstyles, Layers, Text Styles, etc. The Graphical Table entity only came into the code after that. Generally AutoDesk tends to use "Dictionary" groupings these days for new non-graphic entities. E.g. the Dimstyle is still kept as a (tblnext "DIMSTYLE" t) entity, while the new MLEADER style is saved in the DWG as a Dictionary element. This is probably done in an effort to get around the confusion ... but then Dictionaries are VERY CONFUSING in themselves.

ccowgill
2009-04-06, 05:37 PM
Two Examples

First collects polyline vertices:



(setq ent (entget (car (entsel))))
(setq vertex_lst (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) ent)))
Second will parse through the entity list looking for dxf code 1, then run the wcmatch and execute code if needed:



(setq ent (entget (car (entsel))))
(foreach dp ent
(if (= (car dp) 1)
(if (= (wcmatch (cdr dp) "{*") T)
(progn
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
)
)
)
)
Ty :mrgreen:

I know its been a while, but I still dont understand what I'm doing.
Multileader Entget:


((-1 . <Entity name: 7ffff86b580>) (0 . "MULTILEADER") (5 . "2590") (102 .
"{ACAD_XDICTIONARY") (360 . <Entity name: 7ffff86b590>) (102 . "}") (102 .
"{ACAD_REACTORS") (330 . <Entity name: 7ffff86b5a0>) (102 . "}") (330 . <Entity
name: 7ffff871950>) (100 . "AcDbEntity") (67 . 1) (410 . "09-004-06") (8 .
"Dim") (100 . "AcDbMLeader") (300 . "CONTEXT_DATA{") (40 . 1.0) (10 19.8771
10.5996 0.0) (41 . 0.08) (140 . 0.15) (145 . 0.04) (174 . 6) (175 . 1) (176 .
0) (177 . 0) (290 . 1) (304 . "ST-11, DR STRUCTURE, 48 INCH DIA, COVER B\\PRIM
778.76\\PINV. 774.93 - 12\" NE & SW\\PINV. 772.60 - 12\" NW") (11 0.0 0.0 1.0)
(340 . <Entity name: 7ffff8751d0>) (12 19.9171 10.6956 0.0) (13 1.0 0.0 0.0)
(42 . 0.0) (43 . 0.0) (44 . 0.0) (45 . 1.0) (170 . 2) (90 . -1073741824) (171 .
1) (172 . 5) (91 . -1073741824) (141 . 0.0) (92 . 11972840) (291 . 0) (292 . 0)
(173 . 0) (293 . 0) (142 . 0.0) (143 . 0.0) (294 . 0) (295 . 0) (296 . 0) (110
17.3683 15.0226 0.0) (111 1.0 0.0 0.0) (112 0.0 1.0 0.0) (297 . 0) (302 .
"LEADER{") (290 . 1) (291 . 1) (10 16.8494 10.5996 0.0) (11 1.0 0.0 0.0) (90 .
0) (40 . 3.02773) (304 . "LEADER_LINE{") (10 17.3683 15.0226 0.0) (10 16.8494
14.5036 0.0) (91 . 0) (305 . "}") (303 . "}") (301 . "}") (340 . <Entity name:
7ffff877b60>) (90 . 267456) (170 . 1) (91 . -1023410171) (341 . <Entity name:
7ffff871920>) (171 . -2) (290 . 1) (291 . 1) (41 . 3.02773) (42 . 0.15) (172 .
2) (343 . <Entity name: 7ffff8751d0>) (173 . 6) (95 . 1) (174 . 1) (175 . 0)
(92 . -1073741824) (292 . 0) (93 . -1056964608) (10 1.0 1.0 1.0) (43 . 0.0)
(176 . 0) (293 . 0) (294 . 0) (178 . 0) (179 . 1) (45 . 1.0))

If I wanted to use this on a multileader to collect information about the leader I would use the following?

(setq ent (entget (car (entsel))))
(setq vertex_lst (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 302)) ent)))
Then I could use


(setq ent (entget (car (entsel))))
(foreach dp ent
(if (= (car dp) 10)
(if (= (wcmatch (cdr dp) "{*") T)
(progn
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
;***YOUR CODE HERE**;
)
)
)
)

to modify the 10 item, or collect the information from the 10 item?

RobertB
2009-04-06, 06:07 PM
You know you need the first DWF group code 10 after the leader definition, so it should be as simple as:

(cdr (assoc 10 (member '(302 . "LEADER{") ent)))

ccowgill
2009-04-06, 06:40 PM
You know you need the first DWF group code 10 after the leader definition, so it should be as simple as:

(cdr (assoc 10 (member '(302 . "LEADER{") ent)))
Hit the nail on the head. Thats what I needed, thanks.