LIST command addition

LIST command addition

barry2104
Collaborator Collaborator
2,615 Views
23 Replies
Message 1 of 24

LIST command addition

barry2104
Collaborator
Collaborator

I have a polyline with say 100 nodes along the way, running in the direction it wants to. I want to spit out a coordinates list for each node (which is what the command LIST is good for), but on top of this, I want an extra column/Output at each node for the chainage along the way. So say for example each node is 3 metres after the previous node, the first Outputs would read:

            At Point X=(x-coordinate)   Y=(y-coordinate)   C=0.000

            At Point X=(x-coordinate)   Y=(y-coordinate)   C=3.000

            At Point X=(x-coordinate)   Y=(y-coordinate)   C=6.000

            At Point X=(x-coordinate)   Y=(y-coordinate)   C=9.000

...and so on

I don't care what the chainage is called (in the example above I called it "C"), nor whether this is before or after the X/Y coordinates.

Does anyone know how this can be done?

If via Lisp, then perhaps the output can be even more simplified to save cleaning up in Excel (removing the "At Point X=" etc from the cells) after reading out:

            (x-coordinate), (y-coordinate), (Chainage) 

Running AutoCAD Architecture 2020, in German
0 Likes
Accepted solutions (2)
2,616 Views
23 Replies
Replies (23)
Message 2 of 24

pbejse
Mentor
Mentor

@barry2104 wrote:

I have a polyline with say 100 nodes along the way, running in the direction it wants to. I want to spit out...

            (x-coordinate), (y-coordinate), (Chainage) 


 

