TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Binky on March 26, 2008, 04:39:52 PM

Title: Acad2008 and nentsel
Post by: Binky on March 26, 2008, 04:39:52 PM
I have several routines that use nentsel and work just fine in 2007, however not in 2008.  It does not crash the routine just does not return the selected attribute but the block instead.

Anybody else run into this????

Thanks
Title: Re: Acad2008 and nentsel
Post by: Keith™ on March 26, 2008, 04:58:07 PM
There are lots of bugs with AutoCAD 2008 and attributes.

Several have been exposed right here at the swamp.
Title: Re: Acad2008 and nentsel
Post by: Guest on March 26, 2008, 05:01:26 PM
Can you post a snippet of your code?  Maybe it's not 2008.  Maybe..... um.... yeah..... maybe.
Title: Re: Acad2008 and nentsel
Post by: Binky on March 26, 2008, 05:10:10 PM
Here is one that we use to change the color of attributes in panel schedules so that existing loads print lighter.

works fine in 2007.  wrote it about a year ago.

Code: [Select]
;;;;;;
;
; Swaps color of object between 'bylayer' and specified color
; exclr: specified color to use for existing
; ename: selected entity name
; ent: dxf info of selected entitiy
; sog: 'Stop or GO' flag for loop
; x: junk place holder
;
;;;;;;


(defun c:toggle (/ ename ent exclr sog x)
 
  (setq sog 1
        exclr (getint "\nColor number of existing <Enter for dialog>: "))
  (if (not exclr)
    (setq exclr (acad_colordlg 9)));sets existing color via dialog
  (setvar "errno" 0)

  (while (= sog 1)
    (setq ename (car (nentsel "\nSelect Item: ")))
    (if (/= (setq x (getvar "errno")) 0);set x to error number if not 0
      (cond ;true
        ((= x 7)(princ "Missed"));back to top
        ((= x 52)(setq sog 0));kills loop
      );ends condition
    (progn ;false
      (setq ent (entget ename));grabs dxf info
      (if (not (assoc 62 ent));checks for lack of color entry
        (setq ent (append (list (cons 62 exclr)) ent));true adds color entry
        (if (equal (cdr (assoc 62 ent)) exclr);false;if already set to existing
          (setq ent (subst (cons 62 256) (assoc 62 ent) ent));true;set to bylayer
          (setq ent (subst (cons 62 exclr) (assoc 62 ent) ent));false;set to existing
        );end if
      );end if
      (entmod ent);writes modifacations
      (entupd ename);updates entity on screen
    );end progn
    );end if
    (setvar "errno" 0);resets error number
  );end while
  (princ "\nThank You")
  (princ)
);end function

[code]
[/code]
Title: Re: Acad2008 and nentsel
Post by: Crank on March 26, 2008, 05:38:02 PM
I'm sorry to tell you this: You can't use (entmod) on annotative objects. Even if you only try to change te color the objects change of scale. So if you're on 2k8 or 2k9 I suggest you start using activex.
Title: Re: Acad2008 and nentsel
Post by: CAB on March 26, 2008, 05:41:06 PM
Are you sure it is the nentsel that is causing an error?
I don't have 2008 to test but the reason I ask is there have been cases in the past where adding
a DXF pair to the end of the entity list caused problems for me. I can't remember the specifics as it
was too long ago.

So I'm suspect of this line of code:
(setq ent (append (list (cons 62 exclr)) ent));true adds color entry
Title: Re: Acad2008 and nentsel
Post by: Binky on March 26, 2008, 06:07:48 PM
Are you sure it is the nentsel that is causing an error?
No, just assumed since the routine works on the text used for the description of the load

So I'm suspect of this line of code:
(setq ent (append (list (cons 62 exclr)) ent));true adds color entry
By default code 62 is omitted if the color is 'bylayer' when the object is created so to change it you have no choice but to add.

I'm sorry to tell you this: You can't use (entmod) on annotative objects. Even if you only try to change te color the objects change of scale. So if you're on 2k8 or 2k9 I suggest you start using activex.
Is this a bug in 2008 or a deliberate change in autocad.  I just checked the Autolisp Reference from both 2007 and 2008 and they read the same with the same restrictions. It works on 2007(not to harp on that point, i just have not gotten out of my system yet)
Title: Re: Acad2008 and nentsel
Post by: Binky on March 26, 2008, 06:17:16 PM
I'm sorry to tell you this: You can't use (entmod) on annotative objects. Even if you only try to change te color the objects change of scale. So if you're on 2k8 or 2k9 I suggest you start using activex.

