Lisp for Correcting Bad Partslist Descriptions and UOM

Lisp for Correcting Bad Partslist Descriptions and UOM

Anonymous
Not applicable
956 Views
13 Replies
Message 1 of 14

Lisp for Correcting Bad Partslist Descriptions and UOM

Anonymous
Not applicable

Hello everyone! My company is going through the pains of a merger with a former competitor. In the process, engineering is updating PN's and drawings to "align" with the other entities of our corporate family. This means taking drawings that were perfectly usable pre-merger, and running various existing lisp routines to produce a partslist (BOM) on our AutoCAD drawings. The descriptions and UOM's that result are terrible. 

 

To correct for this, each designer has to ***manually*** correct all descriptions back to the old GOOD description. (see attached drawing and you will understand how bad the descriptions are!!) This is so we can still process work through our shop.

 

What I need is a lisp that replaces bad descriptions and units of measure. I have no idea how to execute this, and to be honest, I don't have the time to figure it out.

 

Ideally, I would envision selecting all the Good descriptions first then pressing enter, then selecting all the corresponding bad descriptions second, press enter, and the program would go through each block matching the item numbers and swapping out the description attribute. That's the plan. Like I said, no idea how to get to that point. I have had to do this for partslists at least 60 items long and that's just dumb. 

 

Any help is always much appreciated!

0 Likes
957 Views
13 Replies
Replies (13)
Message 2 of 14

Sea-Haven
Mentor
Mentor

Big task but may be some light at end of tunnel. 1st step is dump the attribute details to a file  then open in excel cut paste so then delete anything not relevant, then make into a new csv that is a new , old csv file. You can then look for old text and replace with new text. The big issue is going to be that you need to build the master list. And keep adding as you find missed text.

 

