Hi,
in excel I created a list of coordinates and description for lisp of the type:
(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3"))
how can I pass this list into lisp as input?
Solved! Go to Solution.
Solved by MrJSmith. Go to Solution.
Solved by komondormrex. Go to Solution.
Solved by MrJSmith. Go to Solution.
@dar.lombardi wrote:
Hi,
in excel I created a list of coordinates and description for lisp of the type:
(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3"))
how can I pass this list into lisp as input?
use foreach
(setq value '(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3")))
(foreach itm value
(print (Car itm));<-- The coordinates
(print (cadr itm));<-- The Description
(princ)
)
hey,
(mapcar '(lambda (test) (your_function test))
'(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3"))
)
Taking it one step further for Mr/Ms Lombardi...
defun pass (value)
(mapcar '(lambda (test) (your_function test)) value)
)
John F. Uhden
Hi,
the function returns "errore: no function definition: YOUR_FUNCTION".
I need to be asked for list input on the command line.
I copy the list from Excel and paste into the command line.
The list must be saved in a variable. Similar to getpoint or getstring but with a list.
C'mon, silly. @komondormrex wrote "your_function" meaning you must provide the function you want to be called. We use such words all the time around here. It is meant to be obvious.
John F. Uhden
Ok I see.
The problem is I need to give the list as input. Example:
1.In command line ask " insert list point";
2.I paste list point in command line;
3.List point is save in variable.
How Can do it?
In the short example I had provided, 'value' is the data list to which you refer. It would most easily be read into an AutoLisp list variable from a .CSV.
Then you would process each item of data to create the intended AutoCAD entities.
The data and other ancillary variables would be localized so as not to hang around in AutoCAD memory after your program was terminated.
John F. Uhden
It sounds like you'd be better off reading the excel file directly. What you are attempting to do is very awkward from a coding perspective. The "best" method would be to ask for the input as a string, I.e. (setq yourValue (getstring "Please enter the coordinates as a list")) and then they could past your generated list "(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3"))". You'd then need to use the "read" function to translate it from a string to a list. I.e. (foreach it (read yourValue) (print it)) would print out each of your elements with the first being "(1000 2000 0.0) "TESTO1")".
Other options could include reading the clipboard or setting the variable directly, but the best solution would be to read the excel file directly and pull the information from it through code.
Here is a program that will apply points, and echo's what's in the list.
As others have said, you would be better off reading those points and comments from Excel.
I'm sure someone here will give you a pointer to where similar code exists.
This code is just to demonstrate that it's possible...
;; demo.lsp
(defun c:demo ( value / coords item itm pt)
;; Evaluate each item in the list passed into c:demo as 'value'..
(foreach itm value
(setq coords (car itm)) ; put the coordinates into a local variable name
(setq item (cadr itm)) ; put the 'item' into a local variable name
;; Now, show that they are truly in variables
(princ "\n"); blank line at command prompt
(princ (strcat "\n" "Coordinates for " item " = "
(rtos (car coords)) " " ; 1st element of list 'coords'
(rtos (cadr coords)) " " ; 2nd element of list 'coords'
(rtos (caddr coords)) "")); 3rd element of list 'coords'
(princ "\n")
) ; foreach
;; Now, put in points for each Coordinate
(setvar "PDMODE" 2)
(setvar "PDSIZE" 5)
;; make each coordinate a point
(foreach itm value
(setq coords (car itm)) ; each coordinate point
(setq pt coords); already in a point list
(command "_point" pt)
); foreach
;; and Zoom to show the points
(command "_zoom" "E")
(princ)
); function c:demo
;; Say your 'list' looks like next line, and saved in a variable called 'listx
(setq listx '(((1000 2000 0.0) "TESTO1") ((1100 2200 0.0) "TESTO2") ((800 500 0.0) "TESTO3")))
;; Next line shows how to pass the 'list' into a function called C:demo
(c:demo listx); pass in the list to the above function..
;; Copy / Paste this code into Notepad.
;; Save the file as DEMO.lsp (over-ride the .txt default) with Notepad
;; To make it run in Acad, at the command line, do a (load "c:/xxx/demo.lsp")
;; - where xxx is the folder name you saved it to.
;; You may have to push the F2 (textscreen) to see what happened.
ECCAD
I disagree. Though I have successfully read directly from an XLS file, I am much more comfortable reading from a CSV (text file), knowing of course the delimiter character(s). I have a str2list function that allows for multicharacter delimiters, though I don't think Excel provides such a save-as option anyway. A one-character delimiter is just fine provided you don't use a comma if a text field contains a comma. You could use a tab or semicolon instead.
Anyway, God forbid that the user has to type in all that data. No no no!
John F. Uhden
@dar.lombardi wrote:
Ok I see.
The problem is I need to give the list as input. Example:
1.In command line ask " insert list point";
2.I paste list point in command line;
3.List point is save in variable.
How Can do it?
As most of the reply suggested, read the source then process the list instead of copy + paste
Post the xls/csv source so we can show you how also tell us what are you intending to do with the collected data?
try this
(setq list_ (getstring t "\nPaste your clipboarded list in here: "))
(setq list_ (read list_))
(princ list_)
IF you really really want copy+paste
(defun c:FE ( / clipbord-get-txt lst ) ;<-- From Excel
(defun clipbord-get-txt (/ HTML pw cb data)
(if(and(not(vl-catch-all-error-p
(setq HTML(vl-catch-all-apply
'vlax-create-object (list "htmlfile")
)
)
)
)
(=(type HTML) 'vla-object)
)
(progn
(if(not(and(not(vl-catch-all-error-p
(setq pw (vl-catch-all-apply
'vlax-get (list HTML 'ParentWindow)
)
)
)
)
(not(vl-catch-all-error-p
(setq cb (vl-catch-all-apply
'vlax-get (list PW 'ClipBoardData)
)
)
)
)
(not(vl-catch-all-error-p
(setq data (vl-catch-all-apply
'vlax-invoke (list CB 'Getdata "TEXT")
)
)
)
)
)
)
(setq data nil)
)
(vlax-release-object HTML)
)
)
(if data data "")
)
(setq lst (clipbord-get-txt))
(setq lst (read lst))
(foreach itm lst
(and (Eq (type (Setq pt (car itm))) 'LIST)(vl-every 'numberp pt)
(entmakex (list (cons 0 "POINT") (cons 10 pt))))
(and (Cadr itm)
(entmakex (list (cons 0 "TEXT")(cons 10 pt) (cons 40 (getvar 'Textsize))
(cons 1 (vl-princ-to-string (Cadr itm)))))
)
)
(princ)
)
command: FE
HTH
It works as I wanted, thanks.
In Excel, given the coordinates of the points I obtain the string (((1000 2000 0.0) \"TEXT1\") ((1100 2200 0.0) \"TEXT2\") ((800 500 0.0) \"TEXT3\")) with command concatenate of Excel .
When lisp asks for input I paste it into the command line and it is saved as a lisp variable.
@john.uhden Are you referring to turning the data into a list using a function (str2list)? You can do that easily in excel. For instance, you could grab an entire column of data and turn it into a list using a function like so.
;Range -- Defined range in Excel. Typically use 'UsedRange of a sheet or active sheet.
;colNum -- Can be either a number or letter representing the desired excel column. "A" or 1 both do the first column.
(defun excelGetColumnData (range colNum / vD)
(if
(setq vD
(vlax-variant-value
(vlax-get-property
(vlax-variant-value
(vlax-get-property
(vlax-get-property range "Columns") "Item" colNum)
)
'value
)
)
)
(progn
(setq vD (vlax-safearray->list VD));Safe Array of the variant data of an entire column
(mapcar '(lambda (x) (vlax-variant-value (vlax-variant-change-type (car x) 8))) vD) ;Returns a list of the variant data in string format.
;Data could be transformed into other formats via different variant change types
)
)
)
You could then call it like so to get the first column of data from excel into a list.
(setq range (vlax-get-property (vlax-get-property (vlax-get-or-create-object "Excel.Application") 'ActiveSheet) 'UsedRange))
(setq data (excelGetColumnData range 1))
I was talking about taking all the Excel fields and creating a list of lists in AutoCAD.
A CSV is so much easier because it's already organized that way...
1,X1,Y1,Z1
2,X2,Y2,Z2
3,X3,Y3,Z3
...
N,Xn,Yn,Zn
If taking it directly from Excel works for you then go for it.
John F. Uhden
Can't find what you're looking for? Ask the community or share your knowledge.