I'm attempting to write a code that will read a csv file, and for each line, spit out a block with the attributes defined using that csv. I seem to get errors no matter what I try, and AutoLISP is so very confusing to me despite plenty of prior programming knowledge. At first I tried using "vl-string-split" but AutoCAD told me that function doesn't exist (despite having VisualLISP). Next I tried using Lee Mac's read-csv code, and now I get an error of "too few arguments". I know I'm probably missing something very basic here, but I've hit my limit of searching forums for an answer that fits. If someone could kindly point this newb in the right direction it would be greatly appreciated!
Not sure if its relevant, but I'm using AutoCAD Map 3D 2020
(defun c:poleTest ()
;; Read CSV - Lee Mac
;; Parses a CSV file into a matrix list of cell values.
;; csv - [str] filename of CSV file to read
(defun LM:readcsv ( csv / des lst sep str )
(if (setq des (open csv "r"))
(progn
(setq sep (cond ((vl-registry-read "HKEY_CURRENT_USER\\Control Panel\\International" "sList")) (",")))
(while (setq str (read-line des))
(setq lst (cons (LM:csv->lst str sep 0) lst))
)
(close des)
)
)
(reverse lst)
)
;; CSV -> List - Lee Mac
;; Parses a line from a CSV file into a list of cell values.
;; str - [str] string read from CSV file
;; sep - [str] CSV separator token
;; pos - [int] initial position index (always zero)
(defun LM:csv->lst ( str sep pos / s )
(cond
( (not (setq pos (vl-string-search sep str pos)))
(if (wcmatch str "\"*\"")
(list (LM:csv-replacequotes (substr str 2 (- (strlen str) 2))))
(list str)
)
)
( (or (wcmatch (setq s (substr str 1 pos)) "\"*[~\"]")
(and (wcmatch s "~*[~\"]*") (= 1 (logand 1 pos)))
)
(LM:csv->lst str sep (+ pos 2))
)
( (wcmatch s "\"*\"")
(cons
(LM:csv-replacequotes (substr str 2 (- pos 2)))
(LM:csv->lst (substr str (+ pos 2)) sep 0)
)
)
( (cons s (LM:csv->lst (substr str (+ pos 2)) sep 0)))
)
)
(defun LM:csv-replacequotes ( str / pos )
(setq pos 0)
(while (setq pos (vl-string-search "\"\"" str pos))
(setq str (vl-string-subst "\"" "\"\"" str pos)
pos (1+ pos)
)
)
str
)
;; End of Lee Mac code
(setq filePath (getfiled "Select CSV file" "" "csv" 0))
(progn
(setq file (open filePath "r"))
(while (setq line (LM:csv->lst file))
(setq filePath "Z:\\Project Tools\\Customized Tools\\CAD\\prog\\BELL\\polebase1.dwg")
(setq xyz "0,0,0")
(setq scale "1,1,1")
(setq height (car (last line)))
(setq circ (car (nth 14 line)))
(setq year (car (nth 13 line)))
(setq txno (car (nth 12 line)))
(setq ground (car (nth 17 line)))
(setq slground (car (nth 18 line)))
(setq pics (car (nth 6 line)))
(setq poleno (car (nth 4 line)))
(setq poleID (car (nth 5 line)))
(setq owner (car (car line)))
(princ filePath)
(princ xyz)
(princ scale)
(princ height)
(princ circ)
(princ year)
(princ txno)
(princ ground)
(princ slground)
(princ pics)
(princ poleno)
(princ poleID)
(princ owner)
(command "insert" filePath xyz scale height circ year txno ground slground pics poleno poleID owner)
)
)
)
My
LM:readcsv
function will read the contents of a CSV file into a list of lists, which you can then iterate over (using aforeach
loop, for example) in order to insert your blocks.The issue with your current code is that you are calling my
LM:csv->lst
function, which requires three arguments: a string to be parsed, a delimiter character, and an initial character position (always 0). Instead, you should call myLM:readcsv
function.Consider the following code: