Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lisp for changing text in an attributed block

11 REPLIES 11
Reply
Message 1 of 12
TROYDAWES
3054 Views, 11 Replies

Lisp for changing text in an attributed block

I work at a MEP Engineering Firm; I am trying to speed up some basic drafting of text revisions.

 

In the P (plumbing) we call out the fixture units for a water pipe, along with the fixture units, the pipe size changes.

 

  1. Is there any way to add numbers in an attributed block? (I have a lisp that works on text & mtext, but not attributes)

1.1.    Example: Like if you have a block with two attributed text fields, the 1st field {x} is a number (fixture unit), and the 2nd field {y} is a number (pipe size).  I would want it to only add the 1st text fields. [If possible then change the 2nd text field according to a changeable chart. (see #2)]

1.1.1.   This is how the block looks like: x (y")

1.1.1.1.   x could be any number from 0.5 – 10,000 (only using 1 decimal place, and only as needed)

1.1.1.2.   y could be any number from the following list: ½, ¾, 1, 1¼, 1½, 2, 2½, 3, 3½, 4, 5, 6

 

  1. Is there a way like in excel that you can set up a formula that will give a numerical result depending on other input? Like pipe size that change depending on the number of fixtures. There would need to be two different formula, one for hot and one for cold values (The value would be set at the beginning of the job; typically these values would not change later in the job). This could be separate text or if possible using the attributed block as described in #1.

2.1.    Example: Like if you have a block with two attributed text fields, the 1st field {x} is a number (fixture unit), and the 2nd field {y} is a number (pipe size).  I would want it to change the 2nd text fields according to the value in the 1st text field. If the value in {x} is 0.5 – 1.0, it would result in ½; 1.5 – 7.0 = ¾; 7.5 - 17 = 1; 17.5 – 36 = 1¼; ect.

2.2.    In excel it would be =IF(x)<1,"1/2",IF(x)<7,"3/4”,IF(x)<17,"1",…{all #’s in between} …IF(x)>5000,"6")))))

 

Thank you for all your help, and input,

Troy Dawes

Tags (3)
11 REPLIES 11
Message 2 of 12
hmsilva
in reply to: TROYDAWES

TROYDAWES,

Attached is a dwg to test the lisp

Try it, is minimally tested...

 

(defun c:test (/ ss blk xstr xnum ystr yent)
  (setq ss (ssget "_:S" (list (cons 0 "INSERT") (cons 2 "xy")))); change your blk name
  (setq blk (ssname ss 0))
  (setq xstr (cdr (assoc 1 (entget (setq blk (entnext blk))))))
  (setq xstr (vl-string-subst "." "," xstr))
  (setq xnum (atof xstr))
  (if (>= xnum 0.5)
    (progn
      (cond
	((and (>= xnum 0.5) (<= xnum 1.0)) ;between 0,5  and 1.0
	 (setq ystr "(1/2\")")
	)
	((and (>= xnum 1.5) (<= xnum 7.0)) ;between 1,5  and 7.0
	 (setq ystr "(3/4\")")
	)
	((and (>= xnum 7.5) (<= xnum 17.0)) ;between 7,5  and 17.0
	 (setq ystr "(1\")")
	)
	((and (>= xnum 17.5) (<= xnum 36.0)) ;between 17,5  and 36.0
	 (setq ystr "(1 1/4\")")
	);Complete according to your changeable chart for the other sizes
      ); cond
      (setq yent (entget (setq blk (entnext blk))))
      (setq yent (subst (cons 1 ystr) (assoc 1 yent) yent))
      (entmod yent)
    ); progn
  ); if
  (setq ss nil)
  (princ)
); defun

 

hope that helps

 

Henrique

EESignature

Message 3 of 12
pbejse
in reply to: TROYDAWES


@TROYDAWES wrote:

 ..... fields, the 1st field 


Are you refering to FIELD Expressions? 

 

 

Message 4 of 12
Hallex
in reply to: TROYDAWES

Hi Troy, welcome on board Can you upload sample drawing with this block and Excel file to work with?
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 5 of 12
TROYDAWES
in reply to: TROYDAWES

Attached are some samples:

 

FU-PS-LEFT.dwg is one of the attributted blocks

PIPE SIZING SAMPLE.dwg is a sample using the block, and the table that shows the calculations.

 

Hope this helps,

Troy

Message 6 of 12
TROYDAWES
in reply to: pbejse


@pbejse wrote:

@TROYDAWES wrote:

 ..... fields, the 1st field 


Are you refering to FIELD Expressions? 

 

 


I am referring to the prompts within the attributed block.

 

In the block, there are 2 separate attributes

1st attribute is the Fixture units, in the block I use, the TAG = FU, PROMPT = Number of fixture units, DEFAULT = (x)

2nd attribute is the Pipe size, in the block I use, the TAG = PS, PROMPT = Pipe Size, DEFAULT = y

 

I am sorry if I am using the wrong terminology. 

 

Attached is the block.

 

Thanks,

Troy

Message 7 of 12
hmsilva
in reply to: TROYDAWES

TROYDAWES wrote:
Example: Like if you have a block with two attributed text fields, the 1st field {x} is a number (fixture unit), and the 2nd field {y} is a number (pipe size). 
I would want it to change the 2nd text fields according to the value in the 1st text field...

 

Troy,
just a question, you want to change the second attribute at the moment you inserts the block,
or after the block is inserted and with the value of the first attribute already filled?

 

Henrique

EESignature

Message 8 of 12
TROYDAWES
in reply to: hmsilva


@hmsilva wrote:

@TROYDAWES wrote:
Example: Like if you have a block with two attributed text fields, the 1st field {x} is a number (fixture unit), and the 2nd field {y} is a number (pipe size). 
I would want it to change the 2nd text fields according to the value in the 1st text field...

 

Troy,
just a question, you want to change the second attribute at the moment you inserts the block,
or after the block is inserted and with the value of the first attribute already filled?

 

Henrique


After, the block will already be in the drawing.

Message 9 of 12
hmsilva
in reply to: TROYDAWES

Troy,

let's see if the attached lisp have the desired result, see the txt file attached, and before running the code you need to create in the same directory where the dwg is, a file named "Fixture Unit.txt" it will operate as a data base, the file need to be identical to the file I have attached, no blank lines at the end and no spaces after the text values and a space separating the first value to the second value of each set, the first eleven sets of values are for cold water and second eleven sets of values are for hot water.

Even if you do not use all diameters in that specific job, you have to provide all the data (twenty-two sets of values), to populate the code variables.

 

 

Hope that helps, good luck

 

Henrique

EESignature

Message 10 of 12
Kent1Cooper
in reply to: TROYDAWES


@TROYDAWES wrote:

....

1.1.1.1.   x could be any number from 0.5 – 10,000 (only using 1 decimal place, and only as needed)

1.1.1.2.   y could be any number from the following list: ½, ¾, 1, 1¼, 1½, 2, 2½, 3, 3½, 4, 5, 6

....

If the value in {x} is 0.5 – 1.0, it would result in ½; 1.5 – 7.0 = ¾; 7.5 - 17 = 1; 17.5 – 36 = 1¼; ect.

....

IF(x)>5000,"6"

....


Others have dealt with applying values to the Attributes....

 

As for determining the pipe diameter based on the fixture unit count, I think you can avoid a lot of the repetition in something like a (cond) function, with each possibility having its own separate (setq) function for the diameter text, or a bunch of (if)'s, or whatever.  And it doesn't seem necessary to use an external file.  A couple of relatively simple lists right in the routine, with appropriate use of (nth), can do it, with just one (setq) function to put the diameter text into a variable.

 

With 'fu' being a variable name containing the Fixture Unit count [which would be converted to text and applied to the first Attribute], you can do this:

 

(setq inc 0)
(while
  (> fu (nth inc '(1 7 17 40 100 200 350 800 1200 2000 5000 99999))); guestimates -- supply correct numbers
  (setq inc (1+ inc)); raise increment to next number if appropriate
); while
(setq diatxt ; = DIAmeter TeXT to be applied to second Attribute
  (strcat
    "(" ; [applicable to all]
      (nth inc '("1/2" "3/4" "1" "1 1/4" "1 1/2" "2"  "2 1/2" "3"  "3 1/2" "4" "5" "6"))
    "\")" ; [applicable to all]
  ); strcat
); setq

 

That way, if the fixture unit count is anything up to 1, the test in the (while) function will fail on the first try, and the 'inc' variable will remain at 0, and it will extract the "1/2" from the second list.  If 'fu' is more than 1 but less than or equal to 7, it will have moved 'inc' up to 1, but no further, and will extract "3/4" from the second list.  And so on, until it finds the right position.

 

Trying it out:

 

(setq fu 0.75)
The function returns:

"(1/2\")"

 

(setq fu 384); assuming my guestimates are close-ish
The function returns:

"(3\")"

 

(setq fu 18)
The function returns:

"(1 1/4\")"

 

(setq fu 6343)
The function returns:
"(6\")"

 

You could incorporate the (chr) things for the stacked-fraction characters, if you prefer them that way and your text font can handle that.

Kent Cooper, AIA
Message 11 of 12
pbejse
in reply to: TROYDAWES


@TROYDAWES wrote:
In the block, there are 2 separate attributes

1st attribute is the Fixture units, in the block I use, the TAG = FU, PROMPT = Number of fixture units, DEFAULT = (x)

2nd attribute is the Pipe size, in the block I use, the TAG = PS, PROMPT = Pipe Size, DEFAULT = y

 


Another approach:

 

(defun c:demo ( / table blks i e fu ps)
(vl-load-com)
;;; This is where you add additional values ;;; (min max string) ;;; (1 10 "value")
(setq table '((0.5 1.0 "½")(1.5 7.0 "3/4") (7.5 17.0 "1")(17.5 36.0 "1¼")))

;;;
(if (setq blks (ssget "_X" '((0 . "INSERT") (2 . "FU-PS-RIGHT,FU-PS-LEFT")))) (repeat (setq i (sslength blks)) (setq val (vlax-invoke (setq e (vlax-ename->vla-object (ssname blks (setq i (1- i))))) 'GetAttributes)) (if (and (setq fu (car (read (vla-get-textstring (Car val))))) (setq ps (vl-some '(lambda (x) (if (<= (Car x) fu (cadr x)) (last x) nil)) table))) (vla-put-textstring (Cadr val) ps)) ) )(princ) )

 

 

HTH

 

Message 12 of 12
3wood
in reply to: TROYDAWES

Now you can use formula in ALTEXT.

Please try attached ALTEXT.vlx, and select "Use formula" and the bottom. When it prompts to select a lisp file as the formula, pick up ALTEXT_formula.lsp

You can expand/modify the condition defined in ALTEXT_formula.lsp as you like.

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost