Jump to content

Check to so if a layers exists! if so do something, if not skip


HEJINC

Recommended Posts

I’m trying to create an if/then/else command statement. I have 2 sets of lisp routines that I have created. One set is for turn on/off layers in a xref’d dwg and one set for freezing & thawing layers in viewports, depending on the discipline that they apply to.

 

Model space turning on/off lisp

 

(defun c:LAYFLR ()
(COMMAND "LAYER" "SET" "0" "")
(COMMAND "LAYER" "ON" "*A-AC" "ON" "A-AC" "")
(COMMAND "LAYER" "ON" "*A-AC-ATTIC" "ON" "A-AC-ATTIC" "")
(COMMAND "LAYER" "ON" "*A-AC-EXT" "ON" "A-AC-EXT" "")
(COMMAND "LAYER" "ON" "*A-ACC" "ON" "A-ACC" "")
(COMMAND "LAYER" "ON" "*A-ACC-EXT" "ON" "A-ACC-EXT" "")
(COMMAND "LAYER" "ON" "*A-ACC-UPPR" "ON" "A-ACC-UPPR" "")

 

 

Paper space freeze/thaw lisp

 

(defun c:LAYFLRVP ()
(COMMAND "LAYER" "SET" "0" "")
(COMMAND "VPLAYER" "T" "*A-AC" "C" "")
(COMMAND "VPLAYER" "T" "*A-AC-ATTIC" "C" "")
(COMMAND "VPLAYER" "T" "*A-AC-EXT" "C" "")
(COMMAND "VPLAYER" "T" "*A-ACC" "C" "")
(COMMAND "VPLAYER" "T" "*A-ACC-EXT" "C" "")
(COMMAND "VPLAYER" "T" "*A-ACC-UPPR" "C" "")

 

 

Now, I’m showing part of the lisp here, I have about 100 layers I use. Then * is there for picking up xref’d dwg names.

 

My problem is the top lisp, for model space works perfect, even if the layer does not exist in the xref dwg. But the bottom lisp, for paper space, works, but if a layer is missing from the dwg, it crashes at the command line

 

I want to create an if/then/else state!

Check to see if a certain layer exists, then if so freeze or thaw it, if it does not exist, then skip to the next if/then/else statement.

 

How do I do this. My lisp knowledge is limited & self taught

 

Please help

 

HEJINC

Edited by rkmcswain
added CODE tags
Link to comment
Share on other sites

See the (tblsearch "LAYER" "LayerName") function. It returns nil if the layer doesn't exist, so you can use it in an if / cond.

Link to comment
Share on other sites

thanks for the reply. i have done some web searching on this, i found reference to (tblsearch "LAYER" "LayerName"). plus i have not created any if / cond statements before. that's why i made the post, i'm at a loss on how to combine them into a statement that works, LOL :)

Link to comment
Share on other sites

For batch layer work, you could use something like this:

 

[b][color=BLACK]([/color][/b]defun c:batchlay [b][color=FUCHSIA]([/color][/b]/ laylist[b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]setq laylist '[b][color=NAVY]([/color][/b][color=#2f4f4f]"1D"[/color] [color=#2f4f4f]"2D"[/color] [color=#2f4f4f]"3D"[/color][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]command [color=#2f4f4f]"_.LAYER"[/color] [color=#2f4f4f]"_Unlock"[/color] [color=#2f4f4f]"0"[/color] [color=#2f4f4f]"_ON"[/color] [color=#2f4f4f]"0"[/color] [color=#2f4f4f]"_Thaw"[/color] [color=#2f4f4f]"0"[/color] [color=#2f4f4f]"_Set"[/color] [color=#2f4f4f]"0"[/color][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]foreach l laylist
   [b][color=NAVY]([/color][/b]if [b][color=MAROON]([/color][/b]tblsearch [color=#2f4f4f]"LAYER"[/color] l[b][color=MAROON])[/color][/b]
       [b][color=MAROON]([/color][/b]command [color=#2f4f4f]"_Unlock"[/color] l [color=#2f4f4f]"_Thaw"[/color] l [color=#2f4f4f]"_On"[/color] l[b][color=MAROON])[/color][/b]
       [b][color=MAROON]([/color][/b]princ[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]command [color=#2f4f4f]""[/color][b][color=FUCHSIA])[/color][/b]

 [b][color=FUCHSIA]([/color][/b]prin1[b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b]

 

 

Simply change the laylist and commands to your needs. -David

Link to comment
Share on other sites

Not too worry ... they're not that difficult at all.

 

Say you're looking for a layer named something like A-ACC-UPPR.

(if (tblsearch "LAYER" "A-ACC-UPPR") ;Check if the layer exists
 (progn ;Combine the following items into one Then portion for the if
   ;; Add any normal lisp statements here - those you want performed if the layer exists
 ) ;End if progn
 (progn ;Combine the following items into one Else portion for the if
   ;; Add any normal lisp statements here - those you want performed if the layer doesn't exist
 ) ;End if progn
) ;End of if

For the cond thingy, it can be seen as a selection of statements (one of which will perform if its 1st item evaluates to something other than nil):

(cond ;Start a conditional switch
 ;; 1st Condition
 ((tblsearch "LAYER" "A-ACC-UPPR") ;Check for layer A-ACC-UPPR
   ;; Do any number of lisp calls if A-ACC-UPPR exists
   ;; Note none of the following will even be checked if this layer exists
 ) ;End of 1st condition

 ;; 2nd condition
 ((tblsearch "LAYER" "[size=3][font=Arial]A-ACC-EXT[/font][/size]") ;Check for layer [size=3][font=Arial]A-ACC-EXT[/font][/size]
   ;; Do any number of lisp calls if [size=3][font=Arial]A-ACC-EXT[/font][/size] exists
   ;; Note none of the following will even be checked if this layer exists
 ) ;End of 2nd condition

 ;; Last condition (similar to an else portion of the if). It's not needed, but it's available.
 (t
   ;; Do any number of lisp calls if none of the above layers exist
 ) ;End of last condition
) ;End of cond

As you can see the cond is a bit more comprehensive than the if. It's just that you don't need to nest several ifs into each other, and you don't need any progn's to combine several lisp calls into one Then / Else portion.

 

Where your particular system is going to become a bit difficult is when you want to test for layer names with that * wildcard matching. Unfortunately tblsearch doesn't work with this. An alternative method would be to step through each layer's DXF codes in turn using the tblnext method. Then test its DXF code 2 (i.e. layer name) using the wcmatch function - which does use the * wildcards (just now it's also case sensitive so you might want to also use strcase to change everything to upper case before checking).

 

As an alternative, try this:

(defun LayerWCMatch (name / lay found)
 (setq lay (tblnext "LAYER" t)) ;Get the 1st layer
 (while (and (not found) ;While layer was not found
             lay ;And there is a next layer
        ) ;End of and
   ;; Save if the layer's name matches, first changing both the layer's DXF code & the
   ;; name to search for to upper case before checking with wcmatch
   (setq found (wcmatch (strcase (cdr (assoc 2 lay))) (strcase name)) 
         lay (tblnext "LAYER") ;Get the next layer
   ) ;End of setq
 ) ;End of while
 found ;Return t if found / nil if not
) ;End o defun

Now you can use that defun in your own code:

(if (LayerWCMatch [size=3][font=Arial]"*A-AC") [/font][/size];Check if such a layer exists
 [size=3][font=Arial](COMMAND "VPLAYER" "T" "*A-AC" "C" "") ;Then do this one lisp call
) ;End of if[/font][/size]

Repeat for the others.

 

Note this is not the most efficient way. I'd actually go through the layer list once (extracting all their names into a list using the cons function). Then stepping through that list will be a lot quicker than using tblnext each time you check for another layer's existence.

Link to comment
Share on other sites

thanks for your response, you definitly know more about this than me, my expertise in architecture & cad drafting. but i love to create things tht sve me time.

 

thanks again for all your help.

 

i think you last option would work best, due to the "wild card". i under the case sensitive part. that's not a problem. i'll try the last option with layerWCmatch. still now sure sbout something. i hope this is not over my head, LOL :)

 

but basicly i would have a lisp as LAYFLRVP.lsp "layer floor viewpoint"

then define "layerWCmatch", first, as you have encoded

then have an IF statement for each layer, second, as you have encoded

 

????

again thanks for your help

 

HEJINC

Link to comment
Share on other sites

That would work. The LayerWCMatch simply has to be loaded from somewhere to run correctly. If it's inside the same LSP file as the code where you use it, you'll be certain it's always loaded when needed. You could have it in another file and have a (load "Path/Filename") call somewhere in your own file, or just have that other file loaded automatically. It's up to you what you want to do.

 

I've got lots of these helper functions in various files which I simply load when needed. Otherwise I'd have had to load 1000's of LSP files each time a DWG opened. Or worse have 1000's of copies of the same defun in various LSPs.

 

As for placing the code before yours ... it's not really necessary. It needs to be loaded before your code runs, i.e. before the user types the command (or clicks the button). So it could even be after your code in the same LSP. Or you could place a load call to its external file inside your defun just before you use it in one of the ifs - that way it will only load when it actually gets used.

 

BTW, I'm also mostly in Arch & Drafting - but I think my B.Com (info systems) helped me a lot with the programming side. Not as much as simply testing stuff for myself and asking questions here (and on other forums) - that usually teaches a lot better than a disinterested lecturer :shock:

Link to comment
Share on other sites

I’m a draftsman with 4 out of 7 of my exams done. I’m also the cad manager for the office I work in. I create a custom menu program for my cad. I still even use a 12x12 tablet w/ a puck. I have a tablet with about 800 buttons; Regular commands, custom commands for getting around repetitive inputs, short cuts for layers, etc. thought the years I created my own way of doing things, to make my life easier while drawing. Most the LISP files I have, I got from someone years ago. I have edited a few of them into another version or two. I have created a few myself, but not much more complicated than what I posted. All my knowledge is from looking around, playing with & I have some lisp lesion from years ago, put I just don’t understand it all. So even what was post to is confusing. But this is teaching more right now, so thanks

 

I’ll explain how I do things little more

 

I have a base dwg (Xref into another dwg) with all my applicable elements, arch, frmg, fndn, elec, mech, civil. now I have one set of lisp (mspace onse I created 2 yrs ago) for turning on or off the layesr not applicable to the discipline I want to show.( Ex: floor plan, only arch. Related layers show, few excepts but most the structural stuff is off). Now when i have 2 discipline on a sheet. For example, electrical & mechanical, I can create 2 viewports in Pspace & click in each one & run the appropriate lisp for the discipline. So had to remember what layer is on or off for what discipline. That’s what I'm trying to do

 

Since I don’t need to load “layerWCwatch” in each lisp file for each discipline. I could create a separate lisp “LAYERWC”. Use you code for that lisp.

 

I use a master lisp file when loading acad. In that file I add all the lisp I want loaded, instead using the startup suite, for each and every lisp file. shown below would be what I would add to that start up lisp. So it’s loading at startup

 

(autoload " LAYERWC " '("LayerWCMatch"))

 

Then I’ll create the new lisps for the viewports, one for each discipline. Listing out each layer in them. I showed 2 below as an example, not the 100+ I use

 

(defun C:LAYFLRVP ()

(if (LayerWCMatch "*A-AC")

(COMMAND "VPLAYER" "F" "*A-AC" "C" "")

(if (LayerWCMatch "*A-WALL-CMU")

(COMMAND "VPLAYER" "T" "* A-WALL-CMU " "C" "")

)

 

each layer has to be controlled separately. Not enough room to explain it, I could show you in 5 or 10 mins, if you where sitting at my desk with me. I picture is worth a thousand words J

 

would that work. I have beat my head on my desk a lot for this project, LOL J

thanks again

Link to comment
Share on other sites

That would work perfectly if the autoload didn't screw up with the defun's name. I've re-written the autorun for my own puropses, you can see a sample of it inside the menu system I doo for my Open Source project (Caddons). Basically I have the MNL file which loads automatically if that CUI is installed. Then inside it the Caddons:AutoLoad defun performs what you want to do (i.e. autoloads because of a defun call, not a command call with the defun's name prefixed with c: ). See line number 182 in the Caddons.MNL file. It goes a bit further by checking where the CUI was loaded from - thus there's no need to have the folder on the support folders in options: makes installing a whole lot simpler.

 

That's probably a whole lot of too much work for this one file. So I'd just add a normal (load "LAYERWC") to your base LSP. That would be the simplest, especially since it's such a small defun.

Link to comment
Share on other sites

  • 3 weeks later...

well i just was about to get back into the site, since it was down.

 

right now i'm inthe middle of converting from cad 2006 to 2010, so when i get a chance to try it, i'll let know what happens

 

thanks again for your help

Link to comment
Share on other sites

  • 2 weeks later...

i add the "layerwatch" code to make startup lisp file (instead of making a sep. file). created 2 lisp that run the "freeze in current viewport" command & check to see if the layer exsists or not. it seems to work. i'm gona test it on a much larger scale now & do all the layers for each disapline.

 

thanks a lot man. i owe ya one

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...