This is dump what you have do it twice open in notepad and paste the 1st column to excel run again paste to excel and check matches. Not sure if the """ will cause problems.

 

Once you have a csv file may be able to do something. 

 

 

(defun c:wow ( / lst1 ss att )
(setq lst1 '())
(alert "pick 1st area of blocks as next step")
(setq ss (ssget (list (cons 0 "INSERT")(cons 2 "BOMPRT"))))
(repeat (setq x (sslength ss))
(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x) ))) 'getattributes)
(if (= "DESC" (strcase (vla-get-tagstring att)))
(setq lst1 (cons (vla-get-textstring att) lst1))
)
)
)
(setq fo (open "d:\\acadtemp\\blkdump.txt" "W"))
(foreach txt lst1
(write-line txt fo)
)
(close fo)
(princ)
)
(c:wow)

 

0 Likes
Message 3 of 14

Anonymous
Not applicable

Sea-Haven,

Thanks for the code but it doesn't really produce a useful result. All i get is a text file with the two desc columns listed. What i really envision is a program that ask to select the good desc's first (perhaps putting them into a matrix?) then the bad desc's second (storing them in a second matrix). Then using the item number as the position within the matrix (ie, item 1 is row 1 of the matrix) make the swap from bad to good descriptions. At the same time, doin the second half which is looking at the units of measure in a similar way and performing a simple conversion calc if there's a potential match (ie, sq ft to sq m, ft to m, etc). If there's not a good correlation (ie, ft to pieces) then the unit of measure is converted as "?" and left for the designer to figure out.

 

I hope this makes sense!

0 Likes
Message 4 of 14

pbejse
Mentor
Mentor

Can you do this one for us

pbejse_0-1634838623652.png

What will be the NEW and correct description?

 

 

0 Likes
Message 5 of 14

Sea-Haven
Mentor
Mentor

You dont need a matrix just a single line say in csv style 3,1,PC,152142,A,Angle-l...,NEWANGLE,M and so on 

 

The Angle description with the commas would use a simple swap to say ANGLE-L|HRS|3.9|3.0|.38 for comparisons. Use any character as seperator. 

 

As per your suggestion there is a command vl-position which finds a matching string in a big list.

0 Likes
Message 6 of 14

Anonymous
Not applicable

patrickthomasme_0-1634914452405.png

Finished result should look like this:

 

3 | 1 | PC | 4H0217043 | - | ANGLE-L,HRS,3.00,3.00,.38

 

Sorry for the confusion! It's literally copying the attribute value of DESC from one line (ie, Ctrl+C of "ANGLE-L,HRS,3.00,3.00,.38" and pasting over the attribute value of "152142:ANGLE STEEL MILD STEEL". then performing a check of the UOM (valid UOM changeovers are: EA -> PC, FT -> M, FT^2 -> M^2, GAL -> L). If there's a UOM mismatch (EA -> M) then program places a "?" in QTY attribute. 

0 Likes
Message 7 of 14

pbejse
Mentor
Mentor

@Anonymous wrote:

Sorry for the confusion! It's literally copying the attribute value of DESC from one line (ie, Ctrl+C of "ANGLE-L,HRS,3.00,3.00,.38" and pasting over the attribute value of "152142:ANGLE STEEL MILD STEEL". then performing a check of the UOM (valid UOM changeovers are: EA -> PC, FT -> M, FT^2 -> M^2, GAL -> L). If there's a UOM mismatch (EA -> M) then program places a "?" in QTY attribute. 


Is that SF -> M2  for FT^2 -> M^2? 

Please verify if this is the correct result:

 

1 | AR | ? | 400020429 | +DI+ | PLATE,TEMPER PASS,.188,LOW CARBON,7.66 LBS/SQ FT | 0
2 | 4 | PC | 4H0217043 | - | ANGLE-L,HRS,3.00,3.00,.38 | 0
3 | 1 | PC | 4H0217043 | - | ANGLE-L,HRS,3.00,3.00,.38 | 0
4 | 1 | PC | 400023745 | - | PLENUM-EXHAUST,INLET MANIFOLD,CLEAN | 0
5 | 1 | PC | 400025615 | - | PLENUM-SEAL AIR,INLET MANIFOLD,CLEAN | 0
6 | 1 | PC | 400026088 | - | FLANGE-EXH,HRS,INLET MANIFOLD,CLEAN | 0
7 | 1 | PC | 400016963 | - | FLANGE-INLET,HRS,INLET MANIFOLD,CLEAN | 0
8 | 1 | PC | 400023922 | - | FLANGE-FORMED,EXTL,610,920,50,76 | 0
9 | 1 | PC | 400025430 | - | ACCESS DOOR ASSY,STL,INSUL PAN,610,920 | 0
10 | 13 | PC | 400018942 | - | COUPLING,BLKS, .500,STD | 0
11 | 2 | PC | 400019336 | - | NIPPLE,BLKS, .500, 6.00,STD | 0
12 | 1 | PC | 400018944 | - | COUPLING,BLKS, .750,STD | 0
13 | 22 | PC | 4S0102808 | - | SCREW-CAP,STL,M 12 X 1.75, 65,HEX HD | 0
14 | 22 | PC | 400016388 | - | WSHR-FLAT,STL,M 12,SERIES W,PLD | 0
15 | 22 | PC | 4S0501024 | - | WSHR-LOCK,STL,M 12,SPRING,PLD | 0
16 | 27 | M | 400014575 | - | SEALANT-JOINT,TEFLON,.375,CONTINUOUS | 0
17 | 1 | ? | 400025044 | - | FLANGE,3154,3154,SV-60 | 0
18 | - | - | - | - | - |  
19 | 1 | PC | 4H0217043 | - | ANGLE-L,HRS,3.00,3.00,.38 | 0
20 | 1 | PC | 4H1553012 | - | TUBING-SQUARE STRL,CS, 3.00,.188 WALL | 0
21 | 2 | PC | 4H1553012 | - | TUBING-SQUARE STRL,CS, 3.00,.188 WALL | 0
22 | 2 | PC | 4H1553012 | - | TUBING-SQUARE STRL,CS, 3.00,.188 WALL | 0
23 | 1 | PC | 4H1553012 | - | TUBING-SQUARE STRL,CS, 3.00,.188 WALL | 0
24 | 6 | PC | 4H0217043 | - | ANGLE-L,HRS,3.00,3.00,.38 | 0
25 | 1 | PC | 400017303 | - | PIPE,BLKS, 2.000,SCHED 40 | 0
26 | 2 | ? | 400021464 | - | CHANNEL-1.63,20.00,UNISTRUT  | 0
27 | AR | ? | 400018843 | - | SHEET,CRS,16 GA,TABULATED | 0
28 | 37 | M2 | 400018765 | - | INSULATION-BLKT,CER FBR,1.00,24.00 | 0
29 | 1 | PC | 400023784 | - | BAFFLE,HX,SEAL AIR,CLEAN | 0
30 | 2 | PC | 400023932 | - | COVER-BAFFLE,HX,SEAL AIR,SV-60 | 0
31 | 24 | PC | 4S0102111 | - | SCREW-CAP,STL,M 12 X 1.75, 25,HEX,HD | 0
32 | 24 | PC | 400016388 | - | WSHR-FLAT,STL,M 12,SERIES W,PLD | 0
33 | 24 | PC | 4S0501024 | - | WSHR-LOCK,STL,M 12,SPRING,PLD | 0

 

 

0 Likes
Message 8 of 14

Scottu2
Advocate
Advocate

I would like to suggest two ways to approach the situation.

 

Option 1:

If both descriptions are on the cad screen then create a lisp routine that would copy the text to text.

Click the source, then click the target text to replace.

The routine would extract the text regardless of the entity type, like attribute, text or mtext

and replace the target text while automatically detecting if its an attribute, text or mtext.

 

Option 2 (data base extraction):

Create two text files tab delimited, the new BOM and the other old BOM.

File format1 (new): PN.n  tab  PN.o  tab  Dn

File format2 (old): PN.o  tab  Do

where PN.n = New part number, PN.o=old part number, Dn=Do=description new and old

 

In format1 primary key is the new part number PN.n with a secondary key PN.o

The secondary key is extracted from the description based on the format ###: to make ###

 

Routine operation:

Select New part:

Create a selection set (ssget block with attribute)

Extract EN (entity name) and PN.n from the text block

Read file format1 line and get the PN.n and PN.o

Compare (if (= selected PN.n) exit loop and read file format2

The routine reads file format2 line and get the PN.n and D.o and compares

(if (= PN.n PN.o) exit loop and put D.o into attribute description of EN

 

Option1 is less key strokes and can be used for other situations

Option2 is more complicated, but its automatic and only be for descriptions.

 

0 Likes
Message 9 of 14

Sea-Haven
Mentor
Mentor

At some stage you will have to make a new / old data list that was what I was suggesting to dump out strings. I would expect a few hundred descriptions. So keep making/updating the master database.

0 Likes
Message 10 of 14

Anonymous
Not applicable

that's correct! That's the output I'm looking for!

0 Likes
Message 11 of 14

Anonymous
Not applicable

@pbejse 

 

Can you post the code for arriving at the results shown?

 

Much appreciated!

0 Likes
Message 12 of 14

Scottu2
Advocate
Advocate

Try the copy text routine from Lee-Mac.

http://www.lee-mac.com/copytext.html

 

0 Likes
Message 13 of 14

pbejse
Mentor
Mentor

@Anonymous wrote:

Can you post the code for arriving at the results shown?


There was no code back then when i posted that result. After you confirm, is is when i started writing the code

 

(Defun c:Otn ( /  _SelData new old nData a aTv BalV UMV NdescV match V_UM)
(defun _SelData (ss  / i Atdata e l)
  (repeat (setq i (sslength ss))
    (setq AtData (mapcar '(lambda (At)
			    (list (vla-get-tagstring at) (vla-get-textstring at)
				  at ) )
			 (Vlax-invoke
			   (setq e (vlax-ename->vla-object (ssname ss (setq i (1- i)))
				   )
			   ) 'GetAttributes
			 )
		 )
    	)
    (setq l (cons (list AtData e) l))
  )
  l
  )  
  (if (and
	(princ "\nSelect new parts list")
	(setq new (ssget '((0 . "INSERT")(66 . 1)(2 . "BOMPRT"))))
	(princ "\nSelect Old parts list")
	(setq old (ssget '((0 . "INSERT")(66 . 1)(2 . "BOMPRT"))))
	)
	(progn
	  (setq nData (_SelData new) oData (_SelData old))
	  (while (setq a (car nData))
	    	 (setq nData (Cdr nData))
	    	(setq aTv (Car a) BalV (assoc "BAL" aTv) UMV (assoc "UM" aTv))
	    	(if (and
		      (setq NdescV (assoc "DESC" aTv))
		      (setq match
			   (Vl-some '(lambda (b)
				(if (eq (Cadr (assoc "BAL" (car b)))(cadr BalV)) b))
					      oData)
			  )
		      (setq descV (assoc "DESC" (car match)))
		      )
		  (progn
		    (setq oData (vl-remove match oData))
		    (Vla-put-textstring  (caddr NdescV) (Cadr descV))
		    (vla-delete (cadr match))
		    (if (and (setq V_UM (assoc (Cadr UMV) '(("PC" "EA") ("M" "FT") ("M2" "SF") ("L" "GAL"))))
		      		(/= (cadr V_UM)(cadr (assoc "UM" (car match)))))
		      	(vla-put-textstring (caddr UMV) "?"))
		    ))))
    )
  (princ)
    )

 

Command: OTN
Select new parts list
Select objects: Specify opposite corner: 33 found

Select objects:


Select Old parts list
Select objects: w
Specify first corner: Specify opposite corner: 32 found

Select objects:

 

HTH

 

 

0 Likes
Message 14 of 14

Sea-Haven
Mentor
Mentor

Maybe I am miss understanding request why would you have "new" block, comparing new to old what happens when a text is not there ? Would not each dwg have a unique "old" so how compare to "new".

 

Thats why I have said all along need a look up system, a file,  find old text replace with new text, it would be dwg independent and could have 100's of entries.

 

Just look at "ANGLE-L,HRS,3.00,3.00,.38 | 0" how many angle types are there ? I doubt only 1 used by the company.

 

Happy to accept I am wrong. Need Patricthomasme to confirm that is the only descriptions ever used by the company. 

0 Likes