That got me thinking and digging into the help files a bit more and ran into this

"The entmod function can modify subentities such as polyline vertices and block attributes."

in the following help section
 AutoLISP Developer's Guide > Using the AutoLISP Language > Using AutoLISP to Manipulate AutoCAD Objects > Object Handling > Entity Data Functions >
Modifying an Entity

Title: Re: Acad2008 and nentsel
Post by: CAB on March 26, 2008, 09:24:57 PM
So I'm suspect of this line of code:
(setq ent (append (list (cons 62 exclr)) ent));true adds color entry
By default code 62 is omitted if the color is 'bylayer' when the object is created so to change it you have no choice but to add.

What I mean is that if you place it LAST in the entity list it may not fly. You would need to place it near where you would normally find it in the list.
This is just a guess on my part.
Title: Re: Acad2008 and nentsel
Post by: CAB on March 26, 2008, 09:45:34 PM
Try something like this which inserts the DXF pair after the layer (8 . lname)

Code: [Select]
(defun insertDXF (ent pair / pair2 el2)
  (setq elst (entget ent))
  (while (and (setq pair2 (car elst))
              (setq el2 (cons pair2 el2))
              (if (/= (car pair2) 8)
                (setq elst (cdr elst))  ; stay in loop
                (not (setq el2  (cons pair el2)
                           elst (cdr elst)
                     )
                )                       ; exit loop
              )
         )
  )
  (while (setq pair2 (car elst))
    (setq el2 (cons pair2 el2))
    (setq elst (cdr elst))
  )
  (reverse el2)
)


