Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Multiple csv files from attributes

msmith_ncl
Enthusiast

Multiple csv files from attributes

msmith_ncl
Enthusiast
Enthusiast

Hope someone can help or point me in the right direction.  I need to create 3 different csv files from specific attributes selected on screen.  I would like 3 different csv files created in a specific folder with the same prefix on each filename - user prompted for file prefix.  Each csv file needs certain attributes, some are needed in all 3 csv files and others in only 1.   I tried using ATTEXT and this works ok using templates for each different csv, the problem is I need column headers in the csv files and couldn't work this out, I can do everything needed with EATTEXT but I'm hoping to find a way of creating all 3 files in 1 command as this is a task we are repeating multiple times every day in different drawings.  I've had a look at a few different lisp routines for exporting attributes to different formats and couldn't find anything suitable.  I have attached a sample drawing with some blocks and an excel with 3 tabs being the 3 different csv files I'm trying to get, sorted in the correct order, any help would be appreciated.

0 Likes
Reply
Accepted solutions (3)
2,627 Views
27 Replies
Replies (27)

pbejse
Mentor
Mentor
Accepted solution

@msmith_ncl wrote:

I've had a look at a few different lisp routines for exporting attributes to different formats and couldn't find anything suitable.  


Try this then [ change the block1 to the actual block name ]

 

(Defun c:TripleCSV ( / _comma data ss i folder opf csvfile)
;;		pBe Nov 2020		;;;;
(setq _comma (lambda (lst)(substr
	       (apply 'strcat
		      (mapcar '(lambda (str)
				 (strcat  "," str) ) lst)
		      ) 2
	       ) 
	     )
	)
(if
  (and
	(setq data nil
	   ss (ssget '((0 . "INSERT")(66 . 1)(2 . "block1"))))
		(repeat (setq i (sslength ss))
		    (setq data (cons
				 (mapcar '(lambda (atb)
					    (list (vla-get-tagstring atb)
						  (Vla-get-textstring atb)))
					 (Vlax-invoke
					   (vlax-ename->vla-object
					     (ssname ss (setq i (1- i)))
					   )
					   'GetAttributes
					 )
				 )
				 data
			       )
		    ) data
		  )
		(setq data (vl-sort	data
				'(lambda (n m)
				   (< (cadr (assoc "DEVICE_NUMBER" n))
				      (cadr (assoc "DEVICE_NUMBER" m))
				   )
				 )
		       )
		)
    (setq folder (acet-ui-pickdir (Getvar 'dwgprefix)))
	)
	
	(foreach itm  '(("PREFIX_Devices"
			 	("DEVICE_NUMBER" "DEVICE_TYPE" "PANEL_NUMBER" "PORT_NUMBER" ))
			("PREFIX_Inputs"
			 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "INPUT_NUMBER" "INPUT_TYPE" ))
			("PREFIX_Outputs"
			 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "OUTPUT_NUMBER" "OUTPUT_TYPE" ))
			)
		
	  (setq opf (open (setq csvfile (strcat folder "\\" (Car itm) ".csv")) "w"))
	  (write-line (_comma (setq taglst (Cadr itm))) opf)
		(Foreach val data
		  (write-line
		  (_comma (mapcar '(lambda (v)
			     (cadr (assoc v val))) taglst)) opf)
		  )
	  (close opf)
	  (startapp "explorer" csvfile)
	  )
    )
  (princ)
  )

The CSV filename on selected folder 

Tested on posted drawing [ Device Blocks.dwg ]

HTH

 

msmith_ncl
Enthusiast
Enthusiast

Many thanks, that's exactly what I needed, much appreciated, only 1 thing that would make it more perfect is if the user could be prompted for a reference number  - AP123456 or similar and this would be used as the prefix for all 3 csv filenames

0 Likes

pbejse
Mentor
Mentor

@msmith_ncl wrote:

Many thanks, that's exactly what I needed, much appreciated, only 1 thing that would make it more perfect is if the user could be prompted for a reference number  - AP123456 or similar and this would be used as the prefix for all 3 csv filenames


You are welcome @msmith_ncl 

 

Here's an idea, I'm not really a big fan of "typing" values., if the "reference number" is part of name of the folder you select to save the files , we can just grab it from there?

 

Hows' that sound? if that is not possble then we will add the prompy for prefix.

 

 

 

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

I would prefer prompt, the DWG files are in subfolders called 'plans' with the ref number in a parent folder name and not always the same number of subfolders so can't use that.  Thanks

