Attribute to CSV

Attribute to CSV

mbelleza
Participant Participant
818 Views
9 Replies
Message 1 of 10

Attribute to CSV

mbelleza
Participant
Participant

Hi guys,

 

I am trying to extract more attributes from the "node" block. 

Node block has a couple other variables that I would like to display in the same fashion.

Right now is only working with Serv_Name, I also need 5 more, if blank then just writes "TBD" on the csv.
How can I achieve this? I am not good when it comes to VLA.

Credits to pEb from the CadTutor forum for most of the code.

 

(defun c:ConnectedTo ( / _First&Second AttbList PlineList PB&PlineList ss ent i typ _rtos _carcadr fn fl ) ;credits to pBe from Cadtutor.net
  (vl-load-com)
  
  (defun _First&Second (lst alst / a b c d)
    (repeat 2
      (setq a (car lst) lst (cdr lst))
      (setq c (cadar (vl-sort
        (mapcar '(lambda (k)
                   (list (distance a (cadr k))
                         k)) alst)
        (function (lambda (p1 p2)
                    (< (car p1) (car p2)))))))
      (setq d (cons (car c) d))
    ) 
  )
  
  (if (setq AttbList nil PlineList nil PB&PlineList nil
            ss (ssget "_X"
                      '((-4 . "<OR")  (-4 . "<AND")
                        (0 . "INSERT")  (2 . "NODE")
                        (-4 . "AND>")  (-4 . "<AND")
                        (0 . "LWPOLYLINE")(8 . "RA*")
                        (-4 . "AND>")
                        (-4 . "OR>")
                        )
                      ))
    (progn
      (repeat (setq i (sslength ss))
        (setq ent (ssname ss (setq i (1- i))))
        (cond
          ((eq (setq typ  (cdr  (assoc  0 (entget  ent))))
                "INSERT")
            (if (setq attval (car (vl-remove-if-not
              '(lambda (j) (eq (vla-get-tagstring j) "Serv_Name"))
              (vlax-invoke (vlax-ename->vla-object ent)
                           'Getattributes))))
              (setq AttbList
                    (cons (list (vla-get-textstring attval)
                                (cdr (assoc 10 (entget  ent))))
                          AttbList))))
          ((and (eq typ "LWPOLYLINE")
                (> (distance (vlax-curve-getStartPoint ent)(vlax-curve-getEndPoint ent)) 0.1))
            (setq PlineList
              (cons (list (vlax-curve-getStartPoint  ent)
                          (vlax-curve-getEndPoint ent)
                          (vlax-curve-getDistAtParam ent
                            (vlax-curve-getEndParam ent)))
                    PlineList))
          )
        )
      )
      (foreach itm PlineList
        (setq PB&PlineList
          (cons (list (_First&Second itm AttbList)
                      (car itm)
                      (cadr itm)
                      (last itm))
                PB&PlineList))
      )
    )
  )
  (princ)

  (setq _rtos (lambda (q) (rtos q 2 16)))
  (setq _carcadr (lambda (x) (list (car x) (cadr x))))
  (if (= (getvar 'Dwgtitled) 1)
      (progn
        (setq fl (strcat (getvar 'Dwgprefix)
                         (cadr (fnsplitl (getvar 'Dwgname)))
                         ".csv"))
        (setq fn (open fl "w"))
        (foreach pline (vl-sort PB&PlineList '(lambda (s1 s2) (< (last s1) (last s2))))
          (setq line (strcat (caar pline)
                             ","
                             (_rtos (last pline))
                             ","
                             (if (eq (caar pline) (cadar pline)) "" (cadar pline))))
          (write-line line fn)
        )
        (close fn)
        (startapp (strcat "explorer /select, "fl", /e"))
      )
  )
  (princ "ConnectedTo function executed successfully.")
)

 

0 Likes
819 Views
9 Replies
Replies (9)
Message 2 of 10

hak_vz
Advisor
Advisor

Search this forum older posts, there are at least 10 solutions provided for attribute extraction.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 3 of 10

miguel.bellezaKN8L2
Explorer
Explorer

Hi @hak_vz. I am a bit unfamiliar with VLA, I was able to modify the code for my use, but I just need more attributes.
I updated the code to select more blocks now, I wanted to show all attributes of each block instead of just one.
I am pretty familiar on how to do it without VLA, but as this code was almost ready for my needs I decided to give it a try. Do you know a good read to learn how to manipulate these variables?

0 Likes
Message 4 of 10

hak_vz
Advisor
Advisor

Check this for a start. I currently have no time to work on it. 

Create selection set of blocks in drawing and use shown functions to extract attribute values. Or create list of block names. Store result in list and export to csv.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 5 of 10

mbelleza
Participant
Participant

Thanks for the reply. I read Lee's website.

I am already creating a selection set of blocks ("ss").The only portion I am struggling a bit to understand is the extraction itself.

The current lines are extracting the attribute CH_COD1 value or textstring and adding it to the AttbList:

 

 

          (if (setq attval (car (vl-remove-if-not '(lambda (j) (eq (vla-get-tagstring j) "CH_COD1")) (vlax-invoke (vlax-ename->vla-object ent) 'Getattributes))))
              (setq AttbList (cons (list (vla-get-textstring attval) (cdr (assoc 10 (entget  ent)))) AttbList))))

 

 

If I wanted to add more attributes to the AttbList, I am assuming I would have to change to mapcar instead of car and change the vl-remove-if-not to look similar to Lee's function.

I tried this but was not successful. Maybe I need to populate AttbList in a different way.

 

Message 6 of 10

komondormrex
Mentor
Mentor

hey,

it is better to build associative list of all block's attribute to then do whatever you want to to any. like this is changing its value. or put it value eg. to csv file... 

 

 

(setq attribute_assoc_list nil)
(foreach attribute 
		(vlax-invoke 
			(vlax-ename->vla-object 
				(car 
					(entsel "\Pick your attributed block: ")
				)
			)
			'getattributes
		)
		(setq attribute_assoc_list (append attribute_assoc_list 
										   (list (cons (vla-get-tagstring attribute) attribute))
								   )
		)
)
(vla-put-textstring (cdr (assoc "CH_COD1" attribute_assoc_list)) "NEW_VALUE")

 

 

Message 7 of 10

pbejse
Mentor
Mentor

@mbelleza wrote:

Hi guys,

 

I am trying to extract more attributes from the "node" block. 

Node block has a couple other variables that I would like to display in the same fashion.

Right now is only working with Serv_Name, I also need 5 more, if blank then just writes "TBD" on the csv.


How can I achieve this? I am not good when it comes to VLA.

 Are you just after the TAG / STRING value of attributes? and the data has nothing to do with WPOLYLINES?

Message 8 of 10

miguel.bellezaKN8L2
Explorer
Explorer

The lisp is creating a csv file with the "Code" attribute of the block where the polyline starts, the polyline (PL) length, and the "Code" attribute of where the PL ends.
Something like this:
Code (PL Start), PL Length, Code (PL End).

 

I wanted to have more attributes instead of just "Code".

I know I need to edit the way I am populating the AttbList and how I am transferring this info to the CSV.

 

I also need to change the way I am filtering the blocks, I use dynamic blocks so I just changed to "NODE,*'U* for now to test. I will change to Effective name later, which I know how to do.

 

I am trying to populate an Excel file that calculates voltage drop (vdrop). I want to be able to export the load (kW) attribute of the Node block as well as a couple other key attributes that are required to calculate the vdrop.

 

(defun c:ConnectedTo ( / _First&Second AttbList PlineList PB&PlineList ss ent i typ _rtos _carcadr fn fl ) ;credits to pBe
  (vl-load-com)
  
  (defun _First&Second (lst alst / a b c d)
    (repeat 2
      (setq a (car lst) lst (cdr lst))
      (setq c (cadar (vl-sort
        (mapcar '(lambda (k)
                   (list (distance a (cadr k))
                         k)) alst)
        (function (lambda (p1 p2)
                    (< (car p1) (car p2)))))))
      (setq d (cons (car c) d))
    ) 
  )
  
  (if (setq AttbList nil PlineList nil PB&PlineList nil
            ss (ssget "_X"
                      '((-4 . "<OR") (-4 . "<AND")
                        (0 . "INSERT") (2 . "NODE,`*U*")
                        (-4 . "AND>") (-4 . "<AND")
                        (0 . "LWPOLYLINE")
                        (-4 . "AND>")
                        (-4 . "OR>")
                        )
                      ))
    (progn
      (repeat (setq i (sslength ss))
        (setq ent (ssname ss (setq i (1- i))))
        (cond
          ((eq (setq typ (cdr (assoc 0 (entget ent))))
                "INSERT")
            (if (setq attval (car (vl-remove-if-not
              '(lambda (j) (eq (vla-get-tagstring j) "CODE"))
              (vlax-invoke (vlax-ename->vla-object ent)
                           'Getattributes))))
              (setq AttbList
                    (cons (list (vla-get-textstring attval)
                                (cdr (assoc 10 (entget ent))))
                          AttbList))))
          ((and (eq typ "LWPOLYLINE")
                (> (distance (vlax-curve-getStartPoint ent)(vlax-curve-getEndPoint ent)) 0.1))
            (setq PlineList
              (cons (list (vlax-curve-getStartPoint ent)
                          (vlax-curve-getEndPoint ent)
                          (vlax-curve-getDistAtParam ent
                            (vlax-curve-getEndParam ent)))
                    PlineList))
          )
        )
      )
      (foreach itm PlineList
        (setq PB&PlineList
          (cons (list (_First&Second itm AttbList)
                      (car itm)
                      (cadr itm)
                      (last itm))
                PB&PlineList))
      )
    )
  )
  (princ)

  (setq _rtos (lambda (q) (rtos q 2 16)))
  (setq _carcadr (lambda (x) (list (car x) (cadr x))))
  (if (= (getvar 'Dwgtitled) 1)
      (progn
        (setq fl (strcat (getvar 'Dwgprefix)
                         (cadr (fnsplitl (getvar 'Dwgname)))
                         ".csv"))
        (setq fn (open fl "w"))
        (foreach pline (vl-sort PB&PlineList '(lambda (s1 s2) (< (last s1) (last s2))))
          (setq line (strcat (caar pline)
                             ","
                             (_rtos (last pline))
                             ","
                             (if (eq (caar pline) (cadar pline)) "" (cadar pline))))
          (write-line line fn)
        )
        (close fn)
        (startapp (strcat "explorer /select, "fl", /e"))
      )
  )
  (princ "ConnectedTo function executed successfully.")
)

 

0 Likes
Message 9 of 10

pbejse
Mentor
Mentor

@miguel.bellezaKN8L2 wrote:

I wanted to have more attributes instead of just "Code".

I know I need to edit the way I am populating the AttbList and how I am transferring this info to the CSV.


Let's say you have 5 different attribute tag/values, how will that look on the csv file? 

What i meant is the if 5 other TAGS you are referring to belongs to the same block . or are you saying depending on a dynamic property , the target would be different? Post a sample drawing, the code you refer to was written a decade ago, perhaps we can build a new one without using VL?

 

Message 10 of 10

miguel.bellezaKN8L2
Explorer
Explorer

Thanks for replying @pbejse ! Are you the same pBe from CadTutor?!

 

I would like to see the attributes before the "from,distance,to".

Something like this:

 

STR_NAME, ATT1.textstring, ATT2.textstring, ...

STR_NAME, ATT1.textstring, ATT2.textstring, ...
####################################

STR_NAME,DISTANCE,STR_NAME

STR_NAME,DISTANCE,STR_NAME

...

 

I will manipulate all the data in excel later with VBA.

I will create a new command to import the values from Excel back to the dynamic blocks. I know how to do this part.

 

0 Likes