Jump to content

Recommended Posts

Posted

Hi,

 

I have been using CAD for a while and am pretty experienced...however i am now trying to write a lisp routine for a simple change...but i am stuck!

 

What i am trying to do:

 

1) select all text on "EC_DATA_EQPM_E" layer (there are other objects on this layer)

2) Move this text to a new layer "Commstextlayer"

 

When i do this lisp at the moment i get the error message:

"Error: no function definition: nil"

 

I am pretty sure that i have made a basic error somewhere (routine below) ..but am not sure how to fix it...any help would be really appreciated - or if you have a similar lisp which i could modify that would be great

 

Many thanks,

 

Marcus

 

 

My routine:

 

(defun c:changetextonlayer()

(setq lay_name "EC_DATA_EQPM_E")

(setq ss1 ((ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name)))))

(subst (cons 8 "Commstextlayer") (assoc 8 ss1) ss1 )

)

  • Replies 33
  • Created
  • Last Reply

Top Posters In This Topic

  • scaramangamp

    12

  • Lee Mac

    10

  • jammie

    4

  • alanjt

    4

Top Posters In This Topic

Posted

One way is to iterate through each text entity in the selection set ss1 and change the properties individually. I prefer VLisp functions...

Replace your (subst line with this

 

(vl-load-com)
(setq idx 0)
(repeat (sslength ss1)
  (setq obj (vlax-ename->vla-object (ssname ss1 idx)))
  (vlax-put-property obj 'Layer "Commstextlayer")
   (setq idx (1+ idx))
)

Untested... if the layer "Commstextlayer" doesn't exist it will error

 

You could also use

(command "_Change" ss1 "" "P" "LA" "Commstextlayer" "")

again... untested

Posted

Ok, thanks..

 

I have added this...the layer "Commstextlayer" doesn't exist..however i thought that it would just make the layer.

 

If i wanted to add in the line to make a new layer how would i do that?

and also would i then be able to change the properties of the layer (lineweight, colour) etc. in the same lisp file

 

Thanks for you help,

 

Marcus

Posted
(if (not
(tblsearch "layer" "Commstextlayer"))
(command "_layer" "m" "Commstextlayer" ""); add color, linetype etc. in here
)

this may set the layer "Commstextlayer" current, so you may want to restore the previous current layer

Posted

Thank you very much...

 

Here is my lsp. file however it still doesn't work it get the "Error: no function definition: nil" error message...do you know what is wrong with it?

 

(DEFUN C:changetextonlayer()

(setq lay_name "EC_DATA_EQPM_E")

(setq ss1 ((ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name)))))

(if (not

(tblsearch "layer" "Commstextlayer"))

(command "_layer" "m" "Commstextlayer" "" "LW" "0.25" "Commstextlayer" "C" "7" "Commstextlayer")) ; add color, linetype etc. in here

(PRINC)

)

 

 

Thanks for all of your help!

Posted
Error: no function definition: nil"

 

You have an extra set of brackets

 

(setq ss1 [color="Red"]([/color](ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name)))[color="red"])[/color])

 

I would probably use lpseifert method of iterating through the selection set, espicially if you need to change several object propeties. That being said the Change command will also work quiet well for this example.

 

(DEFUN C:changetextonlayer()

 (if
   (not
     (tblsearch "layer" "Commstextlayer"))
   (command "_layer" "m" "Commstextlayer" "LW" "0.25" "Commstextlayer" "C" "7" "Commstextlayer" "")
   )

 (setq lay_name "EC_DATA_EQPM_E")

 (if
   (setq ss1 (ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name))))

   (progn

     (command "change" ss1 "" "p" "la" "Commstextlayer" "")
     )
   )      
; add color, linetype etc. in here
(PRINC)
)

Posted

I think you've got an unnecessary set of parenthesis there, around your "ssget", and that might be the cause of your error.

 

Also, I would suggest (this is only a suggestion) that you include a check to see if your selection set exists before you try to do stuff with it. You could wrap that into your IF statement, like so:

 

(if (and ss1 (not (tblsearch "layer" "Commstextlayer"))) ...)

Posted

Thanks Jammie, i have removed the extra bracket and have changed it slightly (changed order as Jammie suggested and swapped "commstextlayer" for "EC_TEXT")

 

I am now getting a "Syntax error" do you know why this may be...?

 