(defun c:demo ( / LM:open ss csvfile e ent points chainage filetowrite)
  
;; pBe May 2018
  
;; Open  -  Lee Mac
;; A wrapper for the 'Open' method of the Shell Object
;; target - [int/str] File, folder or ShellSpecialFolderConstants enum
  
(defun LM:open ( target / rtn shl )
    (if (and (or (= 'int (type target)) (setq target (findfile target)))
             (setq shl (vla-getinterfaceobject (vlax-get-acad-object) "shell.application"))
        )
        (progn
            (setq rtn (vl-catch-all-apply 'vlax-invoke (list shl 'open target)))
            (vlax-release-object shl)
            (if (vl-catch-all-error-p rtn)
                (prompt (vl-catch-all-error-message rtn))
                t
            )
        )
    )
)
  
  (if (and
	(setq ss (ssget "_+.:S:E" '((0 . "LWPOLYLINE"))))
	(setq csvfile (getfiled "Enter CSV file name" (getvar 'dwgprefix) "CSV" 1))
	)
    
    (progn
	(setq ent (entget (setq e (ssname ss 0))))
	(setq points (mapcar 'cdr 
	     (vl-remove-if-not '(lambda (j)(= (Car j) 10)) ent)))

	(setq chainage (mapcar '(lambda (d)
				(vlax-curve-getDistAtPoint e d)) points))
	(setq filetowrite (open csvfile "w"))
	(while (and
	       (setq pts (Car points))
	       (setq chain (Car chainage))
	       )
	(write-line (strcat (rtos (car pts) 2) ","
			    (rtos (cadr pts) 2) ","
			    (rtos chain 2)) filetowrite)
	(setq points (Cdr points) chainage (Cdr chainage)))
	(close filetowrite)
        (LM:OPEN csvfile)
		)
    	)
  (princ)
  )

HTH

 

0 Likes
Message 3 of 24

john.uhden
Mentor
Mentor
Accepted solution

Here's one version that may be helpful.

Note that it is set up to report chainages in a metric format (C=x+xxx.xxx) though you can find the place where to change that if you wish.

 

(defun c:PChain ( / *error*  vars vals e etype p param d chainage @FormatSta)
   ;; (c) 2018, John F. Uhden
   ;; Program reports the coordinates and chainage of polyline vertices.
   (defun *error* (error)
     (mapcar 'setvar vars vals)
     (vla-endundomark *doc*)
     (cond
       ((not error))
       ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
       (1 (princ (strcat "\nERROR: " error)))
     )
     (princ)
   )
   (setq Mspace (vlax-get (vlax-get (vlax-get-acad-object) 'Activedocument) 'Modelspace))
   (setq vars '(cmdecho dimzin))
   (setq vals (mapcar 'getvar vars))
   (or *acad* (setq *acad* (vlax-get-acad-object)))
   (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
   (vla-endundomark *doc*)
   (vla-startundomark *doc*)
   (mapcar 'setvar vars '(0 0))
   (command "_.expert" (getvar "expert")) ;; dummy command
   (defun @FormatSta (sta xp prec / n sign str)
     ;; where:
     ;;  sta = real or integer
     ;;  xp = exponent of 10 to specify how many numeric charcters between "+" and "."
     ;;  prec = decimal precision
     (setq n (expt 10.0 xp))
     (setq sign (if (minusp sta) "-" ""))
     (setq sta (abs sta))
     (setq str1 (strcat sign (itoa (fix (/ sta n))) "+"))
     (setq str2 (rtos (* n (rem (/ sta n) 1)) 2 prec))
     (repeat (max (- xp (strlen str2))(- xp (vl-string-position 46 str2)))
       (setq str2 (strcat "0" str2))
     )
     (strcat str1 str2)
   )
   (while (setq e (car (entsel "\nSelect a polyline: ")))
     (and
       (setq etype (cdr (assoc 0 (entget e))))
       (or (= etype "LWPOLYLINE")(prompt (strcat "\nObject selected is a(n) " etype)))
       (princ "\n")
       (setq param 0)
       (setq end (vlax-curve-getendparam e))
       (while (<= param end)
         (setq p (vlax-curve-getpointatparam e param))
         (setq d (vlax-curve-getdistatparam e param))
         (setq chainage (strcat "C=" (@formatsta d 3 3)))
         (write-line (strcat (rtos (car p) 2 4) "," (rtos (cadr p) 2 4) "," chainage))
         (setq param (1+ param))
       )
     )
   )
   (*error* nil)
 )
  

John F. Uhden

0 Likes
Message 4 of 24

barry2104
Collaborator
Collaborator

great, just what I was looking for, thanks!!

Running AutoCAD Architecture 2020, in German
0 Likes
Message 5 of 24

barry2104
Collaborator
Collaborator

actually one more Thing...

I work in Germany and the Germans use commas for decimals, and decimals for thousand-Separators. Therefore, when I plug the Output into Excel and convert to columns, the decimal gets recognised here as a thousand-separator which blows out the coordinates and chainage. Obviously I can do a quick find/replace before Splitting the Output to designated columns, but if this conversion can get worked into the code so that the decimal Point is replaced with a comma, that would save me more time.

 

PS: because of this, I've managed to alter the code to put in semicolons instead of commas between the X and Y and C Outputs, and also removed the "C=" from the Output so that it now Outputs as

5411189.6113;5660440.9632;0002.052

It's just those decimals I want to replace with commas now

Running AutoCAD Architecture 2020, in German
0 Likes
Message 6 of 24

pbejse
Mentor
Mentor
Have you tried the code at post#2 ?
It opens the file in excel or notepad .

Change the "," to ";" and later i'll update the code to replace the decimals to comma
0 Likes
Message 7 of 24

barry2104
Collaborator
Collaborator

I did try this, but this was not quite so flexible as I didn't want to have to deal with saving 10 separate files for 10 different alignments and then copying/pasting those 10 into a single document.

It's easier to just select the 10 polylines one after another, then copy the Output directly from the command line into Excel - I have the command-line-breaks between the polylines as a guide/separator.

Perhaps your edit for ,/. can be used in the 2nd code though?

Running AutoCAD Architecture 2020, in German
0 Likes
Message 8 of 24

john.uhden
Mentor
Mentor

This should give semicolons as separators and commas in place of decimals...

 

(defun c:PChain ( / *error*  vars vals e etype p param d chainage @FormatSta @comma)
   ;; (c) 2018, John F. Uhden
   ;; Program reports the coordinates and chainage of polyline vertices.
   (defun *error* (error)
     (mapcar 'setvar vars vals)
     (vla-endundomark *doc*)
     (cond
       ((not error))
       ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
       (1 (princ (strcat "\nERROR: " error)))
     )
     (princ)
   )
   (setq Mspace (vlax-get (vlax-get (vlax-get-acad-object) 'Activedocument) 'Modelspace))
   (setq vars '(cmdecho dimzin))
   (setq vals (mapcar 'getvar vars))
   (or *acad* (setq *acad* (vlax-get-acad-object)))
   (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
   (vla-endundomark *doc*)
   (vla-startundomark *doc*)
   (mapcar 'setvar vars '(0 0))
   (command "_.expert" (getvar "expert")) ;; dummy command
   (defun @FormatSta (sta xp prec / n sign str)
     ;; where:
     ;;  sta = real or integer
     ;;  xp = exponent of 10 to specify how many numeric charcters between "+" and "."
     ;;  prec = decimal precision
     (setq n (expt 10.0 xp))
     (setq sign (if (minusp sta) "-" ""))
     (setq sta (abs sta))
     (setq str1 (strcat sign (itoa (fix (/ sta n))) "+"))
     (setq str2 (rtos (* n (rem (/ sta n) 1)) 2 prec))
     (repeat (max (- xp (strlen str2))(- xp (vl-string-position 46 str2)))
       (setq str2 (strcat "0" str2))
     )
     (strcat str1 str2)
   )
   (defun @comma (#)
     (vl-string-subst "," "." (rtos # 2 3))
   )
   (while (setq e (car (entsel "\nSelect a polyline: ")))
     (and
       (setq etype (cdr (assoc 0 (entget e))))
       (or (= etype "LWPOLYLINE")(prompt (strcat "\nObject selected is a(n) " etype)))
       (princ "\n")
       (setq param 0)
       (setq end (vlax-curve-getendparam e))
       (while (<= param end)
         (setq p (vlax-curve-getpointatparam e param))
         (setq d (vlax-curve-getdistatparam e param))
       ;;  (setq chainage (strcat "C=" (@formatsta d 3 3)))
         (setq chainage (@comma d))
         (write-line (strcat (rtos (car p) 2 4) ";" (rtos (cadr p) 2 4) ";" chainage))
         (setq param (1+ param))
       )
     )
   )
   (*error* nil)
 )
  

John F. Uhden

0 Likes
Message 9 of 24

barry2104
Collaborator
Collaborator

...for the chainages, yes, that worked. But the coordinates are still with decimals rather than commas

 

5411105.1608;5660497.8943;5,571

Running AutoCAD Architecture 2020, in German
0 Likes
Message 10 of 24

pbejse
Mentor
Mentor

@barry2104 wrote:

 

Perhaps your edit for ,/. can be used in the 2nd code though?


(defun c:demo ( / LM:open ss csvfile e ent points chainage filetowrite AllData) 
(defun _rtosToComma (n)
    	(vl-string-subst "," "." (rtos n 2 4)))  
  
;; pBe May 2018  

  (if (and
	(setq AllData nil
	      ss (ssget  '((0 . "LWPOLYLINE"))))
	(setq csvfile (getfiled "Enter CSV file name"
				(strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)))   "CSV" 1))
	)
    
    (progn
      (repeat (setq i (sslength ss))
	(setq ent (entget (setq e (ssname ss (setq i (1- i))))))
	(setq points (mapcar 'cdr 
	     (vl-remove-if-not '(lambda (j)(= (Car j) 10)) ent)))

	(setq chainage (mapcar '(lambda (d)
				(vlax-curve-getDistAtPoint e d)) points))
	
	(setq AllData (cons (list points chainage)  AllData))
	)

	(setq filetowrite (open csvfile "w"))	  
	(foreach itm AllData
		(setq points 	(Car itm)
		      chainage	(Cadr itm))			
			(while (and
			       (setq pts (Car points))
			       (setq chain (Car chainage))
			       )
				(write-line (strcat (_rtosToComma (car pts)) ";"
						    (_rtosToComma (cadr pts)) ";"
						    (_rtosToComma chain)) filetowrite)
				(setq points (Cdr points) chainage (Cdr chainage)))
	  		(write-line "" filetowrite))			  		
	(close filetowrite)
        (startapp "Notepad" csvfile)
		)
    	)
  (princ)
  )

 

We can write a more complex code to open an excel file with 3 columns

 

 

 

 

0 Likes
Message 11 of 24

john.uhden
Mentor
Mentor
Accepted solution

That was stupid of me, but an easy fix...

 

(defun c:PChain ( / *error*  vars vals e etype p param d chainage @FormatSta @comma)
   ;; (c) 2018, John F. Uhden
   ;; Program reports the coordinates and chainage of polyline vertices.
   (defun *error* (error)
     (mapcar 'setvar vars vals)
     (vla-endundomark *doc*)
     (cond
       ((not error))
       ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
       (1 (princ (strcat "\nERROR: " error)))
     )
     (princ)
   )
   (setq Mspace (vlax-get (vlax-get (vlax-get-acad-object) 'Activedocument) 'Modelspace))
   (setq vars '(cmdecho dimzin))
   (setq vals (mapcar 'getvar vars))
   (or *acad* (setq *acad* (vlax-get-acad-object)))
   (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
   (vla-endundomark *doc*)
   (vla-startundomark *doc*)
   (mapcar 'setvar vars '(0 0))
   (command "_.expert" (getvar "expert")) ;; dummy command
   (defun @FormatSta (sta xp prec / n sign str)
     ;; where:
     ;;  sta = real or integer
     ;;  xp = exponent of 10 to specify how many numeric charcters between "+" and "."
     ;;  prec = decimal precision
     (setq n (expt 10.0 xp))
     (setq sign (if (minusp sta) "-" ""))
     (setq sta (abs sta))
     (setq str1 (strcat sign (itoa (fix (/ sta n))) "+"))
     (setq str2 (rtos (* n (rem (/ sta n) 1)) 2 prec))
     (repeat (max (- xp (strlen str2))(- xp (vl-string-position 46 str2)))
       (setq str2 (strcat "0" str2))
     )
     (strcat str1 str2)
   )
   (defun @comma (# prec)
     (vl-string-subst "," "." (rtos # 2 prec))
   )
   (while (setq e (car (entsel "\nSelect a polyline: ")))
     (and
       (setq etype (cdr (assoc 0 (entget e))))
       (or (= etype "LWPOLYLINE")(prompt (strcat "\nObject selected is a(n) " etype)))
       (princ "\n")
       (setq param 0)
       (setq end (vlax-curve-getendparam e))
       (while (<= param end)
         (setq p (vlax-curve-getpointatparam e param))
         (setq d (vlax-curve-getdistatparam e param))
       ;;  (setq chainage (strcat "C=" (@formatsta d 3 3)))
         (setq chainage (@comma d 3))
         (write-line (strcat (@comma (car p) 4) ";" (@comma (cadr p) 4) ";" chainage))
         (setq param (1+ param))
       )
     )
   )
   (*error* nil)
 )
  

John F. Uhden

0 Likes
Message 12 of 24

barry2104
Collaborator
Collaborator

Hello

This lisp worked great back in 2018-2019, but I now get the following error:

 

Object selected is a(n) POLYLINE

Select a polyline:

ERROR: no function definition: VLAX-CURVE-GETENDPARAM

 

Does anyone know how to fix this? I'm now running AutoCAD Architecture 2020, so it might be because of that upgrade.

 

Ideally the code could be amended to also include „copy output to clipboard“ to save me selecting the output rows from the command bar and pressing CTRL+C

 

Thanks!

 

 

EDIT:

it looks like windows explorer has changed my white & red .lsp file thumbnails (like the example below) to a light blue notepad thumbnail. After checking a few other lisps, I get the same vlax error.

I just don't know how to "undo" this so i get the old thumbnail back. Windows now automatically opens my .lsp files in notepad (without asking which program to open it with)

barry2104_1-1595401455417.png

 

 


Running AutoCAD Architecture 2020, in German
0 Likes
Message 13 of 24

john.uhden
Mentor
Mentor
It was written to handle only LWPOLYLINEs.
As to the getendparam not working, add the line
(vl-load-com)
before the line
(defun *error* (error)

As to copying to the clipboard, I found this online at TheSwamp.org
contributed by @patrick_35 to Bull Frog:
(defun GetClipText(/ html result)
(setq html (vlax-create-object "htmlfile")
result (vlax-invoke (vlax-get (vlax-get html 'ParentWindow) 'ClipBoardData)
'GetData "Text")
)
(vlax-release-object html)
result
)
I tested it myself and it works, but it seemed to grab only the latest
lines of text, not the whole textscreen. You could also try DOSLIB; it's
free thanks to Dale Fugier of McNeel.

John F. Uhden

0 Likes
Message 14 of 24

barry2104
Collaborator
Collaborator

thanks for the prompt reply, however the extra line of code does not seem to do the trick - I still get the same error output
ERROR: no function definition: VLAX-CURVE-GETENDPARAM

I have a feeling it's actually to do with the lisp (.lsp) files being recognised as .txt files (even though the filetype is still .lsp, the icon for the file type has changed to that of a text file, as I wrote above in my Edit)

 

Do you happen to know how to revert back to have windows recognise this as a .lsp file type rather than a .txt?

Running AutoCAD Architecture 2020, in German
0 Likes
Message 15 of 24

Kent1Cooper
Consultant
Consultant

@barry2104 wrote:

.... the extra line of code does not seem to do the trick - I still get the same error output
ERROR: no function definition: VLAX-CURVE-GETENDPARAM

I have a feeling it's actually to do with the lisp (.lsp) files being recognised as .txt files ....


I don't think that error message can be related to the .lsp-vs.-.txt issue.  You wouldn't get that message at all except by running some AutoLisp routine, which must mean they're loading.

 

If you have (vl-load-com) incorporated, but you still get that error message, for possible causes/solutions check out >this recent thread<.

Kent Cooper, AIA
0 Likes
Message 16 of 24

barry2104
Collaborator
Collaborator

Thanks. Registry Hacks are about on the edge of my comfortable computer knowledge...

After searching for the mentioned path, I find that I don't have a folder starting with {A4081.....

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0]
@="Visual Lisp ActiveX module"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0\win32]
@="C:\\Program Files\\Autodesk\\AutoCAD 2016\\vl16.tlb"

I'm running Architecture 2020 - is that why?

Can I download the .zip file from Message 12 of 20 in that thread and simply drag that .reg file into my registry editor somewhere and hey presto? 

Running AutoCAD Architecture 2020, in German
0 Likes
Message 17 of 24

Kent1Cooper
Consultant
Consultant

@barry2104 wrote:

Thanks. Registry Hacks are about on the edge of my comfortable computer knowledge...

....

Can I download the .zip file from Message 12 of 20 in that thread and simply drag that .reg file into my registry editor somewhere and hey presto? 


They're beyond  the edge of mine....  I just knew there had been a thread on the topic recently, but you'd be better off contacting those who were involved in that part of the discussion.

Kent Cooper, AIA
0 Likes
Message 18 of 24

barry2104
Collaborator
Collaborator

so harking back to this lisp - it works just as I want it to, spitting out the x-coord;y-coord;chainage characteristics of a polyline.

Which extra line of code would I need to amend to the lisp in order to have it automatically copy the output/list to my clipboard? (and where to insert said extra line of code?)

 

2) a similar lisp would be also needed soon, which spits out the x-coord;y-coord;z-coord

3) and another lisp which has just the x-coord;y-coord

Each (all 3 lisps) should have the same formatting, with semicolons as separators and a comma (not dot point) as a decimal separator, and should all ideally have the output automatically copied to the clipboard.

 

If anyone can help a brother out, it would be much appreciated!

 

 

(defun c:xykm ( / *error*  vars vals e etype p param d chainage @FormatSta @Anonymous)
   ;; (c) 2018, John F. Uhden
   ;; Program reports the coordinates and chainage of polyline vertices.
   (defun *error* (error)
     (mapcar 'setvar vars vals)
     (vla-endundomark *doc*)
     (cond
       ((not error))
       ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
       (1 (princ (strcat "\nERROR: " error)))
     )
     (princ)
   )
   (setq Mspace (vlax-get (vlax-get (vlax-get-acad-object) 'Activedocument) 'Modelspace))
   (setq vars '(cmdecho dimzin))
   (setq vals (mapcar 'getvar vars))
   (or *acad* (setq *acad* (vlax-get-acad-object)))
   (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
   (vla-endundomark *doc*)
   (vla-startundomark *doc*)
   (mapcar 'setvar vars '(0 0))
   (command "_.expert" (getvar "expert")) ;; dummy command
   (defun @FormatSta (sta xp prec / n sign str)
     ;; where:
     ;;  sta = real or integer
     ;;  xp = exponent of 10 to specify how many numeric charcters between "+" and "."
     ;;  prec = decimal precision
     (setq n (expt 10.0 xp))
     (setq sign (if (minusp sta) "-" ""))
     (setq sta (abs sta))
     (setq str1 (strcat sign (itoa (fix (/ sta n))) "+"))
     (setq str2 (rtos (* n (rem (/ sta n) 1)) 2 prec))
     (repeat (max (- xp (strlen str2))(- xp (vl-string-position 46 str2)))
       (setq str2 (strcat "0" str2))
     )
     (strcat str1 str2)
   )
   (defun @Anonymous (# prec)
     (vl-string-subst "," "." (rtos # 2 prec))
   )
   (while (setq e (car (entsel "\nSelect a polyline: ")))
     (and
       (setq etype (cdr (assoc 0 (entget e))))
       (or (= etype "LWPOLYLINE")(prompt (strcat "\nObject selected is a(n) " etype)))
       (princ "\n")
       (setq param 0)
       (setq end (vlax-curve-getendparam e))
       (while (<= param end)
         (setq p (vlax-curve-getpointatparam e param))
         (setq d (vlax-curve-getdistatparam e param))
       ;;  (setq chainage (strcat "C=" (@formatsta d 3 3)))
         (setq chainage (@comma d 3))
         (write-line (strcat (@comma (car p) 4) ";" (@comma (cadr p) 4) ";" chainage))
         (setq param (1+ param))
       )
     )
   )
   (*error* nil)
 )
  

 

Running AutoCAD Architecture 2020, in German
0 Likes
Message 19 of 24

Kent1Cooper
Consultant
Consultant

@barry2104 wrote:

so harking back to this lisp - it works just as I want it to ....

Which extra line of code would I need to amend to the lisp in order to ....


This would have been better in reply to @john.uhden as the author of that code than to me, so I'm hereby calling his attention to it.

Kent Cooper, AIA
Message 20 of 24

john.uhden
Mentor
Mentor
What would you do with the information in the clipboard?
Don't you really want to write it to a file, even a .XLS?

John F. Uhden

0 Likes