(defun c:test(/ ent)
  (setq ent (car (entsel)))
  (princ (entmod (insertDXF ent '(62 . 4))))
  (princ)
)
Title: Re: Acad2008 and nentsel
Post by: Keith™ on March 27, 2008, 12:15:32 AM
preliminary tests reveal that appending a color to the end of a list does modify the color in all versions of AutoCAD prior to R2008, however in R2008, the behavior has changed.

If the color is placed in the proper location after the layer name, the color is properly applied ... at least it is in my tests.

However, this does not apply to regular entities, nor does it apply to subentities selected by nentsel.

Once again this only applies to attributes.
Title: Re: Acad2008 and nentsel
Post by: Crank on March 27, 2008, 08:20:50 AM
[...]
Is this a bug in 2008 or a deliberate change in autocad.  I just checked the Autolisp Reference from both 2007 and 2008 and they read the same with the same restrictions. It works on 2007(not to harp on that point, i just have not gotten out of my system yet)
This is a serious bug that I've reported for Acad2008 and 2009.

Since 2k8 you can't use (entmod) anymore on text/attributes if they are annotative. Because we using annotative scaling for everything, I had to rewrite a lot of code to fix this.

In the express tools they've changed some code, but there are some lisp files that are affected with this bug (tcase.lsp for instance).
Title: Re: Acad2008 and nentsel
Post by: Keith™ on March 27, 2008, 09:20:47 AM
Since 2k8 you can't use (entmod) anymore on text/attributes if they are annotative

I have had problems with attributes even if they are not annotative
Title: Re: Acad2008 and nentsel
Post by: CAB on March 27, 2008, 09:45:58 AM
So Blinky here is a new version to try.
Code: [Select]
;;;;;;
;
; Swaps color of object between 'bylayer' and specified color
; exclr: specified color to use for existing
; ename: selected entity name
; ent: dxf info of selected entitiy
; sog: 'Stop or GO' flag for loop
; x: junk place holder
; 03.28.2008 revised by CAB
;;;;;;


(defun c:toggle (/ ename obj exclr x)
  (vl-load-com)
  (setq exclr (getint "\nColor number of existing <Enter for dialog>: "))
  (or exclr (setq exclr (acad_colordlg 9))) ; sets existing color via dialog
  (while
    (cond
      ((null exclr)(prompt "\nUser Quit."))
      ((null (setvar "errno" 0))); resets error number
      ((setq ename (car (nentsel "\nSelect Item: ")))
        (setq obj (vlax-ename->vla-object ename)); grabs dxf info
        (vla-put-color obj exclr)
        (vla-Regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)
        t
      )
      ((= (setq x (getvar "errno")) 7)(princ "Missed")); back to top
      ((= x 52) nil); ENTER KEY kills loop
      (t (princ "Unknown Error, Try again"))
    )
  )
  (princ "\nThank You")
  (princ)
);end function
Title: Re: Acad2008 and nentsel
Post by: Binky on March 27, 2008, 12:40:15 PM
CAB,

That works, thanks.  I needed to add (vl-load-com).  If I could ask though.....

How is that 'or' statement working?  you have

 (or exclr (setq exclr (acad_colordlg 9)))

It seems to work just like

(if (not exclr) (setq exclr (acad_colordlg 9)))

My reading of the 'or' led me to believe that it evaluates all of the expressions, so I would have assumed that regardless of the state of exclr it would still want to put up the color selection dialog.  It doesn't and I must confess to being confused.

It never would have occurred to me to use a 'cond' and the test expression for a 'while' loop.  Reading it, I get the impression that it should continue to ask for more objects to change until the user presses 'Enter', which is how the previous routine worked.  It ends after only changing 1 object though and again I am confused as to why.

Thank you and everybody for your time.  I am off to a couple meetings so perhaps I can get back to this later today.

Title: Re: Acad2008 and nentsel
Post by: CAB on March 28, 2008, 08:49:45 AM
Binky,
I fixed the code above so copy it again, thanks.
  Added (vl-load-com), I have this in my ACADdoc.lsp so I sometimes forget to add it to sample code
  fixed the repeat problem, added True to the end of the condition
 
As for the OR, here is an excerpt from this thread:
http://www.theswamp.org/index.php?topic=13046.msg158557#msg158557

The  OR will process each line as long as they are false, it will quit when true is returned
Code: [Select]
(or (a. is true) ; stop here
    (b. does not get this far)
)
Code: [Select]
(or (a. is false) ; keep going
    (b. do this & if false keep going)
    (c. do this if b was false)
)

So this will work as well with a variable with a value or nil
Code: [Select]
(setq var "Some Text")
(or  var ; Stop here if the var has a value, if nil then keep going
     (setq var "Some Text")
)

You can use IF or OR in the situation but I prefer OR as the VLIDE format keeps it in one line.
This is just a personal preference.

Read the thread, link posted, about WHILE and COND.
If you still have questions I'll be glad to try and answer them.
Title: Re: Acad2008 and nentsel
Post by: Binky on March 31, 2008, 01:58:01 PM
CAB, Thanks for the explanation, that helps and will be put to use in the future as well.

Here is the final version.  I added a 'if' statement so that if the user picked something that they shouldn't have they can correct it without having to restart the command.

Code: [Select]
;;;;;;
;
; Swaps color of object between 'bylayer' and specified color
; exclr: specified color to use for existing
; ename: selected entity name
; obj: ename converted to a vba object
; x: junk place holder
; 03.28.2008 revised by CAB(via the Swamp)
;;;;;;


(defun c:toggle (/ ename obj exclr x)
(vl-load-com)
  (setq exclr (getint "\nColor number of existing <Enter for dialog>: "))
  (or exclr (setq exclr (acad_colordlg 9))) ; sets existing color via dialog
  (while
    (cond
      ((null exclr)(prompt "\nUser Quit."))
      ((null (setvar "errno" 0))); resets error number
      ((setq ename (car (nentsel "\nSelect Item: ")))
        (setq obj (vlax-ename->vla-object ename)); converts object to vba
(if (assoc 62 (entget ename))
(vla-put-color obj 256)
(vla-put-color obj exclr))
        (vla-Regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)
t)
      ((= (setq x (getvar "errno")) 7)(princ "Missed")); back to top
      ((= (setq x (getvar "errno")) 52) nil); ENTER KEY kills loop
      (t (princ "Unknown Error, Try again"))
    )
  )
  (princ "\nThank You")
  (princ)
);end_defun
Title: Re: Acad2008 and nentsel
Post by: CAB on March 31, 2008, 03:29:39 PM
You're welcome.

And for the IF I would use this.
Code: [Select]
       (if (= (vla-get-color obj) 256)
         (vla-put-color obj exclr)
         (vla-put-color obj 256)
       )