I think i will keep the Command line as it is..because that is one of the few bits i actually understand! - thanks for your suggestions.

 

In my script is the text actually being moved onto the new layer though?

 

(DEFUN C:changetextonlayer()

(if (not

(tblsearch "layer" "EC_TEXT"))

(setq lay_name "EC_DATA_EQPM_E")

(setq ss1 (ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name))))

(command "_layer" "m" "EC_TEXT" "LW" "0.25" "EC_TEXT" "C" "7" "EC_TEXT" "")) ; change properties in here

(PRINC)

)

 

 

Once again thanks for your help

Posted

Hi Scaramangamp,

 

Quite a few options have already been made available to you, here is my offering :)

 

Perhaps take a look at these threads for an idea on how to change the DXF codes of entities:

 

Explanation of a LISP function (Text replacement):

http://www.cadtutor.net/forum/showpost.php?p=264546&postcount=15

 

 

Explanation of a LISP function (Text Height Change):

http://www.cadtutor.net/forum/showpost.php?p=306576&postcount=14

 

 

They do not use SelectionSets, but you may be able to glean something from them.

 

 

With regards to your problem, this is how I might approach it.

 

(defun c:TxtLay (/ Layer ELST ENT I NEWLAYER OLDLAYER SS)

 (setq OldLayer "EC_DATA_EQPM_E" NewLayer "EC_TEXT")

 (defun Layer (Nme Col LWgt)
   (entmake (list (cons 0 "LAYER")
                  (cons 100 "AcDbSymbolTableRecord")
                  (cons 100 "AcDbLayerTableRecord")
                  (cons 2  Nme)
                  (cons 70 0)
                  (cons 62 Col)
                  (cons 370 LWgt))))

 (if (setq i -1 ss (ssget "_X" (list '(0 . "TEXT") (cons 8 OldLayer))))
   (progn     

     (or (tblsearch "LAYER" NewLayer)
         (Layer "EC_TEXT" 7 25))

     (while (setq ent (ssname ss (setq i (1+ i))))
       (setq eLst (entget ent))
       
       (entmod (subst (cons 8 NewLayer) (assoc 8 eLst) eLst))))

   (princ "\n** No Text Found **"))

 (princ))

 

There are lots of ways to approach these problems, see this thread perhaps.

 

Lee

Posted

On a side note, if you really wanted to go the VL route, then this will take you all the way :twisted:

 

(defun c:TxtLayVL (/ MakeVariant Itemp DOC NEWLAYER NLAYER OLDLAYER SELSETS SS)
 (vl-load-com)

 (setq OldLayer "EC_DATA_EQPM_E" NewLayer "EC_TEXT")

 (defun MakeVariant (typ lst)
   (vlax-make-variant
     (vlax-safearray-fill
       (vlax-make-safearray (eval typ)
         (cons 0 (1- (length lst)))) lst)))

 (defun itemp (collection item / result)
     (if (not (vl-catch-all-error-p
                (setq result
                       (vl-catch-all-apply (function vla-item)
                         (list collection item)))))
       result))

 (if (setq ss (itemp (setq SelSets
                       (vla-get-SelectionSets
                         (setq doc (vla-get-ActiveDocument
                                     (vlax-get-acad-object))))) "TextLaySS"))
   (vla-delete ss))

 (setq ss (vla-add SelSets "TextLaySS"))

 (vla-Select ss acSelectionSetAll
   (MakeVariant vlax-vbInteger '(0 )
     (MakeVariant vlax-vbVariant (list "TEXT" OldLayer)))

 (if (not (zerop (vla-get-count ss)))
   (progn
     (vla-StartUndoMark doc)

     (or (itemp NewLayer (vla-get-Layers doc))
         (progn
           (setq nLayer (vla-Add (vla-get-layers doc) NewLayer))
           (vla-put-Lineweight nLayer acLnWt025)
           (vla-put-Color nLayer acWhite)))
   
     (vlax-for obj ss (vla-put-Layer obj NewLayer))

     (vla-EndUndoMark doc))

   (princ "\n** No Text Found **"))

 (vla-delete ss)
 (princ))

Posted
On a side note, if you really wanted to go the VL route, then this will take you all the way :twisted:

 

LoL, you're going to scare him away from VL.

 

Here's a combination way.

 

(defun c:TEst (/ OldLayer NewLayer ss la)

 (setq OldLayer "EC_DATA_EQPM_E"
       NewLayer "EC_TEXT"
 ) ;_ setq

 (cond
   ((setq ss (ssget "_X" (list '(0 . "TEXT") (cons 8 OldLayer))))
    (or *AcadDoc* (setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
    (or (tblsearch "layer" NewLayer)
        (progn (setq la (vla-add (vla-get-layers *AcadDoc*) NewLayer))
               (vla-put-color la 7)
               (vla-put-lineweight la 25)
        ) ;_ progn
    ) ;_ or

    (vlax-for x (setq ss (vla-get-activeselectionset *AcadDoc*))
      (vl-catch-all-apply
        (function vla-put-layer)
        (list x la)
      ) ;_ vl-catch-all-apply
    ) ;_ vlax-for
    (vla-delete ss)
   )
 ) ;_ cond
 (princ)
) ;_ defun

Posted

lol, I don't make SelectionSets in VL too often, so its refreshing :)

Posted
I am now getting a "Syntax error" do you know why this may be...?

 

(if (not
(tblsearch "layer" "EC_TEXT"))
[color="Blue"](setq lay_name "EC_DATA_EQPM_E")[/color]
[color="Red"](setq ss1 (ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name))))[/color]
[color="SeaGreen"](command "_layer" "m" "EC_TEXT" "LW" "0.25" "EC_TEXT" "C" "7" "EC_TEXT" "")[/color]) 

 

The oder of you code is important here. Although on first impression it may look ok, you are actually trying to pass to many arguments to the if expression. I would suggest looking at the help files for AutoCAD's Visual Lisp IDE for info on conditional testing

 

This should work

 

(DEFUN C:changetextonlayer()

(if
 (not
   (tblsearch "layer" "EC_TEXT"))
 (command "_layer" "m" "EC_TEXT" "LW" "0.25" "EC_TEXT" "C" "7" "EC_TEXT" "")
 )
 (setq lay_name "EC_DATA_EQPM_E")
(setq ss1 (ssget "X" (list (cons 0 "TEXT")(cons 8 lay_name))))
 ; change properties in here
(PRINC)
)

Posted

Hi there...i am new to all of this - as you can probably tell! - what is the difference between Lisp and Visual Lisp?

 

Which one is easiest to understand and use and which one should i use to solve this problem?

 

Thanks,

 

Marcus

Posted

Visual LISP is an extension of Vanilla LISP, that uses the ActiveX Model.

 

vla-* functions are Visual LISP versions of their VBA couterparts.

vlax-* functions don't have VBA alternatives

vlr-* functions are for use with reactors, similar to VBA Events, but different in their usage/syntax.

 

Visual LISP is perhaps more intuitive, with functions like 'vla-put-layer', but has less intuitive data types (variants/safearrays) - I recommend getting used to dealing with data in Vanilla LISP so that you get used to the concept of lists, then move into Visual LISP (at least, that's how I did it).

 

Lee

Posted

Thank for clearing that up Lee, i fear it will be a slow and painful (mainly learning by mistakes) process to learn.

 

Jammie, with that code..which i am using as it seems to be the easiest to follow. On the second to last line it says "setq ss1" do we still need to have this setq as it isn't referred to anywhere else in the code.

 

Also where in that code does it move the text (found on EC_DATA_EQPM_E) to the layer "EC_TEXT" as i can't see that line of code?

 

Thanks

 

Marcus

Posted

Is this correct? - although is now seem to get

"Error: bad argument type: listp " !!

 

(DEFUN C:textlayer()

(if

(not

(tblsearch "layer" "EC_TEXT"))

(command "_layer" "m" "EC_TEXT" "LW" "0.25" "EC_TEXT" "C" "7" "EC_TEXT" ""))

(setq lay_name "EC_DATA_EQPM_E")

(setq ss1 (ssget "X" (list (cons 0 "*TEXT")(cons 8 lay_name))))

(subst (cons 8 "EC_TEXT") (assoc 8 ss1) ss1 )

(PRINC)

)

 

Marcus

Posted

If you are going to use 'subst' look at my earlier example.

 

Jammie's solution is set up to use a command call to chprop or similar.

Posted

If you're new, I'd stick with command calls, just to get comfortable with programming.

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...