LISP TO INSERT A BLOCK WITH DIFFERENT ATTRIBUTES AT COORDINATES FROM .CSV FILE

LISP TO INSERT A BLOCK WITH DIFFERENT ATTRIBUTES AT COORDINATES FROM .CSV FILE

Anonymous
Not applicable
5,330 Views
15 Replies
Message 1 of 16

LISP TO INSERT A BLOCK WITH DIFFERENT ATTRIBUTES AT COORDINATES FROM .CSV FILE

Anonymous
Not applicable

Attached is a sample drawing with the block "TEST" to insert and a sample .csv file in which column b and c are x and y coordinates respectively and column a is the value of the attribute at that coordinate.

The default block attribute is 0000, what the lisp should accomplish is to insert block "TEST" at the coordinates specified by the .csv file and changing the default value of "0000" to what the .csv specifies (ex. "0+15"). 

It would be awesome if some of you could lend me a hand.

Thank you,

Jorge.

Accepted solutions (1)
5,331 Views
15 Replies
Replies (15)
Message 2 of 16

dbhunia
Advisor
Advisor
Accepted solution

check the below code.....

 

(defun c:IB ( / fn fp lst l)
(setq fn (getfiled "Select CSV file" "" "csv" 4))
(setq fp (open fn "r") lst '())
(while (setq l (read-line fp))
(setq lst (cons l lst))
)
(close fp)
(setq VAL (getvar "attreq"))
(command "attreq" 0)

(foreach Row lst
(while (if (setq n (vl-string-search "," Row 0))
(setq Row (vl-string-subst " " "," Row))
)
)
(setq Row (read (strcat "(" Row ")")))

(setq ATT1 (vl-symbol-name (nth 0 Row)))
(setq X (nth 1 Row))
(setq Y (nth 2 Row))
(setq PT1 (list X Y))

(command "insert" "TEST" PT1 "1" "" "0")
(setq b1 (entget (entnext (entlast))))
(setq ff1(assoc 1 b1))
(setq xx1 (cons 1 ATT1))
(entmod(subst xx1 ff1 b1))
)
(command "attreq" VAL)
)


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 3 of 16

Anonymous
Not applicable

Hi Dbhunia, thank you so much for the help the lisp forks perfectly as intended.

Regards,

Jorge.

Message 4 of 16

Anonymous
Not applicable

Sir, thanks a lot, i had the same ''problem'' and you solution was perfect

0 Likes
Message 5 of 16

Anonymous
Not applicable

hi, could you please add a few lines of code to this LISP so that more than 1 attribute can be loaded,
example
ATT1, ATT2, ATT3, X, Y
if I had the time and the opportunity I would be grateful

0 Likes
Message 6 of 16

Sea-Haven
Mentor
Mentor

This is a simple example of a multi att block with 2 attributes.

 

(command "-insert" "aaa" "23,24" 1 1 0 "abc" 12)

(command "-insert" blkname (list x y) 1 1 0 att1 att2)

 

0 Likes
Message 7 of 16

pbejse
Mentor
Mentor

@Anonymous wrote:

hi, could you please add a few lines of code to this LISP so that more than 1 attribute can be loaded,
example
ATT1, ATT2, ATT3, X, Y
if I had the time and the opportunity I would be grateful


 

What is then the value for the 2 other attributes? granting one would have the X and Y coordinates similar to the OP.

Which of the 3 will will show the coordinates?

 

 

 

0 Likes
Message 8 of 16

Sea-Haven
Mentor
Mentor

Like pbe need a sample csv.

0 Likes
Message 9 of 16

Anonymous
Not applicable

here you are, in the attachment I am sending a data file and a dwg with the appropriate block to insert, I tried to figure something out myself, but unfortunately I do not know the language well yet and somehow I cannot comprehend it

 

0 Likes
Message 10 of 16

pbejse
Mentor
Mentor

 

 


@Anonymous wrote:

here you are, in the attachment I am sending a data file and a dwg with the appropriate block to insert, I tried to figure something out myself, but unfortunately I do not know the language well yet and somehow I cannot comprehend it

 


There are four columns of info A|B|C|D and two for coordiantes E|F

You have 3 attributes : ATT1|ATT2|ATT3

What column goes to what attribute?

 

0 Likes
Message 11 of 16

CADaSchtroumpf
Advisor
Advisor

Try this code:

(defun c:readCSV2BLK ( / input f_open l_read data1 data2 data3 x_data y_data new_pt)
	(setvar "CMDECHO" 0)
	(setvar "ATTDIA" 0)
	(setq
		input (getfiled "Select a CSV file" "" "csv" 2)
		f_open (open input "r")
	)
	(while (setq l_read (read-line f_open))
		(setq
			data1 (substr l_read 1 (vl-string-position 44 l_read))
			l_read (substr l_read (+ 2 (vl-string-position 44 l_read)))
			data2 (substr l_read 1 (vl-string-position 44 l_read))
			l_read (substr l_read (+ 2 (vl-string-position 44 l_read)))
			data3 (substr l_read 1 (vl-string-position 44 l_read))
			l_read (substr l_read (+ 2 (vl-string-position 44 l_read)))
			l_read (substr l_read (+ 2 (vl-string-position 44 l_read)))
			x_data (atof (substr l_read 1 (vl-string-position 44 l_read)))
			l_read (substr l_read (+ 2 (vl-string-position 44 l_read)))
			y_data (atof (substr l_read 1 (vl-string-position 44 l_read)))
			new_pt (list x_data y_data 0.0)
		)
		(command "_.-insert" "HP_B" "_none" new_pt 1.0 1.0 0.0 data1 data2 data3)
	)
	(close f_open)
	(setvar "ATTDIA" 1)
	(setvar "CMDECHO" 1)
	(prin1)
)
0 Likes
Message 12 of 16

_Tharwat
Advisor
Advisor

@pbejse wrote:

 

 


@Anonymous wrote:

here you are, in the attachment I am sending a data file and a dwg with the appropriate block to insert, I tried to figure something out myself, but unfortunately I do not know the language well yet and somehow I cannot comprehend it

 


There are four columns of info A|B|C|D and two for coordiantes E|F

 

 


In rows 1240 & 1241 there are not, because my program stuck there. 😉

0 Likes
Message 13 of 16

Sea-Haven
Mentor
Mentor

A more global answer would be to redo the csv so X Y are always column A & B just makes life easier.

 

There is no reason why the csv could not have multiple block names with multi atts or even none. Converting the csv line to a list know its length so there for know how many atts, its a case of looping the att part when inserting the block.

 

Obvious error checks are more atts in csv than block has, pad the list if missing atts. So a few extra steps required.

 

 

 

0 Likes
Message 14 of 16

pbejse
Mentor
Mentor

@Sea-Haven wrote:

A more global answer would be to redo the csv so X Y are always column A & B just makes life easier.

 

That is a good idea.

 

 

0 Likes
Message 15 of 16

Anonymous
Not applicable

Thanks for such a quick response, I test this lisp quite intensively, sometimes it bugs or doesn't start, I think there might be a problem with the input data file. I would have such a question (because I try to do it myself, but it does not work) so that I could download the data about the structure
X, Y, ATT1
later I will complete the attributes in excel with attout and attin
the most important thing is that the blocks should be created in place of the given coordinates with at least this one attribute

0 Likes
Message 16 of 16

CADaSchtroumpf
Advisor
Advisor

Hi,

I tried to create a more generic function to have more flexibility in reading the source CSV file.
The essential is to have at least the X and Y coordinates defined in the CSV, but the file can also contain other data that can be imported as an attribute value (or not!)
The file must also have an identical structure in all its content and purge it of its header line if it has one: keep only the data.

The program will first expose the 1st line and you will be asked for each element, if it is a data for an attribute value, a place value (XY and / or Z), or if you want to ignore this value, this will also determine the position of the columns and therefore those to import.

The program will generate the block with the desired number of attributes and insert it into the drawing with the respective attributes.

 

; str2lst
;; Transforme un chaine avec séparateur en liste de chaines
;;
;; Arguments
;; str : la chaine à transformer en liste
;; sep : le séparateur
;;
;; Exemples
;; (str2lst "a b c" " ") -> ("a" "b" "c")
;; (str2lst "1,2,3" ",") -> ("1" "2" "3")
(defun str2lst (str sep / pos)
	(if (setq pos (vl-string-search sep str))
		(cons
			(substr str 1 pos)
			(str2lst (substr str (+ (strlen sep) pos 1)) sep)
		)
		(list str)
	)
)
(defun c:readCSV2BLK ( / input f_open l_read key_sep str_sep l_data l_ini count count_coor key_data x_data y_data z_data l_rmv l_var inc gab_l last_y l_str l_mes blk_scl pt)
	(setq
		input (getfiled "Select a CSV file" "" "csv" 2)
		f_open (open input "r")
		l_read (read-line f_open)
	)
	(close f_open)
	(initget "SPace Comma SEmicolon Tabulation")
	(setq key_sep (getkword "\nSeparator [SPace/Comma/SEmicolon/Tabulation]? <SEmicolon>: "))
	(cond
		((eq key_sep "SPace") (setq str_sep " "))
		((eq key_sep "Comma") (setq str_sep ","))
		((eq key_sep "Tabulation") (setq str_sep "\t"))
		(T (setq str_sep ";"))
	)
	(setq l_data (str2lst (vl-string-right-trim str_sep l_read) str_sep) count 0 count_coor 0 l_ini "Data Xlocation Ylocation Zlocation Ignore")
	(foreach el l_data
		(initget 1 l_ini)
		(setq key_data (getkword (strcat "\nElement " el " is [" (vl-list->string (subst 47 32 (vl-string->list l_ini))) "]?: ")))
		(cond
			((eq key_data "Xlocation") (setq x_data count_coor l_ini (vl-string-subst "" (strcat " " key_data) l_ini) l_rmv (cons (if l_rmv (+ count (length l_rmv)) count) l_rmv) count (1- count)))
			((eq key_data "Ylocation") (setq y_data count_coor l_ini (vl-string-subst "" (strcat " " key_data) l_ini) l_rmv (cons (if l_rmv (+ count (length l_rmv)) count) l_rmv) count (1- count)))
			((eq key_data "Zlocation") (setq z_data count_coor l_ini (vl-string-subst "" (strcat " " key_data) l_ini) l_rmv (cons (if l_rmv (+ count (length l_rmv)) count) l_rmv) count (1- count)))
			((eq key_data "Ignore") (setq l_rmv (cons (if l_rmv (+ count (length l_rmv)) count) l_rmv) count (1- count)))
			(T
				(set (read (strcat "DATA" (itoa count))) count)
				(setq l_var (cons (read (strcat "DATA" (itoa count))) l_var))
			)
		)
		(setq count (1+ count) count_coor (1+ count_coor))
	)
	(cond
		((and (numberp x_data) (numberp y_data))
			(setq count 0 inc (/ 5.0 3.0) gab_l (length l_var))
			(mapcar
				'(lambda (x y / ) 
					(if (not (tblsearch "LAYER" x))
						(entmake
							(list
								'(0 . "LAYER")
								'(100 . "AcDbSymbolTableRecord")
								'(100 . "AcDbLayerTableRecord")
								(cons 2 x)
								'(70 . 0)
								(cons 62 y)
								'(6 . "Continuous")
								'(290 . 1)
								'(370 . -3)
							)
						)
					)
				)
				'("CSV2BLK" "CSV2BLK_x-y" "CSV2BLK_z" "CSV2BLK_ATT")
				'(1 3 3 4)
			)
			(if (not (tblsearch "STYLE" "$CSV2BLK"))
				(entmake
					'(
					(0 . "STYLE")
					(5 . "40")
					(100 . "AcDbSymbolTableRecord")
					(100 . "AcDbTextStyleTableRecord")
					(2 . "$CSV2BLK")
					(70 . 0)
					(40 . 0.0)
					(41 . 1.0)
					(50 . 0.0)
					(71 . 0)
					(42 . 2.5)
					(3 . "arial.ttf")
					(4 . "")
					)
				)
			)
			(if (not (tblsearch "BLOCK" "CSV2BLK"))
				(progn
					(entmake
						'((0 . "BLOCK") (2 . "CSV2BLK") (70 . 2) (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2) (10 0.0 0.0 0.0))
					)
					(setq last_y 0.0 count -1 l_str nil l_mes nil)
					(mapcar
						'(lambda (tag mes / )
							(entmake
								(list
									'(0 . "ATTDEF")
									'(67 . 0)
									'(8 . "0")
									'(62 . 0)
									'(6 . "ByBlock")
									'(370 . -2)
									(cons 10 (list 1.0 last_y 0.0))
									'(40 . 1.0)
									'(1 . "")
									'(50 . 0.0)
									'(41 . 1.0)
									'(51 . 0.0)
									'(7 . "$CSV2BLK")
									'(210 0.0 0.0 1.0)
									(cons 3 mes)
									(cons 2 tag)
									'(70 . 0)
								)
							)
							(setq last_y (+ last_y (- (* inc 2))))
						)
						(append (list "ID-X" "ID-Y" "ID-Z") (reverse (repeat (length l_var) (setq l_str (cons (strcat "DATA" (itoa (setq count (1+ count)))) l_str)))))
						(append (list "Coordinate X: " "Coordinate Y: " "Coordinate Z: ") (repeat (length l_var) (setq l_mes (cons "Data: " l_mes))))
					)
					(entmake
						'(
						(0 . "POINT")
						(67 . 0)
						(8 . "0")
						(62 . 0)
						(6 . "ByBlock")
						(370 . -2)
						(10 0.0 0.0 0.0)
						(210 0.0 0.0 1.0)
						)
					)
					(entmake '((0 . "ENDBLK") (8 . "0") (62 . 0) (6 . "ByBlock") (370 . -2)))
				)
			)
			(initget 2)
			(if (not (setq blk_scl (getreal "\nBlock scale? <1>: "))) (setq blk_scl 1.0))
			(setq f_open (open input "r"))
			(while (setq l_read (read-line f_open))
				(setq
					l_data (str2lst (vl-string-right-trim str_sep l_read) str_sep)
					pt (list (atof (nth x_data l_data)) (atof (nth y_data l_data)) (if z_data (atof (nth z_data l_data)) 0.0))
				)
				(if l_rmv
					(foreach el l_rmv
						(setq l_data
							((lambda (n lst / i rtn)
								(reverse
									(progn
										(setq i -1)
										(foreach x lst
											(if (/= n (setq i (1+ i)))
												(setq rtn (cons x rtn))
											)
										)
										rtn
									)
								)
							)
							el
							l_data
							)
						)
					)
				)
				(setq
					count 0
					l_var nil
				)
				(repeat gab_l
					(set (read (strcat "DATA" (itoa count))) count)
					(setq
						l_var (cons (read (strcat "DATA" (itoa count))) l_var)
						count (1+ count)
					)
				)
				(foreach n l_var
					(set n (nth (eval n) l_data))
				)
				(entmake
					(append
						'(
							(0 . "INSERT")
							(100 . "AcDbEntity")
							(67 . 0)
							(410 . "Model")
							(8 . "CSV2BLK")
							(100 . "AcDbBlockReference")
							(66 . 1)
							(2 . "CSV2BLK")
						)
						(list
							(cons 41 (* 1.0 blk_scl))
							(cons 42 (* 1.0 blk_scl))
							(cons 43 (* 1.0 blk_scl))
						)
						'(
							(50 . 0.0)
							(70 . 0)
							(71 . 0)
							(44 . 0.0)
							(45 . 0.0)
						)
						(list (cons 10 pt) '(210 0.0 0.0 1.0))
					)
				)
				(setq last_y (+ (cadr pt) (* blk_scl (+ inc))) count 0 l_str nil l_mes nil)
				(mapcar
					'(lambda (val tag lay / )
						(entmake
							(append
								(list
									'(0 . "ATTRIB")
									'(100 . "AcDbEntity")
									'(67 . 0)
									'(410 . "Model")
									'(8 . "CSV2BLK_x-y")
									'(100 . "AcDbText")
								)
								(list
									(cons 8 lay)
									(cons 10 (list (+ (car pt) (* blk_scl 1.0)) (setq last_y (+ last_y (* blk_scl (- inc)))) (caddr pt)))
									(cons 1 val)
									(cons 40 (* 1.0 blk_scl))
								)
								(list
									'(50 . 0.0)
									'(41 . 1.0)
									'(51 . 0.0)
									'(7 . "$CSV2BLK")
									'(71 . 0)
									'(72 . 0)
									'(11 0.0 0.0 0.0)
									'(210 0.0 0.0 1.0)
									'(100 . "AcDbAttribute")
								)
								(list (cons 2 tag))
								(list
									'(70 . 0)
									'(73 . 0)
									'(74 . 0)
								)
							)
						)
					)
					(append (list (rtos (car pt) 2) (rtos (cadr pt) 2) (rtos (caddr pt) 2)) (mapcar 'eval (reverse l_var)))
					(append (list "ID-X" "ID-Y" "ID-Z") (reverse (repeat (length l_var) (setq l_str (cons (strcat "DATA" (itoa (setq count (1+ count)))) l_str)))))
					(append (list "CSV2BLK_x-y" "CSV2BLK_x-y" "CSV2BLK_z") (repeat (length l_var) (setq l_mes (cons "CSV2BLK_ATT" l_mes))))
				)
				(entmake '((0 . "SEQEND") (8 . "CSV2BLK") (62 . 0) (6 . "ByBlock") (370 . -2)))
			)
			(close f_open)
		)
		(T (princ "\nNo coordinates introduced, implementation impossible!"))
	)
	(mapcar '(lambda (x) (eval (set x nil))) l_var)
	(prin1)
)