0 Likes

pbejse
Mentor
Mentor
Accepted solution

@msmith_ncl wrote:

I would prefer prompt, 


HYG

(Defun c:TripleCSV ( / _comma data ss i folder opf csvfile)
;;		pBe Nov 2020		;;;;
(setq _comma (lambda (lst)(substr
	       (apply 'strcat
		      (mapcar '(lambda (str)
				 (strcat  "," str) ) lst)
		      ) 2
	       ) 
	     )
	)
(if
  (and
        (setq ReferenceNumber (strcase (getstring "\nEnter Reference Number: ")))
	(snvalid  ReferenceNumber )
	(setq data nil
	   ss (ssget '((0 . "INSERT")(66 . 1)(2 . "block1"))))
		(repeat (setq i (sslength ss))
		    (setq data (cons
				 (mapcar '(lambda (atb)
					    (list (vla-get-tagstring atb)
						  (Vla-get-textstring atb)))
					 (Vlax-invoke
					   (vlax-ename->vla-object
					     (ssname ss (setq i (1- i)))
					   )
					   'GetAttributes
					 )
				 )
				 data
			       )
		    ) data
		  )
		(setq data (vl-sort	data
				'(lambda (n m)
				   (< (cadr (assoc "DEVICE_NUMBER" n))
				      (cadr (assoc "DEVICE_NUMBER" m))
				   )
				 )
		       )
		)
    (setq folder (acet-ui-pickdir (Getvar 'dwgprefix)))
	)
	
(foreach itm  '(("_Devices"
		 	("DEVICE_NUMBER" "DEVICE_TYPE" "PANEL_NUMBER" "PORT_NUMBER" ))
		("_Inputs"
		 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "INPUT_NUMBER" "INPUT_TYPE" ))
		("_Outputs"
		 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "OUTPUT_NUMBER" "OUTPUT_TYPE" ))
		)
	
  (setq opf (open (setq csvfile (strcat folder "\\" ReferenceNumber (Car itm) ".csv")) "w"))
  (write-line (_comma (setq taglst (Cadr itm))) opf)
	(Foreach val data
	  (write-line
	  (_comma (mapcar '(lambda (v)
		     (cadr (assoc v val))) taglst)) opf)
	  )
  (close opf)
  (startapp "explorer" csvfile)
  )
    )
  (princ)
  )

 

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

Many thanks, this is perfect

0 Likes

msmith_ncl
Enthusiast
Enthusiast

Hi

 

I've been using the tool with great success and now looking to change our blocks to be dynamic with different attributes visible in different states, the downside being any attribute that is not visible is still included in the csv.  Is it an easy fix to only export attributes depending on their visibility state?  I had a look but couldn't work it out, also hit problems with the selection set not grabbing anonymous blocks when their state changes and they have "*U###" reference, I think I've found a fix for this but it's probably very messy, I removed all filters from the ssget and had the devices I need on the only active layer, I was looking if these could be selected with the attribute tagname but couldn't find anything.  I have attached a new detail with dynamic version of the block.  Any help or advice you can give is much appreciated.  Thanks.

0 Likes

pbejse
Mentor
Mentor

@msmith_ncl wrote:

 

..Is it an easy fix to only export attributes depending on their visibility state? 

 Yes

 


@msmith_ncl wrote:

  I have attached a new detail with dynamic version of the block.  Any help or advice you can give is much appreciated.  Thanks.


Will this be just for this block? any other block you are planning to use it for?

Also, is it always just three of this blocks on the drawing? or more<--- and if it is then how would the result look like on the csv file?

 

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

I might add more blocks or more possibilities in the visibility states, not sure yet, there will always be an ID attribute tag called DEVICE_NUMBER and maybe another block with PANEL_NUMBER attribute.  The CSV files wont change much, maybe some adjustments to which attribute lands in each file.  Thanks.

0 Likes

pbejse
Mentor
Mentor

@msmith_ncl wrote:

I might add more blocks or more possibilities in the visibility states, not sure yet, there will always be an ID attribute tag called DEVICE_NUMBER and maybe another block with PANEL_NUMBER attribute.  The CSV files wont change much, maybe some adjustments to which attribute lands in each file.  Thanks.


Try this. 

 

