RubberDinero Posted September 16, 2016 Posted September 16, 2016 (defun c:awz ( / sUndo enx atent atent_list) (setq sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'StartUndoMark)) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq atent (car (nentsel "\nSelect multiline attribute to change Defined Width to 0: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nNothing Selected.") ) ( (null atent) (prompt "\nExit.") ) ( (/= "ATTRIB" (cdr (assoc 0 (setq enx (entget atent))))) (prompt "\nSelected object is not an Attribute.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected Attribute is on a locked layer.") ) (if atent (setq atent_list (entget atent)) (setq atent_list (subst (cons 41 0) (assoc 42 atent_list) atent_list )) (entmod atent_list) )) (if sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'EndUndoMark)) )(princ) )(vl-load-com)(princ) by researching past codes from pros like Lee Mac and Grrr, i was able to create this lisp all on my own. At work we have a program that inserts Blocks with a multiline attributes with information set in them and each value is it's own line of text. Unfortunately, sometimes, by that i mean most of the time, if a space is inside the information, it'll "word wrap" and create a new line. It is very annoying having to double click the attribute, then "..." and then change the width of sometimes over 100 attributes. Out of frustration, this Code was born. I welcome everyone to criticize this code as much as they can, i like learning how others would have written it. what i added that wasn't needed, what i needed that wasn't added, what would have been an easier approach. don't hold nothing back! If i didn't give credit to some of the original creators of the code that inspired me, i apologize. you guys deserve all the credit. Quote
Roy_043 Posted September 16, 2016 Posted September 16, 2016 (edited) There are indeed some issues... The best advice I can give you is: Be more careful about indenting your code. This will help you understand the program structure better. With proper indentation you would probably have noticed the strange if statement inside your cond statement. Note that sUndo is nil throughout your program so EndUndoMark will never be invoked. (defun c:awz ( / doc enx atent) (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object)))) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq atent (car (nentsel "\nSelect multiline attribute to change Defined Width to 0: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nNothing Selected.") ) ( (null atent) (prompt "\nExit.") ) ( (/= "ATTRIB" (cdr (assoc 0 (setq enx (entget atent))))) (prompt "\nSelected object is not an Attribute.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected Attribute is on a locked layer.") ) ( T (entmod (append enx '((41 . 0.0)))) ) ) ) (vla-endundomark doc) (princ) ) (vl-load-com) (princ) Edited September 16, 2016 by Roy_043 Quote
Roy_043 Posted September 16, 2016 Posted September 16, 2016 ... Have you tried redefining the block(s)? This would obviously be more efficient. Quote
RubberDinero Posted September 16, 2016 Author Posted September 16, 2016 (defun c:awz ( / doc enx atent) (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object)))) (setvar 'errno 0) (while (/= 52 (getvar 'errno)) (setvar 'errno 0) (setq atent (car (nentsel "\nSelect multiline attribute to change Defined Width to 0: "))) (cond ( (= 7 (getvar 'errno)) (prompt "\nNothing Selected.") ) ( (null atent) (prompt "\nExit.") ) ( (/= "ATTRIB" (cdr (assoc 0 (setq enx (entget atent))))) (prompt "\nSelected object is not an Attribute.") ) ( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "layer" (cdr (assoc 8 enx))))))) (prompt "\nSelected Attribute is on a locked layer.") ) ( T (entmod (subst (cons 41 0) (assoc 41 enx) enx )) ) ) ) (vla-endundomark doc) (princ) ) (vl-load-com) (princ) It definitely looks cleaner then my version. A bit easier to understand too. Quote
RubberDinero Posted September 16, 2016 Author Posted September 16, 2016 ... Have you tried redefining the block(s)? This would obviously be more efficient. as in setting the attribute within blockeditor to a width of 0? and then running BATTMAN to sync? That should work, but it would have to be done on every new job. it is a corporate program and I will not mess with it. Quote
Roy_043 Posted September 16, 2016 Posted September 16, 2016 (edited) I have edited the code in my previous post. Gc 41 occurs twice in the entity list and my code would wrongly change the first occurrence. My initial thought was to use reverse. But then there would still be an issue if both gc 41 items have the same value. Using append instead of subst solves both problems. (subst '(41 . 0.0) '(41 . 1.0) '((41 . 1.0) (41 . 1.0))) => ((41 . 0.0) (41 . 0.0)) Edited September 16, 2016 by Roy_043 Quote
Grrr Posted September 17, 2016 Posted September 17, 2016 by researching past codes from pros like Lee Mac and Grrr, i was able to create this lisp all on my own. Thanks for the compliment! But I don't consider myself as pro nor a programmer. My current skills are due high interest about writing codes.. and learning from more skilled users (where Lee Mac and Tharwat played a big role). I highly appreciate their help, so I try to translate any 'copyrights' from my practice works to them/their nicknames. As a proof, Roy_043 mentioned a mistake from the example I posted in your previous thread: Note that sUndo is nil throughout your program so EndUndoMark will never be invoked. I know that in these forums are swimming some LISP giants, deeper in the swamp I just follow Tharwat's advice to participate in the threads as much as I can. Quote
RubberDinero Posted September 17, 2016 Author Posted September 17, 2016 My current skills are due high interest about writing codes.. and learning from more skilled users (where Lee Mac and Tharwat played a big role).I highly appreciate their help, so I try to translate any 'copyrights' from my practice works to them/their nicknames. . That is my goal. To become some-what proficient in writing code and everyone here has been very helpful. Quote
Grrr Posted September 17, 2016 Posted September 17, 2016 That is my goal. To become some-what proficient in writing code and everyone here has been very helpful. Okay... so just to have an idea with what you are currently dealing with, analyse the following (entsel) examples: [color=#8b4513]; Provided 4 examples to show the difference and complexity for prompting the user for [b][color=BLACK]([/color][/b]entsel[b][color=BLACK])[/color][/b]:[/color] [b][color=BLACK]([/color][/b]defun C:test [b][color=FUCHSIA]([/color][/b] / e e1 e2 LineEntity R [b][color=FUCHSIA])[/color][/b] [color=#8b4513]; >>> Example #1 - easy <<<:[/color] [color=#8b4513]; Many drawbacks, compare this with the below examples.[/color] [b][color=FUCHSIA]([/color][/b]setq e [b][color=NAVY]([/color][/b]entsel [color=#2f4f4f]"\nSelect an entity: "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; prompt the user to select an entity [b][color=FUCHSIA]([/color][/b]if he misses, we can't do anything with [color=#2f4f4f]"e"[/color], as we didn't wrap a loop, using [b][color=NAVY]([/color][/b]while[b][color=NAVY])[/color][/b] function[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]if e [color=#8b4513]; display the result for [color=#2f4f4f]"e"[/color][/color] [b][color=NAVY]([/color][/b]alert [color=#2f4f4f]"\nYou selected an entity!"[/color][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]alert [color=#2f4f4f]"\nNo selected entity! "[/color][b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b] [color=#8b4513]; >>> Example #2 version1 - medium <<<:[/color] [color=#8b4513]; Drawbacks: forcing the user either to select entity, or to crash te program + cannot fill requirements for a particular entity [b][color=FUCHSIA]([/color][/b]type/layer/other property[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not [b][color=MAROON]([/color][/b]setq e1 [b][color=GREEN]([/color][/b]entsel [color=#2f4f4f]"\nSelect 1st entity: "[/color][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] e1[b][color=FUCHSIA])[/color][/b][color=#8b4513]; force the user to select an entity [b][color=FUCHSIA]([/color][/b]impossible to miss one[b][color=FUCHSIA])[/color][/b] - version #1[/color] [b][color=FUCHSIA]([/color][/b]if e1 [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nThe 1st entity is selected! "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #2 version2 - medium <<<:[/color] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not e2[b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]setq e2 [b][color=MAROON]([/color][/b]entsel [color=#2f4f4f]"\nSelect 2nd entity: "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; force the user to select an entity [b][color=FUCHSIA]([/color][/b]impossible to miss one[b][color=FUCHSIA])[/color][/b] - version #2[/color] [b][color=FUCHSIA]([/color][/b]if e2 [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nThe 2nd entity is selected! "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #3 - average <<<:[/color] [color=#8b4513]; the drawback here is that if uncorrect entity is selected, the program won't print whats wrong with it [/color] [color=#8b4513]; [b][color=FUCHSIA]([/color][/b]for example user is selecting a single segment PLINE on layer [color=#2f4f4f]"0"[/color] instead of [color=#2f4f4f]"LINE"[/color] on layer [color=#2f4f4f]"0"[/color][b][color=FUCHSIA])[/color][/b][/color] [color=#8b4513]; also it forces the user to select the entity [b][color=FUCHSIA]([/color][/b]the only possible exit is to crash the program[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]while [color=#8b4513]; enclose in a loop until we have the correct entity with the correct properties[/color] [b][color=NAVY]([/color][/b]not [b][color=MAROON]([/color][/b]and [color=#8b4513]; prompt for the entity, and fill the requirements here:[/color] [b][color=GREEN]([/color][/b]setq LineEntity [b][color=BLUE]([/color][/b]car [b][color=RED]([/color][/b]entsel [color=#2f4f4f]"\nSelect a line on a layer \"[/color]0\[color=#2f4f4f]": "[/color][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]= [color=#2f4f4f]"LINE"[/color] [b][color=BLUE]([/color][/b]cdr [b][color=RED]([/color][/b]assoc 0 [b][color=PURPLE]([/color][/b]entget LineEntity[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]= [color=#2f4f4f]"0"[/color] [b][color=BLUE]([/color][/b]cdr [b][color=RED]([/color][/b]assoc 8 [b][color=PURPLE]([/color][/b]entget LineEntity[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]if [b][color=MAROON]([/color][/b]= 7 [b][color=GREEN]([/color][/b]getvar 'errno[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]princ [color=#2f4f4f]"\nNothing Selected! "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b][color=#8b4513]; if we successfuly exit the loop, we can be sure that [color=#2f4f4f]"LineEntity"[/color] is a line on a layer [color=#2f4f4f]"0"[/color][/color] [b][color=FUCHSIA]([/color][/b]if LineEntity [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nYou selected a \"[/color]LINE\[color=#2f4f4f]" entity on layer \"[/color]0\[color=#2f4f4f]" !"[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #4 - high level <<<:[/color] [color=#8b4513]; no drawbacks here.. if anythings wrong, the program informs the user, also doesn't force the user to exit the program by crashing it [b][color=FUCHSIA]([/color][/b]pressing ESC[b][color=FUCHSIA])[/color][/b]:[/color] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]/= 52 [b][color=MAROON]([/color][/b]getvar 'errno[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; this is our pseudo-loop statement[/color] [b][color=NAVY]([/color][/b]initget 128 [color=#2f4f4f]"Exit"[/color][b][color=NAVY])[/color][/b] [color=#8b4513]; allow all type of inputs [b][color=NAVY]([/color][/b]with 128 bit[b][color=NAVY])[/color][/b][/color] [b][color=NAVY]([/color][/b]setq R [b][color=MAROON]([/color][/b]entsel [color=#2f4f4f]"\nSelect Circle on layer \"[/color]0\[color=#2f4f4f]" or [Exit]: "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; prompt the user for something, and msg what is expected [b][color=NAVY]([/color][/b]R - is for [color=#2f4f4f]"Return"[/color][b][color=NAVY])[/color][/b][/color] [b][color=NAVY]([/color][/b]cond [color=#8b4513]; using conditions we analyse the [color=#2f4f4f]"Return"[/color]:[/color] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]= [b][color=BLUE]([/color][/b]getvar 'errno[b][color=BLUE])[/color][/b] 7[b][color=GREEN])[/color][/b] [color=#8b4513]; there was an error - nothing selected[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nMissed, try again! "[/color][b][color=GREEN])[/color][/b][color=#8b4513]; non-nil return, stay in loop[/color] [b][color=GREEN]([/color][/b]setvar 'errno 0[b][color=GREEN])[/color][/b] [color=#8b4513]; reset the 'errno variable[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= 'STR [b][color=RED]([/color][/b]type R[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=BLUE]([/color][/b]wcmatch R [color=#2f4f4f]"E*"[/color][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; the [color=#2f4f4f]"Return"[/color] is a string and contains [color=#2f4f4f]"E*"[/color][/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nUser has chosen to exit!"[/color][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]setq R nil[b][color=GREEN])[/color][/b][b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; exiting - set the [R]eturn to nil, and stop the loop, by setting errno to 52[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= [b][color=RED]([/color][/b]type [b][color=PURPLE]([/color][/b]car R[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b] 'ENAME[b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]/= [color=#2f4f4f]"CIRCLE"[/color] [b][color=RED]([/color][/b]cdr [b][color=PURPLE]([/color][/b]assoc 0 [b][color=TEAL]([/color][/b]entget [b][color=OLIVE]([/color][/b]car R[b][color=OLIVE])[/color][/b][b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; is ename, but not a circle[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nThis is not a circle!"[/color][b][color=GREEN])[/color][/b] [color=#8b4513]; print whats wrong[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= [b][color=RED]([/color][/b]type [b][color=PURPLE]([/color][/b]car R[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b] 'ENAME[b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]/= [color=#2f4f4f]"0"[/color] [b][color=RED]([/color][/b]cdr [b][color=PURPLE]([/color][/b]assoc 8 [b][color=TEAL]([/color][/b]entget [b][color=OLIVE]([/color][/b]car R[b][color=OLIVE])[/color][/b][b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; the above statement is true [b][color=GREEN]([/color][/b]so a circle is selected[b][color=GREEN])[/color][/b], but here the layer is wrong[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nThis circle is not on a layer \"[/color]0\[color=#2f4f4f]"!"[/color][b][color=GREEN])[/color][/b] [color=#8b4513]; print whats wrong[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]= [b][color=BLUE]([/color][/b]type [b][color=RED]([/color][/b]car R[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b] 'ENAME[b][color=GREEN])[/color][/b] [color=#8b4513]; just need to check that its an ename [b][color=GREEN]([/color][/b]the above expressions guarantee that its a circle on layer [color=#2f4f4f]"0"[/color][b][color=GREEN])[/color][/b][/color] [b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; correct entity is selected - stop the loop[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]T [color=#8b4513]; different input is provided like.. user pressed enter[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nYou pressed enter, exiting! "[/color][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]setq R nil[b][color=GREEN])[/color][/b][b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; exiting - set the [R]eturn to nil, and stop the loop[/color] [b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b][color=#8b4513]; cond[/color] [b][color=FUCHSIA])[/color][/b][color=#8b4513]; while[/color] [b][color=FUCHSIA]([/color][/b]if R [color=#8b4513]; we had exited the above loop, there were 3 possible exits, where only one doesn't set the [color=#2f4f4f]"R"[/color] to nil[/color] [b][color=NAVY]([/color][/b]progn [color=#8b4513]; do our stuff... change layer... change radius... etc.[/color] [b][color=MAROON]([/color][/b]princ [color=#2f4f4f]"\nYou have selected a circle on layer \"[/color]0\[color=#2f4f4f]" !"[/color][b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]princ[b][color=FUCHSIA])[/color][/b] [b][color=BLACK])[/color][/b][color=#8b4513]; defun[/color] The last one (#4) is the most complex - the same example you've taken from LM, which is not bad.. but considering that you are just starting learning LISP, I would suggest you to move atleast to (#3), so you won't be totally lost in the next codes you are attemptng. (I even sometimes prefer using #2 for testing purposes, and for a final program go to #3 or #4). Ofcourse there are many little details, but as a begginer, your main goal inside the code should be concentrated elsewhere, so even keeping it simple like: (if (setq ent (car (entsel "\nSelect an entity: "))) (progn ; <do suff with "ent" > ) ) No one will judge you and even the 'pro's sometimes construct and post their questions like this. As per your main question, my honest oppinion is that unless you use Mac OS, go straight practicing with Visual LISP, I mean use this to retrieve all the allowed properties for that attribute: (vlax-dump-object (vlax-ename->vla-object (car (nentsel)))) Then you will see for example the following property: ; ScaleFactor = 0.7 .. and to change it, use something like this: (vla-put-ScaleFactor (vlax-ename->vla-object (car (nentsel))) 2) This seems alot easier, isn't it? Roy's suggestion seems to solve the problem, but do you really understand how it works? - If I have to admit - I don't. Atleast when I started for the first few months I haven't done any "list manipulations", instead I did "set quote manipulations" Sorry if I criticised you, but I really do think that my post will help you alot. I also get often "criticised" about things, but critics here do nothing more than to improve you (so no room for offended users or arguing). Quote
RubberDinero Posted September 17, 2016 Author Posted September 17, 2016 Okay... so just to have an idea with what you are currently dealing with, analyse the following (entsel) examples: [color=#8b4513]; Provided 4 examples to show the difference and complexity for prompting the user for [b][color=BLACK]([/color][/b]entsel[b][color=BLACK])[/color][/b]:[/color] [b][color=BLACK]([/color][/b]defun C:test [b][color=FUCHSIA]([/color][/b] / e e1 e2 LineEntity R [b][color=FUCHSIA])[/color][/b] [color=#8b4513]; >>> Example #1 - easy <<<:[/color] [color=#8b4513]; Many drawbacks, compare this with the below examples.[/color] [b][color=FUCHSIA]([/color][/b]setq e [b][color=NAVY]([/color][/b]entsel [color=#2f4f4f]"\nSelect an entity: "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; prompt the user to select an entity [b][color=FUCHSIA]([/color][/b]if he misses, we can't do anything with [color=#2f4f4f]"e"[/color], as we didn't wrap a loop, using [b][color=NAVY]([/color][/b]while[b][color=NAVY])[/color][/b] function[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]if e [color=#8b4513]; display the result for [color=#2f4f4f]"e"[/color][/color] [b][color=NAVY]([/color][/b]alert [color=#2f4f4f]"\nYou selected an entity!"[/color][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]alert [color=#2f4f4f]"\nNo selected entity! "[/color][b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b] [color=#8b4513]; >>> Example #2 version1 - medium <<<:[/color] [color=#8b4513]; Drawbacks: forcing the user either to select entity, or to crash te program + cannot fill requirements for a particular entity [b][color=FUCHSIA]([/color][/b]type/layer/other property[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not [b][color=MAROON]([/color][/b]setq e1 [b][color=GREEN]([/color][/b]entsel [color=#2f4f4f]"\nSelect 1st entity: "[/color][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] e1[b][color=FUCHSIA])[/color][/b][color=#8b4513]; force the user to select an entity [b][color=FUCHSIA]([/color][/b]impossible to miss one[b][color=FUCHSIA])[/color][/b] - version #1[/color] [b][color=FUCHSIA]([/color][/b]if e1 [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nThe 1st entity is selected! "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #2 version2 - medium <<<:[/color] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]not e2[b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]setq e2 [b][color=MAROON]([/color][/b]entsel [color=#2f4f4f]"\nSelect 2nd entity: "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; force the user to select an entity [b][color=FUCHSIA]([/color][/b]impossible to miss one[b][color=FUCHSIA])[/color][/b] - version #2[/color] [b][color=FUCHSIA]([/color][/b]if e2 [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nThe 2nd entity is selected! "[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #3 - average <<<:[/color] [color=#8b4513]; the drawback here is that if uncorrect entity is selected, the program won't print whats wrong with it [/color] [color=#8b4513]; [b][color=FUCHSIA]([/color][/b]for example user is selecting a single segment PLINE on layer [color=#2f4f4f]"0"[/color] instead of [color=#2f4f4f]"LINE"[/color] on layer [color=#2f4f4f]"0"[/color][b][color=FUCHSIA])[/color][/b][/color] [color=#8b4513]; also it forces the user to select the entity [b][color=FUCHSIA]([/color][/b]the only possible exit is to crash the program[b][color=FUCHSIA])[/color][/b][/color] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]while [color=#8b4513]; enclose in a loop until we have the correct entity with the correct properties[/color] [b][color=NAVY]([/color][/b]not [b][color=MAROON]([/color][/b]and [color=#8b4513]; prompt for the entity, and fill the requirements here:[/color] [b][color=GREEN]([/color][/b]setq LineEntity [b][color=BLUE]([/color][/b]car [b][color=RED]([/color][/b]entsel [color=#2f4f4f]"\nSelect a line on a layer \"[/color]0\[color=#2f4f4f]": "[/color][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]= [color=#2f4f4f]"LINE"[/color] [b][color=BLUE]([/color][/b]cdr [b][color=RED]([/color][/b]assoc 0 [b][color=PURPLE]([/color][/b]entget LineEntity[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]= [color=#2f4f4f]"0"[/color] [b][color=BLUE]([/color][/b]cdr [b][color=RED]([/color][/b]assoc 8 [b][color=PURPLE]([/color][/b]entget LineEntity[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]if [b][color=MAROON]([/color][/b]= 7 [b][color=GREEN]([/color][/b]getvar 'errno[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]princ [color=#2f4f4f]"\nNothing Selected! "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b][color=#8b4513]; if we successfuly exit the loop, we can be sure that [color=#2f4f4f]"LineEntity"[/color] is a line on a layer [color=#2f4f4f]"0"[/color][/color] [b][color=FUCHSIA]([/color][/b]if LineEntity [b][color=NAVY]([/color][/b]princ [color=#2f4f4f]"\nYou selected a \"[/color]LINE\[color=#2f4f4f]" entity on layer \"[/color]0\[color=#2f4f4f]" !"[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; print to comfirm[/color] [color=#8b4513]; >>> Example #4 - high level <<<:[/color] [color=#8b4513]; no drawbacks here.. if anythings wrong, the program informs the user, also doesn't force the user to exit the program by crashing it [b][color=FUCHSIA]([/color][/b]pressing ESC[b][color=FUCHSIA])[/color][/b]:[/color] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]while [b][color=NAVY]([/color][/b]/= 52 [b][color=MAROON]([/color][/b]getvar 'errno[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; this is our pseudo-loop statement[/color] [b][color=NAVY]([/color][/b]initget 128 [color=#2f4f4f]"Exit"[/color][b][color=NAVY])[/color][/b] [color=#8b4513]; allow all type of inputs [b][color=NAVY]([/color][/b]with 128 bit[b][color=NAVY])[/color][/b][/color] [b][color=NAVY]([/color][/b]setq R [b][color=MAROON]([/color][/b]entsel [color=#2f4f4f]"\nSelect Circle on layer \"[/color]0\[color=#2f4f4f]" or [Exit]: "[/color][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; prompt the user for something, and msg what is expected [b][color=NAVY]([/color][/b]R - is for [color=#2f4f4f]"Return"[/color][b][color=NAVY])[/color][/b][/color] [b][color=NAVY]([/color][/b]cond [color=#8b4513]; using conditions we analyse the [color=#2f4f4f]"Return"[/color]:[/color] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]= [b][color=BLUE]([/color][/b]getvar 'errno[b][color=BLUE])[/color][/b] 7[b][color=GREEN])[/color][/b] [color=#8b4513]; there was an error - nothing selected[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nMissed, try again! "[/color][b][color=GREEN])[/color][/b][color=#8b4513]; non-nil return, stay in loop[/color] [b][color=GREEN]([/color][/b]setvar 'errno 0[b][color=GREEN])[/color][/b] [color=#8b4513]; reset the 'errno variable[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= 'STR [b][color=RED]([/color][/b]type R[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=BLUE]([/color][/b]wcmatch R [color=#2f4f4f]"E*"[/color][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; the [color=#2f4f4f]"Return"[/color] is a string and contains [color=#2f4f4f]"E*"[/color][/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nUser has chosen to exit!"[/color][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]setq R nil[b][color=GREEN])[/color][/b][b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; exiting - set the [R]eturn to nil, and stop the loop, by setting errno to 52[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= [b][color=RED]([/color][/b]type [b][color=PURPLE]([/color][/b]car R[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b] 'ENAME[b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]/= [color=#2f4f4f]"CIRCLE"[/color] [b][color=RED]([/color][/b]cdr [b][color=PURPLE]([/color][/b]assoc 0 [b][color=TEAL]([/color][/b]entget [b][color=OLIVE]([/color][/b]car R[b][color=OLIVE])[/color][/b][b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; is ename, but not a circle[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nThis is not a circle!"[/color][b][color=GREEN])[/color][/b] [color=#8b4513]; print whats wrong[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]and [b][color=BLUE]([/color][/b]= [b][color=RED]([/color][/b]type [b][color=PURPLE]([/color][/b]car R[b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b] 'ENAME[b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]/= [color=#2f4f4f]"0"[/color] [b][color=RED]([/color][/b]cdr [b][color=PURPLE]([/color][/b]assoc 8 [b][color=TEAL]([/color][/b]entget [b][color=OLIVE]([/color][/b]car R[b][color=OLIVE])[/color][/b][b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [color=#8b4513]; the above statement is true [b][color=GREEN]([/color][/b]so a circle is selected[b][color=GREEN])[/color][/b], but here the layer is wrong[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nThis circle is not on a layer \"[/color]0\[color=#2f4f4f]"!"[/color][b][color=GREEN])[/color][/b] [color=#8b4513]; print whats wrong[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b][b][color=GREEN]([/color][/b]= [b][color=BLUE]([/color][/b]type [b][color=RED]([/color][/b]car R[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b] 'ENAME[b][color=GREEN])[/color][/b] [color=#8b4513]; just need to check that its an ename [b][color=GREEN]([/color][/b]the above expressions guarantee that its a circle on layer [color=#2f4f4f]"0"[/color][b][color=GREEN])[/color][/b][/color] [b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; correct entity is selected - stop the loop[/color] [b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]T [color=#8b4513]; different input is provided like.. user pressed enter[/color] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nYou pressed enter, exiting! "[/color][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]setq R nil[b][color=GREEN])[/color][/b][b][color=GREEN]([/color][/b]setvar 'errno 52[b][color=GREEN])[/color][/b][color=#8b4513]; exiting - set the [R]eturn to nil, and stop the loop[/color] [b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b][color=#8b4513]; cond[/color] [b][color=FUCHSIA])[/color][/b][color=#8b4513]; while[/color] [b][color=FUCHSIA]([/color][/b]if R [color=#8b4513]; we had exited the above loop, there were 3 possible exits, where only one doesn't set the [color=#2f4f4f]"R"[/color] to nil[/color] [b][color=NAVY]([/color][/b]progn [color=#8b4513]; do our stuff... change layer... change radius... etc.[/color] [b][color=MAROON]([/color][/b]princ [color=#2f4f4f]"\nYou have selected a circle on layer \"[/color]0\[color=#2f4f4f]" !"[/color][b][color=MAROON])[/color][/b] [b][color=NAVY])[/color][/b] [b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]princ[b][color=FUCHSIA])[/color][/b] [b][color=BLACK])[/color][/b][color=#8b4513]; defun[/color] The last one (#4) is the most complex - the same example you've taken from LM, which is not bad.. but considering that you are just starting learning LISP, I would suggest you to move atleast to (#3), so you won't be totally lost in the next codes you are attemptng. (I even sometimes prefer using #2 for testing purposes, and for a final program go to #3 or #4). Ofcourse there are many little details, but as a begginer, your main goal inside the code should be concentrated elsewhere, so even keeping it simple like: (if (setq ent (car (entsel "\nSelect an entity: "))) (progn ; <do suff with "ent" > ) ) No one will judge you and even the 'pro's sometimes construct and post their questions like this. As per your main question, my honest oppinion is that unless you use Mac OS, go straight practicing with Visual LISP, I mean use this to retrieve all the allowed properties for that attribute: (vlax-dump-object (vlax-ename->vla-object (car (nentsel)))) Then you will see for example the following property: ; ScaleFactor = 0.7 .. and to change it, use something like this: (vla-put-ScaleFactor (vlax-ename->vla-object (car (nentsel))) 2) This seems alot easier, isn't it? Roy's suggestion seems to solve the problem, but do you really understand how it works? - If I have to admit - I don't. Atleast when I started for the first few months I haven't done any "list manipulations", instead I did "set quote manipulations" Sorry if I criticised you, but I really do think that my post will help you alot. I also get often "criticised" about things, but critics here do nothing more than to improve you (so no room for offended users or arguing). Thanks! I always appreciate feedback and i appreciate the examples even more! Looking forward to analyzing them! Quote
RubberDinero Posted September 30, 2022 Author Posted September 30, 2022 @Roy_043 I'm back, without any success this time... Been trying to re-write this code to allow me to do a cross select on multiple blocks that some have multiple attributes and set all found attributes defined width to zero. tried this to select multiple blocks (if (and (setq s (ssget ":L" '((0 . "INSERT"))))) and then a (foreach e but since I don't know the process of extracting a list of ATTRIB to then manipulate, I came back for help. I tried for about 2 hours and AutoCAD would load my lisp, but it just wouldn't do anything. This is my code and I know why it doesn't work, I just don't know the solution to modifying the defined width of multiple attributes for multiple blocks. (defun c:test ( / sUndo enx atent atent_list) (if (and (setq s (ssget ":L" '((0 . "INSERT"))))) (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))) (setq sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'StartUndoMark)) (setvar 'errno 0) (while (setq atent (car (nentsel e))) (setq atent_list (entget atent)) (setq atent_list (subst (cons 41 0) (assoc 42 atent_list) atent_list )) (entmod atent_list) (if sUndo (vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'EndUndoMark)) )))(princ) )(vl-load-com)(princ) The original code has been working great, but I'm always looking for the next improvement. Thanks ahead of time and thanks to the entire community! Quote
BIGAL Posted October 1, 2022 Posted October 1, 2022 1st can add in the ssget filter does block have attributes. (ssget '(( 0 . "INSERT")(66 . 1))) Using VL makes getting at attributes easier. Some sample code (setq ss (ssget '(( 0 . "INSERT")(66 . 1)))) (repeat (setq x (sslength ss)) (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)) )) 'getattributes) (princ (strcat "\n" (setq str (vla-get-textstring att)))) ; do your thing here ) ) Quote
RubberDinero Posted October 1, 2022 Author Posted October 1, 2022 @BIGALI was not able to figure it out, but here is my new code and notes on the right of each step so you can see my thought process. I'm missing a step or two because I'm getting an error. How far off am I? (defun c:test ( / ss str att x atent atent_list) (setq ss (ssget '(( 0 . "INSERT")(66 . 1)))) ;pick only blocks with attributes (repeat (setq x (sslength ss)) ;x is equal to the quantity of blocks with attributes selected (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)) )) 'getattributes) ;for each block, get attributes, 1-x for next iteration? (setq atent_list (entget att)) ;set atent_list as the current iterations of foreach (setq atent_list (subst (cons 41 0) (assoc 42 atent_list) atent_list )) ;set the defined width to zero (entmod atent_list) ;modify entity ) ) (princ) )(vl-load-com)(princ) I get this error "(ENTGET #<VLA-OBJECT IAcadAttributeReference 000000dfc9d09c08>)" Quote
mhupp Posted October 1, 2022 Posted October 1, 2022 (edited) You cant use entget with vla-object. basically what this is saying. (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)))) 'getattributes) for this block get the vla-object of each attribute. (vla-get-textstring att) get the text of that attribute i don't know what 41 and 42 are but this might b e what your looking for. (defun c:test (/ ss att x ent) (vl-load-com) (setq ss (ssget '((0 . "INSERT") (66 . 1)))) (repeat (setq x (sslength ss)) (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)))) 'getattributes) ;(setq str (vla-get-textstring att)) ;could test for wordwarp here and edit the string instead of entmod 41 (setq ent (entget (vlax-vla-object->ename att))) ;get entname of attribute (setq ent (subst (cons 41 0) (assoc 41 ent) ent)) ;entmod attribute to have 0 width (setq ent (subst (cons 42 0) (assoc 42 ent) ent)) (entmod ent) ) ) (princ) ) Edited October 2, 2022 by mhupp Quote
RubberDinero Posted October 1, 2022 Author Posted October 1, 2022 @mhupp tried this, but I’m either getting a “too few arguments” error or the same VLA error depending on what kind of changes I make. looks like I need to figure out a way to make it full DXF or full VL. I could upload a sample of the block, but it’s just 1 block with 2 multiline attributes and another block with 1 multiline attribute. every time they get inserted they have a defined width not equal to zero. would like a cross select all of those blocks and make the defined width of all attributes to zero. Quote
mhupp Posted October 1, 2022 Posted October 1, 2022 sorry went back and read what you posted back in 2016. update the code. Quote
RubberDinero Posted October 2, 2022 Author Posted October 2, 2022 @mhupp it worked perfect after changing the cons and assoc as followed (cons 41 0) (assoc 42 ent) your code changed the text width but not the define width to zero. now it's perfect!!! I know a bit of Python and know how iterations work, so I'll have to brush up on how this following code works (ssname SS (setq x (1- x))) Thanks for your help, I don't think I could have figured this one out all by myself! Quote
BIGAL Posted October 2, 2022 Posted October 2, 2022 (edited) You can dump the properties of the attributes I am not finding width as a setting but that is probably the blocks I am choosing. I manually did the ssget line, then did the others. (setq ss (ssget '((0 . "INSERT")(66 . 1)))) (setq atts (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)))) 'getattributes)) (vlax-dump-object (nth 0 atts)) "defined width to zero" can you post a sample dwg. Have a look at this using entnext example. https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/edit-attribute-value-with-lisp/td-p/6927162 Edited October 2, 2022 by BIGAL Quote
RubberDinero Posted October 2, 2022 Author Posted October 2, 2022 @BIGALMText has a defined width before it starts to word-wrap to the next line. it can be stretched in edit mode(also stretched to zero), both in MText attributes and in mtext. To avoid word-wrapping, the defined width can be set to zero and word-wrap will only happen on Enter. On MText it's easier because I believe the defined width property, if dynamic columns are turned off, can be found in the property menu, but not so for MText within attributes. Not sure if has a more proper name, "Defined Width" is what it is under in properties. Quote
BIGAL Posted October 2, 2022 Posted October 2, 2022 I think its called Scalefactor (vla-put-scalefactor (car atts) 1) need your dwg to check. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.