Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Collaborator
526 Posts
10 Kudos
21 Solutions
Post 1 of 6
Accepted Solution

Selecting objects by Linetype, If statment

825 Views, 5 Replies
03-19-2013 09:19 AM

Ok....I have created this "simple" routine to help clean up legacy blosks to meet new company standards.

 

It selectect objects by linetype and changes them to the correct layer, color and linetype settings.

It appears that if the linetype is not in the file I get crazy results. This is the fourth version after reading through some post on the discussion group. Am I over looking something simple?

 

I have attache the code and ample dwg.

 

All suggestions welcome and appreciated!

 

Thanks

 

Here is the code:

;
;This programs cleans up an existing legacy block by:
;    Changing hidden linetype lines to layer 0
;   Changing continuous linetype lines to layer 0
;   Changing bylayer linetype lines to layer 0
;   changes color to byblock
;   changes continuous and bylayer linetypes to byblock.
;This sets up blocks to be used with any color, linetype, on any layer for our company standards.
;
(DEFUN C:blkcln ()
(setvar "cmdecho" 1)
   (setq olderr *error*
         *error* CHGTERR)
  (if (tblsearch "ltype" "hidden")
                (progn
    (command "._chprop" (ssget "X" '((6 . "HIDDEN"))) "" "C" "byblock" "LT" "hidden" "la" "0" "")
   );end progn
  );end if
;
  (if (tblsearch "ltype" "continuous")
                (progn
    (command "._chprop" (ssget "X" '((6 . "continuous"))) "" "C" "byblock" "LT" "continuous" "la" "0" "")
    );end progn
  );end if
;
  (if (tblsearch "ltype" "ByLayer")
   (progn
    (command "._chprop" (ssget "X" '((6 . "ByLayer"))) "" "C" "byblock" "LT" "ByLayer" "la" "0" "")
   );end progn
  );end if
;
(COMMAND "-PURGE" "ALL" "" "N")
(COMMAND "REGEN")
;
);END DEFUN

 

 

Here is the Crazy Error I get:

Command: BLKCLN ._change Select objects:   5 found

Select objects: Specify change point or [Properties]: P Enter property to change [Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: C New color [Truecolor/COlorbook] <BYLAYER>: byblock Enter property to change [Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: LT Enter new linetype name <HIDDEN>: hidden Enter property to change [Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: la Enter new layer name <ALCO>: 0 Enter property to change [Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: Command: ._chprop Select objects:   5 found

Select objects: Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: C New color [Truecolor/COlorbook] <BYBLOCK>: byblock Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: LT Enter new linetype name <HIDDEN>: hidden Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: la Enter new layer name <0>: 0 Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: Command: ._chprop Select objects: Command: BLKCLN Unknown command "BLKCLN".  Press F1 for help.

Command: C Unknown command "C".  Press F1 for help.

Command: byblock Unknown command "BYBLOCK".  Press F1 for help.

Command: LT Unknown command "LT".  Press F1 for help.

Command: continuous Unknown command "CONTINUOUS".  Press F1 for help.

Command: la Unknown command "LA".  Press F1 for help.

Command: 0 Unknown command "0".  Press F1 for help.

Command: BLKCLN Unknown command "BLKCLN".  Press F1 for help.

Command: ._chprop Select objects:   51 found

Select objects: Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: C New color [Truecolor/COlorbook] <BYLAYER>: byblock Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: LT Enter new linetype name <ByLayer>: ByLayer Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: la Enter new layer name <ALCO>: 0 Enter property to change [Color/LAyer/LType/ltScale/LWeight/Thickness/Material/Annotative]: Command: -PURGE Enter type of unused objects to purge [Blocks/Dimstyles/LAyers/LTypes/MAterials/Plotstyles/SHapes/textSTyles/Mlinestyl es/Tablestyles/Visualstyles/Regapps/All]: ALL Enter name(s) to purge <*>: Verify each name to be purged? [Yes/No] <Y>: N No unreferenced blocks found.

No unreferenced layers found.

No unreferenced linetypes found.

No unreferenced text styles found.

No unreferenced shape files found.

No unreferenced dimension styles found.

No unreferenced mlinestyles found.

No unreferenced plotstyles found.

No unreferenced table styles found.

No unreferenced materials found.

No unreferenced visual styles found.

Command: REGEN Regenerating model.

Command: nil

 

If this response answers your question, Please mark this response as "Accept as Solution"

Rocky Brown
AutoCAD 2015 / Inventor 2015

That's probably a result of (ssget) not finding anything with a particular linetype assigned.  When it returns nil, the CHPROP command ends, and the "" [Enter] that should be completing the object selection for it becomes a Return that recalls the last command, but within a (command) function that always has a problem with (defun)'d rather than native AutoCAD commands.

 

Without loading it up and trying it, I have a few suggestions.

 

You should not need to check whether the linetypes are loaded [besides which, there's never a need to check for Continuous, because you can't purge it, and Bylayer isn't a linetype that can be "loaded," nor does it show up in a (tblsearch)].  If any objects have them assigned, they will be in the drawing.  But you can avoid the problem by having it only proceed to make the changes you want if it finds any objects with a given linetype assigned.

 

Also, if anything is of ByLayer linetype, it won't be found by searching for that in a code-6 entry -- the object's entity data simply will not have a code-6 entry.  That means (ssget "X" '((6 . "ByLayer"))) will never find anything.  I'd have to think about whether there's any way to use (ssget) to find things that don't have a particular code, other than selecting everything and stepping through to check each one.

 

And by the way, you don't need those (progn) functions, when the 'then' arguments to your (if) tests are just single (command) functions.  The (progn) is needed only if you need to combine multiple functions into one 'then' or 'else' argument.

 

Try something like this [untested] at least for the non-Bylayer categories:

 

(DEFUN C:blkcln ()
;.... your preliminaries ....

  (if (setq ss (ssget "X" '((6 . "HIDDEN")))); only if it finds some
    (command "._chprop" ss "" "C" "byblock" "la" "0" ""); I took out the linrtype assignments, since they already are
  );end if
;
  (if (setq ss (ssget "X" '((6 . "continuous"))))
    (command "._chprop" ss "" "C" "byblock" "la" "0" "")
  );end if
;
; .... your closeout stuff ....

);END DEFUN

 

And of course, those will only work with things that have those linetypes assigned as entitty overrides, not any that inherit them from their Layers.

AUTODESK EXPERT ELITE
7047 Posts
969 Kudos
621 Solutions
Post 2 of 6

Re: Selecting objects by Linetype, If statment

03-19-2013 10:06 AM in reply to: RockyBrown4134

That's probably a result of (ssget) not finding anything with a particular linetype assigned.  When it returns nil, the CHPROP command ends, and the "" [Enter] that should be completing the object selection for it becomes a Return that recalls the last command, but within a (command) function that always has a problem with (defun)'d rather than native AutoCAD commands.

 

Without loading it up and trying it, I have a few suggestions.

 

You should not need to check whether the linetypes are loaded [besides which, there's never a need to check for Continuous, because you can't purge it, and Bylayer isn't a linetype that can be "loaded," nor does it show up in a (tblsearch)].  If any objects have them assigned, they will be in the drawing.  But you can avoid the problem by having it only proceed to make the changes you want if it finds any objects with a given linetype assigned.

 

Also, if anything is of ByLayer linetype, it won't be found by searching for that in a code-6 entry -- the object's entity data simply will not have a code-6 entry.  That means (ssget "X" '((6 . "ByLayer"))) will never find anything.  I'd have to think about whether there's any way to use (ssget) to find things that don't have a particular code, other than selecting everything and stepping through to check each one.

 

And by the way, you don't need those (progn) functions, when the 'then' arguments to your (if) tests are just single (command) functions.  The (progn) is needed only if you need to combine multiple functions into one 'then' or 'else' argument.

 

Try something like this [untested] at least for the non-Bylayer categories:

 

(DEFUN C:blkcln ()
;.... your preliminaries ....

  (if (setq ss (ssget "X" '((6 . "HIDDEN")))); only if it finds some
    (command "._chprop" ss "" "C" "byblock" "la" "0" ""); I took out the linrtype assignments, since they already are
  );end if
;
  (if (setq ss (ssget "X" '((6 . "continuous"))))
    (command "._chprop" ss "" "C" "byblock" "la" "0" "")
  );end if
;
; .... your closeout stuff ....

);END DEFUN

 

And of course, those will only work with things that have those linetypes assigned as entitty overrides, not any that inherit them from their Layers.

Kent Cooper
Collaborator
526 Posts
10 Kudos
21 Solutions
Post 3 of 6

Re: Selecting objects by Linetype, If statment

03-19-2013 10:34 AM in reply to: Kent1Cooper

Thanks Kent. That works sweet.

 

It was even simplier that what I was trying to make it.

 

Ok, i'll keep looking to see what to do for objects that are set for Bylayer.

 

The (Progn were in the cod wen I had it broken out into multiple steps. I just did'nt take them out.

 

Thanks again. I'm a lot closer than I was.

If this response answers your question, Please mark this response as "Accept as Solution"

Rocky Brown
AutoCAD 2015 / Inventor 2015
AUTODESK EXPERT ELITE
2325 Posts
83 Kudos
52 Solutions
Post 4 of 6

Re: Selecting objects by Linetype, If statment

03-19-2013 03:24 PM in reply to: RockyBrown4134

>> Ok, i'll keep looking to see what to do for objects that are set for Bylayer....

 

(tblsearch "LAYER" "MyLayer") will display the dfx codes for that particular layer.

DXF 62 will be color, DXF 6 is linetype.

 

(cdr (assoc 6 (tblsearch "LAYER" "MyLayer"))) is one method to what you are looking for.

 

-OR- look into looping a TBLNEXT to ensure all layers are accounted for...

 

Watch out for xref layers "*|*".

 

Another thought - Don't move bylayer objects to another layer, use -RENAME instead.

 

???

 


Scot-65
Plug Leaks | Fill Gaps | Oil Gears
faceless | twitless | linkless


AUTODESK EXPERT ELITE
7047 Posts
969 Kudos
621 Solutions
Post 5 of 6

Re: Selecting objects by Linetype, If statment

03-19-2013 04:36 PM in reply to: scot-65

scot-65 wrote:
.... 

(tblsearch "LAYER" "MyLayer") will display the dfx codes for that particular layer.

DXF 62 will be color, DXF 6 is linetype.

 

(cdr (assoc 6 (tblsearch "LAYER" "MyLayer"))) is one method to what you are looking for.

 

-OR- look into looping a TBLNEXT to ensure all layers are accounted for...

....


I suspect you've misunderstood what they're trying to do.  It's not about the characteristics of Layers.  They're trying to find [with (ssget) if possible, but I'm not sure it is] all objects whose assigned linetype is "Bylayer," or perhaps I should say whose lack of an assigned linetype makes them Bylayer.  See my paragraph above beginning with "Also" for why I'm not sure you can do that, at least not directly -- you can filter in (ssget) for an entity data entry with a particular associated value, but is it possible to filter for an entry not being there at all?

Kent Cooper
Highlighted
AUTODESK EXPERT ELITE
4725 Posts
780 Kudos
614 Solutions
Post 6 of 6

Re: Selecting objects by Linetype, If statment

03-19-2013 05:54 PM in reply to: RockyBrown4134

RockyBrown4134 wrote:

...

Ok, i'll keep looking to see what to do for objects that are set for Bylayer.

...

 

Just a different approach,

 

(defun c:test (/ ss vlaObj)
  (if (setq ss (ssget "_X"))
    (progn
      (setq ss (vla-get-activeselectionset
		 (vla-get-activedocument (vlax-get-acad-object))
	       )
      )
      (vlax-for	vlaObj ss
	(if (= (vla-get-Linetype vlaobj) "HIDDEN")
	  (progn
	    (vlax-put-property vlaObj 'Layer "0")
	    (vla-put-color vlaObj 0)
	  );; progn
	);; if
	(if (= (vla-get-Linetype vlaobj) "CONTINUOUS")
	  (progn
	    (vlax-put-property vlaObj 'Layer "0")
	    (vla-put-color vlaObj 0)
	  );; progn
	);; if
	(if (= (vla-get-Linetype vlaobj) "BYLAYER")
	  (progn
	    (vlax-put-property vlaObj 'Layer "0")
	    (vla-put-color vlaObj 0)
	  );; progn
	);; if
	(vlax-release-object vlaObj)
      );; vlax-for
    );; progn
  );; if
  (princ)
);; test

 hope that helps
Henrique

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post