(Defun c:TripleCSVD ( / _comma _Visible data ss i ev dp attb a b c folder opf csvfile)
;;		pBe Nov 2020		;;;;
(setq _comma (lambda (lst)(substr
	       (apply 'strcat
		      (mapcar '(lambda (str)
				 (strcat  "," str) ) lst)
		      ) 2
	       ) 
	     )
	)
  (defun _Visible (l) (Vl-remove-if '(lambda (atv)
		   (zerop (car atv))) l))
  (and
        (setq ReferenceNumber (strcase (getstring "\nEnter Reference Number: ")))
	(snvalid  ReferenceNumber )
	(setq data nil
	   ss (ssget '((0 . "INSERT")(66 . 1))))
	(repeat (setq i (sslength ss))
	  (setq ev (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
	  (if (and
		  (setq vp (Vl-some '(lambda (dy)
				       (if (eq  (Vlax-get dy 'PropertyName) "Lookup1")
					 (Vlax-get dy 'Value)))
				       (Vlax-invoke ev 'GetDynamicBlockProperties)))
		  (setq attb (mapcar '(lambda (atb)
					    (list (vlax-get atb 'Visible )(vla-get-tagstring atb)
						  (Vla-get-textstring atb)))
					 (Vlax-invoke ev 'GetAttributes)
				 )
			)
		    )
		  (setq data (cons (list vp (mapcar 'cdr (_Visible attb))) data ))
		  )
	  )
    	(setq folder (acet-ui-pickdir (Getvar 'dwgprefix)))
	(setq data  (Vl-sort data '(lambda (a b)
				     (Cond
				       ((< (car a)(Car b)))
				       ((= (car a)(Car b))(< (cadr (caadr a))(cadr (caadr b)))))))
	)
  	(while (setq a (Car data))
	    	(setq opf (open (setq csvfile (strcat folder "\\" ReferenceNumber "_" (Car a) ".csv")) "w"))   
	    	(write-line (_comma (mapcar 'car (Cadr a))) opf)
	    		(while (eq (car (setq c (car data))) (Car a))
			  	(write-line (_comma (mapcar 'cadr (Cadr c))) opf)
			  	(setq data (cdr data)))
	    	(Close opf)
	        (startapp "explorer" csvfile)
	    )
	)
(princ)
  )

 

 HTH

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

Thanks for this, only 1 thing, I would still want all blocks to export into all 3 files in a similar way to how it worked before with each file listed in the LSP with the relevant attributes instead of each block name having a file so it will be possible to modify / add attributes to these files if we have new devices in the future that need this.  Many thanks.

0 Likes

pbejse
Mentor
Mentor
Accepted solution
(Defun c:TripleCSVD ( / _comma _Visible data ss i ev dp attb a b c folder opf csvfile)
;;		pBe Nov 2020		;;;;
(setq _comma (lambda (lst)(substr
	       (apply 'strcat
		      (mapcar '(lambda (str)
				 (strcat  "," str) ) lst)
		      ) 2
	       ) 
	     )
	)
  (defun _Visible (l) (Vl-remove-if '(lambda (atv)
		   (zerop (car atv))) l))
  (and
        (setq ReferenceNumber (strcase (getstring "\nEnter Reference Number: ")))
	(snvalid  ReferenceNumber )
	(setq data nil
	   ss (ssget '((0 . "INSERT")(66 . 1))))
	(repeat (setq i (sslength ss))
	  (setq ev (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
	  (if (and
		  (setq vp (Vl-some '(lambda (dy)
				       (if (eq  (Vlax-get dy 'PropertyName) "Lookup1")
					 (Vlax-get dy 'Value)))
				       (Vlax-invoke ev 'GetDynamicBlockProperties)))
		  (setq attb (mapcar '(lambda (atb)
					    (list (vlax-get atb 'Visible )(vla-get-tagstring atb)
						  (Vla-get-textstring atb)))
					 (Vlax-invoke ev 'GetAttributes)
				 )
			)
		    )
		  (setq data (cons (mapcar 'cdr (_Visible attb)) data ))
		  )
	  )
    	(setq folder (acet-ui-pickdir (Getvar 'dwgprefix)))
	(setq data (vl-sort	data
				'(lambda (n m)
				   (< (cadr (assoc "DEVICE_NUMBER" n))
				      (cadr (assoc "DEVICE_NUMBER" m))
				   )
				 )
		       )
		)

(foreach itm  '(("_Devices"
	 	("DEVICE_NUMBER" "DEVICE_TYPE" "PANEL_NUMBER" "PORT_NUMBER" ))
	("_Inputs"
	 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "INPUT_NUMBER" "INPUT_TYPE" ))
	("_Outputs"
	 	("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "OUTPUT_NUMBER" "OUTPUT_TYPE" ))
	)	
  	(setq opf (open (setq csvfile (strcat folder "\\" ReferenceNumber (Car itm) ".csv")) "w"))
	  (write-line (_comma (setq taglst (Cadr itm))) opf)
		(Foreach val data
		  (if (vl-every '(lambda (j)(assoc j val)) (Cadr itm))
		  (write-line
		  (_comma (mapcar '(lambda (v)
			     (cadr (assoc v val))) taglst)) opf)
		    )
		  )
 
  	(close opf)
  (startapp "explorer" csvfile)
  )
	)
(princ)
  )
0 Likes

Moshe-A
Mentor
Mentor

Mike,

 

For the last 2 weeks i been taken your thread to a very high level base on OpenDCL (see pic)

if you interested, reply here.

 

Moshe

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

This works well, many thanks for all your help

0 Likes

msmith_ncl
Enthusiast
Enthusiast

Hi

 

Thanks for looking at this, I had a look at the image, looks very useful, I'd be very interested in looking at this.

 

Thanks

0 Likes

Moshe-A
Mentor
Mentor

@msmith_ncl ,

 

i'm now at work, i will send it to you in about 6 hours from now.

 

 

0 Likes

Moshe-A
Mentor
Mentor

@msmith_ncl ,

 

check your private email on this forum.

 

 

0 Likes

msmith_ncl
Enthusiast
Enthusiast

Hoping someone can help with a small change to the attached.  Drawing has 3 blocks inserted with attributes turned on or off with visibility states.

Lisp is currently ignoring blocks when attributes are not visible, I need all blocks to export with blank cells for any attributes not currently visible, they are being ignored and not included in the csv.  Also attached a current CSV export and a CSV showing what I need exporting.  Thanks.

 

(Defun c:TripleCSV ( / _comma _Visible data ss i ev dp attb a b c folder opf csvfile)
(setq _comma (lambda (lst)(substr
(apply 'strcat
(mapcar '(lambda (str)
(strcat "," str) ) lst)
) 2
)
)
)
(defun _Visible (l) (Vl-remove-if '(lambda (atv)
(zerop (car atv))) l))
(and
(setq ReferenceNumber (strcase (getstring "\nEnter Reference Number: ")))
(snvalid ReferenceNumber )
(setq data nil
ss (ssget '((0 . "INSERT")(66 . 1))))
(repeat (setq i (sslength ss))
(setq ev (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
(if (and
(setq vp (Vl-some '(lambda (dy)
(if (eq (Vlax-get dy 'PropertyName) "Lookup1")
(Vlax-get dy 'Value)))
(Vlax-invoke ev 'GetDynamicBlockProperties)))
(setq attb (mapcar '(lambda (atb)
(list (vlax-get atb 'Visible )(vla-get-tagstring atb)
(Vla-get-textstring atb)))
(Vlax-invoke ev 'GetAttributes)
)
)
)
(setq data (cons (mapcar 'cdr (_Visible attb)) data ))
)
)
(setq folder (acet-ui-pickdir (Getvar 'dwgprefix)))
(setq data (vl-sort data
'(lambda (n m)
(< (cadr (assoc "ID_TAG" n))
(cadr (assoc "ID_TAG" m))
)
)
)
)

(foreach itm '(("_Devices"
("DEVICE_NUMBER" "DEVICE_TYPE" "PANEL_NUMBER" "PORT_NUMBER" "INPUT_NUMBER" "INPUT_TYPE" "OUTPUT_NUMBER" "OUTPUT_TYPE" ))
("_Inputs"
("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "INPUT_NUMBER" "INPUT_TYPE" ))
("_Outputs"
("DEVICE_NUMBER" "PANEL_NUMBER" "PORT_NUMBER" "OUTPUT_NUMBER" "OUTPUT_TYPE" ))
)

(setq opf (open (setq csvfile (strcat folder "\\" ReferenceNumber (Car itm) ".csv")) "w"))
(write-line (_comma (setq taglst (Cadr itm))) opf)
(Foreach val data
(if (vl-every '(lambda (j)(assoc j val)) (Cadr itm))
(write-line
(_comma (mapcar '(lambda (v)
(cadr (assoc v val))) taglst)) opf)
)
)

(close opf)
(startapp "explorer" csvfile)
)
)
(princ)
)

0 Likes

mail2kaleb
Explorer
Explorer
hallo Mosch, I am also interest me too this program, maybe you can send me the download link. thanks in advance
0 Likes